<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>墨雪天琊</title>
    <subtitle>墨雪天琊的技术博客</subtitle>
    <link rel="self" type="application/atom+xml" href="https://vercel.juzhong.xyz/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-06-13T14:00:00+08:00</updated>
    <id>https://vercel.juzhong.xyz/atom.xml</id>
    <entry xml:lang="en">
        <title>GNOME Remote Desktop 证书问题排查记录</title>
        <published>2026-06-13T14:00:00+08:00</published>
        <updated>2026-06-13T14:00:00+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2026/06/gnome-remote-desktop-cert-troubleshooting/"/>
        <id>https://vercel.juzhong.xyz/2026/06/gnome-remote-desktop-cert-troubleshooting/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2026/06/gnome-remote-desktop-cert-troubleshooting/">&lt;h1 id=&quot;gnome-remote-desktop-zheng-shu-wen-ti-pai-cha-ji-lu&quot;&gt;GNOME Remote Desktop 证书问题排查记录&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;huan-jing-xin-xi&quot;&gt;环境信息&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;项目&lt;&#x2F;th&gt;&lt;th&gt;值&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;操作系统&lt;&#x2F;td&gt;&lt;td&gt;Debian 13 (Trixie)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;gnome-remote-desktop&lt;&#x2F;td&gt;&lt;td&gt;48.1-4&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;libfreerdp-server&lt;&#x2F;td&gt;&lt;td&gt;3.15.0+dfsg-2.1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;运行模式&lt;&#x2F;td&gt;&lt;td&gt;systemd user service (&lt;code&gt;--user&lt;&#x2F;code&gt;)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;证书目录&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;~&#x2F;.local&#x2F;share&#x2F;gnome-remote-desktop&#x2F;certificates&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;配置文件&lt;&#x2F;td&gt;&lt;td&gt;dconf&#x2F;gsettings (&lt;code&gt;org.gnome.desktop.remote-desktop.rdp&lt;&#x2F;code&gt;)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;gu-zhang-xian-xiang&quot;&gt;故障现象&lt;&#x2F;h2&gt;
&lt;p&gt;启动服务后日志报错，RDP 服务无法正常接受连接：&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;[ERROR][com.freerdp.crypto] - [x509_utils_from_pem]: BIO_new failed for certificate
RDP server certificate is invalid
RDP TLS certificate and key not yet configured properly
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;pai-cha-bu-zou&quot;&gt;排查步骤&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;1-jian-cha-zheng-shu-wen-jian-shi-fou-cun-zai&quot;&gt;1. 检查证书文件是否存在&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;ls -la ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;certificates&amp;#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;证书文件 &lt;code&gt;rdp-tls.crt&lt;&#x2F;code&gt; 和 &lt;code&gt;rdp-tls.key&lt;&#x2F;code&gt; 存在。&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2-yong-openssl-yan-zheng-zheng-shu-ge-shi&quot;&gt;2. 用 OpenSSL 验证证书格式&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;openssl x509 -in rdp-tls.crt -text -noout
openssl rsa  -in rdp-tls.key -check -noout
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;两者均通过验证，说明证书本身是合法 PEM 格式。&lt;&#x2F;p&gt;
&lt;h3 id=&quot;3-jian-cha-zheng-shu-bao-han-de-x509v3-kuo-zhan&quot;&gt;3. 检查证书包含的 X509v3 扩展&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;openssl x509 -in rdp-tls.crt -text -noout | grep -E &amp;quot;Subject Alternative Name|Key Usage|Extended Key Usage&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;输出为空——旧证书缺少现代 TLS 必需的 SAN、Key Usage 等扩展字段。FreeRDP 3.x 对此要求严格。&lt;&#x2F;p&gt;
&lt;h3 id=&quot;4-jian-cha-gsettings-pei-zhi-de-zheng-shu-lu-jing&quot;&gt;4. 检查 gsettings 配置的证书路径&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;gsettings get org.gnome.desktop.remote-desktop.rdp tls-cert
gsettings get org.gnome.desktop.remote-desktop.rdp tls-key
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;输出：&lt;code&gt;&#x2F;home&#x2F;peterxiao&#x2F;...&lt;&#x2F;code&gt; — &lt;strong&gt;指向错误的 home 目录&lt;&#x2F;strong&gt;（实际用户为 &lt;code&gt;peter&lt;&#x2F;code&gt;，&lt;code&gt;&#x2F;home&#x2F;peterxiao&#x2F;&lt;&#x2F;code&gt; 不存在）。这是本次故障的直接原因。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;gen-yin-zong-jie&quot;&gt;根因总结&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;路径不匹配&lt;&#x2F;strong&gt;：gsettings&#x2F;dconf 中配置的证书路径指向不存在的目录（用户名拼写错误），daemon 无法读取证书文件。&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;证书缺少扩展&lt;&#x2F;strong&gt;：即便路径正确，旧证书也缺少 &lt;code&gt;subjectAltName&lt;&#x2F;code&gt;、&lt;code&gt;Key Usage&lt;&#x2F;code&gt;、&lt;code&gt;Extended Key Usage&lt;&#x2F;code&gt; 等 X509v3 扩展，FreeRDP 3.15 会拒绝加载。&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;xiu-fu-bu-zou&quot;&gt;修复步骤&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;bu-zou-1-ting-zhi-fu-wu&quot;&gt;步骤 1：停止服务&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;systemctl --user stop gnome-remote-desktop.service
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;bu-zou-2-shan-chu-jiu-zheng-shu&quot;&gt;步骤 2：删除旧证书&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;rm ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;certificates&amp;#x2F;rdp-tls.crt
rm ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;certificates&amp;#x2F;rdp-tls.key
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;bu-zou-3-zhong-zhi-gsettings-lu-jing&quot;&gt;步骤 3：重置 gsettings 路径&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;gsettings reset org.gnome.desktop.remote-desktop.rdp tls-cert
gsettings reset org.gnome.desktop.remote-desktop.rdp tls-key
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;bu-zou-4-sheng-cheng-fu-he-gui-fan-de-zheng-shu&quot;&gt;步骤 4：生成符合规范的证书&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;HOSTNAME=$(hostname)

openssl req -x509 -newkey rsa:4096 -sha384 -days 730 -nodes \
  -keyout ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;certificates&amp;#x2F;rdp-tls.key \
  -out    ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;certificates&amp;#x2F;rdp-tls.crt \
  -subj   &amp;quot;&amp;#x2F;CN=$HOSTNAME&amp;quot; \
  -addext &amp;quot;subjectAltName=DNS:$HOSTNAME&amp;quot; \
  -addext &amp;quot;keyUsage=digitalSignature,keyEncipherment&amp;quot; \
  -addext &amp;quot;extendedKeyUsage=serverAuth&amp;quot; \
  -addext &amp;quot;nsCertType=server&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;关键点：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;必须包含 &lt;code&gt;subjectAltName&lt;&#x2F;code&gt;（FreeRDP 3.x 强制要求）&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;extendedKeyUsage=serverAuth&lt;&#x2F;code&gt; 标识为 TLS 服务器证书&lt;&#x2F;li&gt;
&lt;li&gt;使用 &lt;code&gt;-sha384&lt;&#x2F;code&gt;（与 gnome-remote-desktop 默认一致）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;bu-zou-5-yan-zheng-zheng-shu-yu-mi-yao-pi-pei&quot;&gt;步骤 5：验证证书与密钥匹配&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;openssl x509 -in ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;certificates&amp;#x2F;rdp-tls.crt -noout -modulus | md5sum
openssl rsa  -in ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;certificates&amp;#x2F;rdp-tls.key -noout -modulus | md5sum
# 两个 md5sum 应一致
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;bu-zou-6-yong-grdctl-pei-zhi-zheng-shu-lu-jing&quot;&gt;步骤 6：用 grdctl 配置证书路径&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;grdctl rdp set-tls-cert ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;certificates&amp;#x2F;rdp-tls.crt
grdctl rdp set-tls-key  ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;certificates&amp;#x2F;rdp-tls.key
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;bu-zou-7-qi-dong-bing-yan-zheng&quot;&gt;步骤 7：启动并验证&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;systemctl --user start gnome-remote-desktop.service

# 查看状态
systemctl --user status gnome-remote-desktop.service

# 应显示 &amp;quot;RDP server started&amp;quot;，无证书错误
grdctl status
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;chang-yong-pai-cha-ming-ling&quot;&gt;常用排查命令&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 查看实时日志
journalctl --user -u gnome-remote-desktop.service -f --no-pager

# 检查证书有效期
openssl x509 -in ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;certificates&amp;#x2F;rdp-tls.crt -noout -dates

# 查看证书完整信息
openssl x509 -in ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;certificates&amp;#x2F;rdp-tls.crt -text -noout

# 检查当前 gsettings 配置
gsettings list-recursively org.gnome.desktop.remote-desktop.rdp

# 检查 RDP 端口监听
ss -tlnp | grep 3389
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;yi-zhi-jian-rong-xing-wen-ti&quot;&gt;已知兼容性问题&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;组件&lt;&#x2F;th&gt;&lt;th&gt;版本&lt;&#x2F;th&gt;&lt;th&gt;要求&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;FreeRDP&lt;&#x2F;td&gt;&lt;td&gt;&amp;gt;= 3.x&lt;&#x2F;td&gt;&lt;td&gt;证书必须包含 &lt;code&gt;subjectAltName&lt;&#x2F;code&gt; 扩展&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;GNOME Remote Desktop&lt;&#x2F;td&gt;&lt;td&gt;48.x&lt;&#x2F;td&gt;&lt;td&gt;使用 SHA-384 签名算法，RSA 4096 密钥&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;证书路径由 &lt;code&gt;grdctl rdp set-tls-cert&#x2F;key&lt;&#x2F;code&gt; 写入 dconf，持久化在 &lt;code&gt;~&#x2F;.config&#x2F;dconf&#x2F;user&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;daemon 不会自动生成证书，必须手动创建或通过 GNOME Settings -&amp;gt; Sharing -&amp;gt; Remote Desktop 触发生成&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;BIO_new failed&lt;&#x2F;code&gt; 通常意味着 FreeRDP 的 OpenSSL 后端无法解析 PEM 文件内容（路径不存在、格式损坏、或缺少必需扩展）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>GNOME Remote Desktop (RDP) 完整排查与修复记录</title>
        <published>2026-06-13T13:00:00+08:00</published>
        <updated>2026-06-13T13:00:00+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2026/06/gnome-remote-desktop-full-troubleshooting/"/>
        <id>https://vercel.juzhong.xyz/2026/06/gnome-remote-desktop-full-troubleshooting/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2026/06/gnome-remote-desktop-full-troubleshooting/">&lt;h1 id=&quot;gnome-remote-desktop-rdp-wan-zheng-pai-cha-yu-xiu-fu-ji-lu&quot;&gt;GNOME Remote Desktop (RDP) 完整排查与修复记录&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;huan-jing-xin-xi&quot;&gt;环境信息&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;项目&lt;&#x2F;th&gt;&lt;th&gt;值&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;操作系统&lt;&#x2F;td&gt;&lt;td&gt;Debian 13.3 (Trixie)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;内核&lt;&#x2F;td&gt;&lt;td&gt;6.12.73+deb13-amd64&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;gnome-remote-desktop&lt;&#x2F;td&gt;&lt;td&gt;48.1-4&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;libfreerdp-server&lt;&#x2F;td&gt;&lt;td&gt;3.15.0+dfsg-2.1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;运行模式&lt;&#x2F;td&gt;&lt;td&gt;systemd user service (&lt;code&gt;--user&lt;&#x2F;code&gt;)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;用户&lt;&#x2F;td&gt;&lt;td&gt;peter (UID 1000)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;主机名&lt;&#x2F;td&gt;&lt;td&gt;xiao99&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;证书目录&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;~&#x2F;.local&#x2F;share&#x2F;gnome-remote-desktop&#x2F;certificates&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;凭据存储&lt;&#x2F;td&gt;&lt;td&gt;GKeyFile (&lt;code&gt;~&#x2F;.local&#x2F;share&#x2F;gnome-remote-desktop&#x2F;credentials.ini&lt;&#x2F;code&gt;)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;配置文件&lt;&#x2F;td&gt;&lt;td&gt;dconf&#x2F;gsettings (&lt;code&gt;org.gnome.desktop.remote-desktop.rdp&lt;&#x2F;code&gt;)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;chu-shi-gu-zhang-xian-xiang&quot;&gt;初始故障现象&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;RDP 服务可以连接（端口 3389 开放），但客户端输入用户名密码后立即断开&lt;&#x2F;li&gt;
&lt;li&gt;日志显示 &lt;code&gt;Credentials are not set, denying client&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;配置好凭据后，连接时日志报 NTLM MIC 验证失败&lt;&#x2F;li&gt;
&lt;li&gt;通过 NLA 认证后，会话创建被阻止，日志显示 &lt;code&gt;Session creation inhibited&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;wen-ti-yi-rdp-zheng-shu-que-shao-x509v3-kuo-zhan&quot;&gt;问题一：RDP 证书缺少 X509v3 扩展&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;pai-cha&quot;&gt;排查&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 检查证书文件是否存在
ls -la ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;certificates&amp;#x2F;
# 结果：rdp-tls.crt 和 rdp-tls.key 存在

# 检查 gsettings 证书路径
gsettings get org.gnome.desktop.remote-desktop.rdp tls-cert
gsettings get org.gnome.desktop.remote-desktop.rdp tls-key
# 结果：路径正确，指向 &amp;#x2F;home&amp;#x2F;peter&amp;#x2F;...

# 检查证书包含的 X509v3 扩展
openssl x509 -in rdp-tls.crt -text -noout | grep -E &amp;quot;Subject Alternative Name|Key Usage|Extended Key Usage&amp;quot;
# 结果：无输出 —— 旧证书缺少现代 TLS 必需的 SAN、Key Usage 等扩展字段
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;gen-yin&quot;&gt;根因&lt;&#x2F;h3&gt;
&lt;p&gt;FreeRDP 3.x 严格要求证书包含 &lt;code&gt;subjectAltName&lt;&#x2F;code&gt; (SAN)、&lt;code&gt;Key Usage&lt;&#x2F;code&gt;、&lt;code&gt;Extended Key Usage&lt;&#x2F;code&gt; 等 X509v3 扩展。旧证书由 GNOME 早期版本自动生成，缺少这些扩展。&lt;&#x2F;p&gt;
&lt;h3 id=&quot;xiu-fu&quot;&gt;修复&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 1. 停止服务
systemctl --user stop gnome-remote-desktop.service

# 2. 删除旧证书
rm ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;certificates&amp;#x2F;rdp-tls.crt
rm ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;certificates&amp;#x2F;rdp-tls.key

# 3. 重置 gsettings 路径
gsettings reset org.gnome.desktop.remote-desktop.rdp tls-cert
gsettings reset org.gnome.desktop.remote-desktop.rdp tls-key

# 4. 生成含正确扩展的证书
HOSTNAME=$(hostname)

openssl req -x509 -newkey rsa:4096 -sha384 -days 730 -nodes \
  -keyout ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;certificates&amp;#x2F;rdp-tls.key \
  -out    ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;certificates&amp;#x2F;rdp-tls.crt \
  -subj   &amp;quot;&amp;#x2F;CN=$HOSTNAME&amp;quot; \
  -addext &amp;quot;subjectAltName=DNS:$HOSTNAME&amp;quot; \
  -addext &amp;quot;keyUsage=digitalSignature,keyEncipherment&amp;quot; \
  -addext &amp;quot;extendedKeyUsage=serverAuth&amp;quot; \
  -addext &amp;quot;nsCertType=server&amp;quot;

# 5. 验证证书与密钥匹配
openssl x509 -in ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;certificates&amp;#x2F;rdp-tls.crt -noout -modulus | md5sum
openssl rsa  -in ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;certificates&amp;#x2F;rdp-tls.key -noout -modulus | md5sum
# 两个 md5sum 必须一致

# 6. 通过 gsettings 设置证书路径
gsettings set org.gnome.desktop.remote-desktop.rdp tls-cert &amp;quot;&amp;#x2F;home&amp;#x2F;peter&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;certificates&amp;#x2F;rdp-tls.crt&amp;quot;
gsettings set org.gnome.desktop.remote-desktop.rdp tls-key  &amp;quot;&amp;#x2F;home&amp;#x2F;peter&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;certificates&amp;#x2F;rdp-tls.key&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;cai-keng-grdctl-she-lu-jing-shi-bai&quot;&gt;踩坑：grdctl 设路径失败&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;grdctl rdp set-tls-cert&lt;&#x2F;code&gt; 通过 D-Bus 与 daemon 通信，若 daemon 未运行，D-Bus 激活会以无证书状态启动 daemon，导致 &lt;code&gt;BIO_new failed for certificate&lt;&#x2F;code&gt; 错误。&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;解决&lt;&#x2F;strong&gt;：改用 &lt;code&gt;gsettings set&lt;&#x2F;code&gt; 直接写 dconf，避免触发 D-Bus 激活。&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;wen-ti-er-rdp-ping-ju-wei-she-zhi&quot;&gt;问题二：RDP 凭据未设置&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;pai-cha-1&quot;&gt;排查&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;grdctl status
# 输出：Username: (empty), Password: (empty)

journalctl --user -u gnome-remote-desktop.service -f
# 日志：[RDP] Credentials are not set, denying client
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;gen-yin-1&quot;&gt;根因&lt;&#x2F;h3&gt;
&lt;p&gt;RDP 服务需要设置登录凭据（用户名 + 密码）才能接受客户端连接。&lt;&#x2F;p&gt;
&lt;h3 id=&quot;xiu-fu-1&quot;&gt;修复&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 尝试标准方式 —— 失败（见问题三）
grdctl rdp set-credentials peter 2021smyl
# 错误：The &amp;#x27;&amp;#x2F;org&amp;#x2F;freedesktop&amp;#x2F;secrets&amp;#x2F;collection&amp;#x2F;login&amp;#x27; object does not exist

# 使用 headless 模式绕过 GNOME Keyring
grdctl --headless rdp set-credentials peter 2021smyl
# 输出：Init TPM credentials failed ... using GKeyFile as fallback.
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;wen-ti-san-gnome-keyring-que-shao-login-mi-yao-huan&quot;&gt;问题三：GNOME Keyring 缺少 login 密钥环&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;pai-cha-2&quot;&gt;排查&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 检查是否存在密钥环集合
python3 -c &amp;quot;
import gi
gi.require_version(&amp;#x27;Secret&amp;#x27;, &amp;#x27;1&amp;#x27;)
from gi.repository import Secret
service = Secret.Service.get_sync(Secret.ServiceFlags.OPEN_SESSION)
collections = service.get_collections()
for c in collections:
    print(f&amp;#x27;{c.get_label()} ({c.get_object_path()})&amp;#x27;)
&amp;quot;
# 结果：No collections found

# 检查密钥环文件
ls ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;keyrings&amp;#x2F;
# 结果：目录不存在

# 检查 D-Bus Secret Service
busctl --user call org.freedesktop.secrets &amp;#x2F;org&amp;#x2F;freedesktop&amp;#x2F;secrets \
  org.freedesktop.DBus.Properties Get ss \
  org.freedesktop.Secret.Service Collections
# 结果：只有一个 session 临时集合，无 login 密钥环
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;gen-yin-2&quot;&gt;根因&lt;&#x2F;h3&gt;
&lt;p&gt;用户的 GNOME Keyring &lt;code&gt;login&lt;&#x2F;code&gt; 密钥环从未被创建。通常由 GDM PAM 模块 (&lt;code&gt;pam_gnome_keyring.so&lt;&#x2F;code&gt;) 在登录时自动创建并解锁。可能原因：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;用户通过 SSH 或 tty 登录而非 GDM&lt;&#x2F;li&gt;
&lt;li&gt;PAM 配置未正确加载 gnome-keyring 模块&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;grdctl rdp set-credentials&lt;&#x2F;code&gt; 底层使用 libsecret，要求 &lt;code&gt;login&lt;&#x2F;code&gt; 密钥环存在才能存储密码。&lt;&#x2F;p&gt;
&lt;h3 id=&quot;xiu-fu-2&quot;&gt;修复&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;方案&lt;&#x2F;strong&gt;：使用 &lt;code&gt;grdctl --headless&lt;&#x2F;code&gt; 模式，凭据存储到 GKeyFile 文件而非 GNOME Keyring。&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;grdctl --headless rdp set-credentials peter 2021smyl
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;凭据写入 &lt;code&gt;~&#x2F;.local&#x2F;share&#x2F;gnome-remote-desktop&#x2F;credentials.ini&lt;&#x2F;code&gt;：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;ini&quot; class=&quot;language-ini &quot;&gt;&lt;code class=&quot;language-ini&quot; data-lang=&quot;ini&quot;&gt;[RDP]
credentials={&amp;#x27;username&amp;#x27;: &amp;lt;&amp;#x27;peter&amp;#x27;&amp;gt;, &amp;#x27;password&amp;#x27;: &amp;lt;&amp;#x27;2021smyl&amp;#x27;&amp;gt;}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;要点&lt;&#x2F;strong&gt;：daemon 也必须以 &lt;code&gt;--headless&lt;&#x2F;code&gt; 模式运行才能读取 GKeyFile 中的凭据。&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;wen-ti-si-systemd-type-dbus-yu-headless-bu-jian-rong&quot;&gt;问题四：systemd Type=dbus 与 --headless 不兼容&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;pai-cha-3&quot;&gt;排查&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;systemctl --user status gnome-remote-desktop.service
# 状态：activating (start) —— 卡在启动中
# 90 秒后超时：Failed with result &amp;#x27;timeout&amp;#x27;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;gen-yin-3&quot;&gt;根因&lt;&#x2F;h3&gt;
&lt;p&gt;daemon 默认以 &lt;code&gt;Type=dbus&lt;&#x2F;code&gt; 运行，systemd 等待 daemon 注册 D-Bus 名称 &lt;code&gt;org.gnome.RemoteDesktop.User&lt;&#x2F;code&gt;。但 &lt;code&gt;--headless&lt;&#x2F;code&gt; 模式下，daemon 可能在注册 D-Bus 名称前需要额外初始化（如 TPM 尝试），导致超时。&lt;&#x2F;p&gt;
&lt;h3 id=&quot;xiu-fu-3&quot;&gt;修复&lt;&#x2F;h3&gt;
&lt;p&gt;创建 systemd 服务覆盖配置文件：&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;~&#x2F;.config&#x2F;systemd&#x2F;user&#x2F;gnome-remote-desktop.service.d&#x2F;headless.conf&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;ini&quot; class=&quot;language-ini &quot;&gt;&lt;code class=&quot;language-ini&quot; data-lang=&quot;ini&quot;&gt;[Service]
Type=simple
ExecStart=
ExecStart=&amp;#x2F;usr&amp;#x2F;libexec&amp;#x2F;gnome-remote-desktop-daemon --headless
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;关键点：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;第一行 &lt;code&gt;ExecStart=&lt;&#x2F;code&gt; 清空上游配置中的 ExecStart&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Type=simple&lt;&#x2F;code&gt; 替代 &lt;code&gt;Type=dbus&lt;&#x2F;code&gt;，daemon 启动即视为就绪&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;systemctl --user daemon-reload
systemctl --user restart gnome-remote-desktop.service
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;wen-ti-wu-session-creation-inhibited-suo-ping-zu-zhi-yuan-cheng-hui-hua&quot;&gt;问题五：Session creation inhibited（锁屏阻止远程会话）&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;pai-cha-4&quot;&gt;排查&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 检查屏幕锁状态
dbus-send --session --dest=org.gnome.ScreenSaver --print-reply \
  &amp;#x2F;org&amp;#x2F;gnome&amp;#x2F;ScreenSaver org.gnome.ScreenSaver.GetActive
# 结果：boolean true —— 屏幕已锁定

# 检查会话状态
loginctl show-session 2 | grep IdleHint
# 结果：IdleHint=yes —— 会话空闲

# 服务日志
journalctl --user -u gnome-remote-desktop.service
# 关键错误：
#   Failed to start remote desktop session:
#   GDBus.Error:org.freedesktop.DBus.Error.Failed: Session creation inhibited
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;gen-yin-4&quot;&gt;根因&lt;&#x2F;h3&gt;
&lt;p&gt;gnome-remote-desktop 依赖活动且未锁定的 GNOME Shell 会话才能创建远程桌面会话。当屏幕锁定或会话休眠时，Mutter 会拒绝远程会话创建请求。这是 GNOME 安全策略 —— 防止在用户离开时通过远程桌面窥探屏幕。&lt;&#x2F;p&gt;
&lt;p&gt;当前环境的主 GNOME 会话 (seat0, session 2) 已空闲 &lt;strong&gt;近 2 周&lt;&#x2F;strong&gt;。&lt;&#x2F;p&gt;
&lt;h3 id=&quot;xiu-fu-lin-shi&quot;&gt;修复（临时）&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 解除屏幕锁
gdbus call --session --dest org.gnome.ScreenSaver \
  --object-path &amp;#x2F;org&amp;#x2F;gnome&amp;#x2F;ScreenSaver \
  --method org.gnome.ScreenSaver.SetActive false
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;xiu-fu-yong-jiu&quot;&gt;修复（永久）&lt;&#x2F;h3&gt;
&lt;p&gt;关闭自动锁屏，防止长期无人使用时再次锁屏阻断 RDP：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;gsettings set org.gnome.desktop.screensaver lock-enabled false
gsettings set org.gnome.desktop.screensaver idle-activation-enabled false
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;&#x2F;strong&gt;：这会彻底禁用锁屏，降低安全性。生产环境建议在 GNOME 设置中配置为&quot;长时间不活动后锁屏&quot;而非禁用。&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;zui-zhong-yan-zheng&quot;&gt;最终验证&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;fu-wu-zhuang-tai&quot;&gt;服务状态&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;systemctl --user status gnome-remote-desktop.service
# Active: active (running) since ...

grdctl --headless status --show-credentials
# RDP:
#   Status: enabled
#   Port: 3389
#   TLS certificate: ...&amp;#x2F;rdp-tls.crt
#   TLS fingerprint: 5a:00:fe:60:...
#   TLS key: ...&amp;#x2F;rdp-tls.key
#   View-only: no
#   Username: peter
#   Password: 2021smyl
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;duan-kou-jian-ting&quot;&gt;端口监听&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;ss -tlnp | grep 3389
# LISTEN  *:3389  users:((&amp;quot;gnome-remote-de&amp;quot;,pid=xxx,fd=xx))
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;zheng-shu-xin-xi&quot;&gt;证书信息&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;openssl x509 -in ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;certificates&amp;#x2F;rdp-tls.crt -text -noout | grep -E &amp;quot;Subject Alternative Name|Key Usage|Extended Key Usage&amp;quot;
#             X509v3 Subject Alternative Name:
#                DNS:xiao99
#             X509v3 Key Usage:
#                Digital Signature, Key Encipherment
#             X509v3 Extended Key Usage:
#                TLS Web Server Authentication
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;chang-yong-pai-cha-ming-ling&quot;&gt;常用排查命令&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 查看实时日志
journalctl --user -u gnome-remote-desktop.service -f --no-pager

# 检查 RDP 配置
grdctl --headless status --show-credentials

# 检查 gsettings 完整配置
gsettings list-recursively org.gnome.desktop.remote-desktop.rdp

# 检查证书有效期
openssl x509 -in ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;certificates&amp;#x2F;rdp-tls.crt -noout -dates

# 检查证书完整信息
openssl x509 -in ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;certificates&amp;#x2F;rdp-tls.crt -text -noout

# 检查 RDP 端口监听
ss -tlnp | grep 3389

# 检查屏幕锁状态
dbus-send --session --dest=org.gnome.ScreenSaver --print-reply \
  &amp;#x2F;org&amp;#x2F;gnome&amp;#x2F;ScreenSaver org.gnome.ScreenSaver.GetActive

# 检查用户会话状态
loginctl list-sessions
loginctl show-session &amp;lt;session-id&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;xiu-fu-hui-zong&quot;&gt;修复汇总&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;#&lt;&#x2F;th&gt;&lt;th&gt;问题&lt;&#x2F;th&gt;&lt;th&gt;根因&lt;&#x2F;th&gt;&lt;th&gt;修复方式&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;证书无效&lt;&#x2F;td&gt;&lt;td&gt;缺少 X509v3 扩展 (SAN&#x2F;KeyUsage&#x2F;EKU)&lt;&#x2F;td&gt;&lt;td&gt;用 openssl 重新生成含扩展的证书&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;凭据未设置&lt;&#x2F;td&gt;&lt;td&gt;从未配置 RDP 用户名密码&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;grdctl --headless rdp set-credentials&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;Keyring 不存在&lt;&#x2F;td&gt;&lt;td&gt;login 密钥环未创建，grdctl 标准模式无法存储凭据&lt;&#x2F;td&gt;&lt;td&gt;使用 &lt;code&gt;--headless&lt;&#x2F;code&gt; 模式写入 GKeyFile&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;服务启动超时&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;Type=dbus&lt;&#x2F;code&gt; 与 &lt;code&gt;--headless&lt;&#x2F;code&gt; 不兼容&lt;&#x2F;td&gt;&lt;td&gt;创建 systemd override，改用 &lt;code&gt;Type=simple&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;会话创建被阻止&lt;&#x2F;td&gt;&lt;td&gt;GNOME 桌面锁屏&#x2F;空闲&lt;&#x2F;td&gt;&lt;td&gt;解除锁屏 + 关闭自动锁屏&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;guan-jian-wen-jian&quot;&gt;关键文件&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;文件&lt;&#x2F;th&gt;&lt;th&gt;用途&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;~&#x2F;.local&#x2F;share&#x2F;gnome-remote-desktop&#x2F;certificates&#x2F;rdp-tls.crt&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;TLS 证书&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;~&#x2F;.local&#x2F;share&#x2F;gnome-remote-desktop&#x2F;certificates&#x2F;rdp-tls.key&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;TLS 私钥&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;~&#x2F;.local&#x2F;share&#x2F;gnome-remote-desktop&#x2F;credentials.ini&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;RDP 凭据 (headless 模式)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;~&#x2F;.config&#x2F;systemd&#x2F;user&#x2F;gnome-remote-desktop.service.d&#x2F;headless.conf&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;systemd 服务覆盖配置&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;~&#x2F;.config&#x2F;dconf&#x2F;user&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;dconf 数据库 (gsettings 持久化)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;yi-zhi-xian-zhi&quot;&gt;已知限制&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;gnome-remote-desktop 需要活动、未锁定的 GNOME Shell 会话&lt;&#x2F;li&gt;
&lt;li&gt;使用 headless + GKeyFile 模式，凭据以明文存储（TPM 不可用时）&lt;&#x2F;li&gt;
&lt;li&gt;若重启系统后问题复现，检查：
&lt;ul&gt;
&lt;li&gt;屏幕是否再次锁定&lt;&#x2F;li&gt;
&lt;li&gt;证书是否过期（有效期 730 天）&lt;&#x2F;li&gt;
&lt;li&gt;daemon 日志中是否有新的证书或会话错误&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>virtiofs ENFILE 问题排查手册</title>
        <published>2026-06-13T12:00:00+08:00</published>
        <updated>2026-06-13T12:00:00+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2026/06/virtiofs-enfile-diagnosis/"/>
        <id>https://vercel.juzhong.xyz/2026/06/virtiofs-enfile-diagnosis/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2026/06/virtiofs-enfile-diagnosis/">&lt;h1 id=&quot;virtiofs-enfile-wen-ti-pai-cha-shou-ce&quot;&gt;virtiofs ENFILE 问题排查手册&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;wen-ti-xian-xiang&quot;&gt;问题现象&lt;&#x2F;h2&gt;
&lt;p&gt;VM 内执行文件操作时报错：&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;ls: 无法打开目录 &amp;#x27;.&amp;#x27;: 系统中打开的文件过多
# 对应系统错误: ENFILE (Too many open files in system)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;pai-cha-bu-zou&quot;&gt;排查步骤&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;1-xi-tong-ji-wen-jian-ju-bing-zhuang-tai&quot;&gt;1. 系统级文件句柄状态&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;cat &amp;#x2F;proc&amp;#x2F;sys&amp;#x2F;fs&amp;#x2F;file-nr
# 输出格式: &amp;lt;已分配数量&amp;gt; &amp;lt;空闲数量&amp;gt; &amp;lt;最大限制&amp;gt;
# 如果第 2 列 = 0 表示文件表已耗尽

cat &amp;#x2F;proc&amp;#x2F;sys&amp;#x2F;fs&amp;#x2F;file-max
cat &amp;#x2F;proc&amp;#x2F;sys&amp;#x2F;fs&amp;#x2F;nr_open
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;2-ding-wei-virtiofsd-jin-cheng&quot;&gt;2. 定位 virtiofsd 进程&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;pgrep -a virtiofsd

ps -o pid,ppid,user,etime,rss,args -p $(pgrep -d&amp;#x27;,&amp;#x27; virtiofsd)
# rss: 内存占用  etime: 运行时长
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;3-jian-cha-virtiofsd-fd-shu-liang&quot;&gt;3. 检查 virtiofsd fd 数量&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 精确计数
sudo -A ls &amp;#x2F;proc&amp;#x2F;&amp;lt;PID&amp;gt;&amp;#x2F;fd | wc -l

# 间接估算（fd 目录字节数 ≈ 30×fd数）
stat &amp;#x2F;proc&amp;#x2F;&amp;lt;PID&amp;gt;&amp;#x2F;fd | grep Size
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;4-cha-kan-fd-lei-xing-fen-bu&quot;&gt;4. 查看 fd 类型分布&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo -A ls -la &amp;#x2F;proc&amp;#x2F;&amp;lt;PID&amp;gt;&amp;#x2F;fd&amp;#x2F; | awk &amp;#x27;{
  target=$NF
  if (target ~ &amp;#x2F;^socket:&amp;#x2F;)       type=&amp;quot;socket&amp;quot;
  else if (target ~ &amp;#x2F;^pipe:&amp;#x2F;)    type=&amp;quot;pipe&amp;quot;
  else if (target ~ &amp;#x2F;^anon_inode:&amp;#x2F;) type=&amp;quot;anon_inode&amp;quot;
  else if (target ~ &amp;#x2F;\(deleted\)$&amp;#x2F;) type=&amp;quot;deleted_file&amp;quot;
  else if (target ~ &amp;#x2F;^\&amp;#x2F;&amp;#x2F;)       type=&amp;quot;regular_file&amp;quot;
  else if (target ~ &amp;#x2F;^\&amp;#x2F;dev\&amp;#x2F;&amp;#x2F;)  type=&amp;quot;dev&amp;quot;
  else                           type=&amp;quot;other&amp;quot;
  count[type]++
} END { for(t in count) print count[t], t }&amp;#x27; | sort -rn
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;5-cha-kan-fd-zhi-xiang-na-xie-mu-lu&quot;&gt;5. 查看 fd 指向哪些目录&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo -A ls -la &amp;#x2F;proc&amp;#x2F;&amp;lt;PID&amp;gt;&amp;#x2F;fd&amp;#x2F; | awk &amp;#x27;{print $NF}&amp;#x27; | \
  sed &amp;#x27;s|&amp;#x2F;home&amp;#x2F;peter&amp;#x2F;project||&amp;#x27; | \
  awk -F&amp;#x27;&amp;#x2F;&amp;#x27; &amp;#x27;{print $1&amp;quot;&amp;#x2F;&amp;quot;$2&amp;quot;&amp;#x2F;&amp;quot;$3&amp;quot;&amp;#x2F;&amp;quot;$4}&amp;#x27; | \
  sort | uniq -c | sort -rn | head -30
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;6-cai-yang-cha-kan-fd-ju-ti-nei-rong&quot;&gt;6. 采样查看 fd 具体内容&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 前 40 个
sudo -A ls -la &amp;#x2F;proc&amp;#x2F;&amp;lt;PID&amp;gt;&amp;#x2F;fd&amp;#x2F; | head -40

# 中间段
sudo -A ls -la &amp;#x2F;proc&amp;#x2F;&amp;lt;PID&amp;gt;&amp;#x2F;fd&amp;#x2F; | sed -n &amp;#x27;5000,5020p&amp;#x27;

# 末尾
sudo -A ls -la &amp;#x2F;proc&amp;#x2F;&amp;lt;PID&amp;gt;&amp;#x2F;fd&amp;#x2F; | tail -20
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;7-jian-cha-virtiofsd-nei-cun-he-zi-yuan-xian-zhi&quot;&gt;7. 检查 virtiofsd 内存和资源限制&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;for pid in &amp;lt;PID_LIST&amp;gt;; do
  echo &amp;quot;=== PID $pid ===&amp;quot;
  cat &amp;#x2F;proc&amp;#x2F;$pid&amp;#x2F;limits | grep -E &amp;quot;open files|processes&amp;quot;
  cat &amp;#x2F;proc&amp;#x2F;$pid&amp;#x2F;status | grep -E &amp;quot;VmRSS|VmSize|Threads&amp;quot;
done
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;8-jian-cha-fuse-lian-jie-can-shu&quot;&gt;8. 检查 FUSE 连接参数&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;ls &amp;#x2F;sys&amp;#x2F;fs&amp;#x2F;fuse&amp;#x2F;connections&amp;#x2F;

for conn in &amp;#x2F;sys&amp;#x2F;fs&amp;#x2F;fuse&amp;#x2F;connections&amp;#x2F;*&amp;#x2F;; do
  echo &amp;quot;=== $(basename $conn) ===&amp;quot;
  cat &amp;quot;$conn&amp;#x2F;max_background&amp;quot; 2&amp;gt;&amp;#x2F;dev&amp;#x2F;null
  cat &amp;quot;$conn&amp;#x2F;congestion_threshold&amp;quot; 2&amp;gt;&amp;#x2F;dev&amp;#x2F;null
  cat &amp;quot;$conn&amp;#x2F;waiting&amp;quot; 2&amp;gt;&amp;#x2F;dev&amp;#x2F;null
done
# max_background 默认 12，congestion_threshold 默认 9
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;9-jian-cha-qemu-jin-cheng&quot;&gt;9. 检查 QEMU 进程&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;ps aux | grep -E &amp;quot;qemu|libvirt&amp;quot; | grep -v grep

for pid in &amp;lt;QEMU_PID_LIST&amp;gt;; do
  stat &amp;#x2F;proc&amp;#x2F;$pid&amp;#x2F;fd | grep Size
done
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;10-quan-xi-tong-fd-tong-ji&quot;&gt;10. 全系统 fd 统计&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;total=0
for p in &amp;#x2F;proc&amp;#x2F;[0-9]*&amp;#x2F;fd&amp;#x2F;; do
  total=$((total + $(ls &amp;quot;$p&amp;quot; 2&amp;gt;&amp;#x2F;dev&amp;#x2F;null | wc -l)))
done
echo &amp;quot;用户可见: $total&amp;quot;
echo &amp;quot;系统分配: $(awk &amp;#x27;{print $1}&amp;#x27; &amp;#x2F;proc&amp;#x2F;sys&amp;#x2F;fs&amp;#x2F;file-nr)&amp;quot;
echo &amp;quot;差值(root): $(( $(awk &amp;#x27;{print $1}&amp;#x27; &amp;#x2F;proc&amp;#x2F;sys&amp;#x2F;fs&amp;#x2F;file-nr) - total ))&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;11-cha-zhao-fd-zui-da-de-jin-cheng&quot;&gt;11. 查找 fd 最大的进程&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;for p in &amp;#x2F;proc&amp;#x2F;[0-9]*&amp;#x2F;fd&amp;#x2F;; do
  size=$(stat -c%s &amp;quot;$p&amp;quot; 2&amp;gt;&amp;#x2F;dev&amp;#x2F;null)
  [ &amp;quot;$size&amp;quot; -gt 1000 ] 2&amp;gt;&amp;#x2F;dev&amp;#x2F;null &amp;amp;&amp;amp; \
    echo &amp;quot;Size=$size PID=$(basename $(dirname $(dirname $p))) Name=$(cat &amp;#x2F;proc&amp;#x2F;$(basename $(dirname $(dirname $p)))&amp;#x2F;comm 2&amp;gt;&amp;#x2F;dev&amp;#x2F;null)&amp;quot;
done | sort -t= -k2 -rn | head -10
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;gen-yin-fen-xi&quot;&gt;根因分析&lt;&#x2F;h2&gt;
&lt;pre&gt;&lt;code&gt;debian13 VM 内某个进程 (IDE&amp;#x2F;编译器&amp;#x2F;文件搜索)
  → 遍历 &amp;#x2F;home&amp;#x2F;peter&amp;#x2F;project 下数十万文件
    → virtiofsd 为每个 open() 在宿主机分配一个真实 fd
      → 数小时内累积数十万 fd + 数 GB 内存
        → 宿主机 file-nr 耗尽 (allocated=1,015,480, free=0)
          → 其他 VM 尝试访问 virtiofs → ENFILE
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;pan-duan-biao-zhun&quot;&gt;判断标准&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;症状&lt;&#x2F;th&gt;&lt;th&gt;结论&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;file-nr&lt;&#x2F;code&gt; 第 2 列 ≈ 0&lt;&#x2F;td&gt;&lt;td&gt;文件表已饱和&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;virtiofsd fd 总数 &amp;gt; 10 万&lt;&#x2F;td&gt;&lt;td&gt;严重泄漏&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;fd 99% 为常规文件&lt;&#x2F;td&gt;&lt;td&gt;VM 内进程遍历文件系统&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;fd 集中在 &lt;code&gt;build&#x2F;cache&lt;&#x2F;code&gt;、&lt;code&gt;node_modules&lt;&#x2F;code&gt;、&lt;code&gt;target&#x2F;debug&lt;&#x2F;code&gt; 等&lt;&#x2F;td&gt;&lt;td&gt;构建工具或 IDE 扫描&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;virtiofsd RSS &amp;gt; 数 GB&lt;&#x2F;td&gt;&lt;td&gt;内存与 fd 同步泄漏&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;xiu-fu-fang-an&quot;&gt;修复方案&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;lin-shi-shi-fang-fd&quot;&gt;临时：释放 fd&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 重启 virtiofsd（会短时断开 VM 内挂载）
sudo -A kill -HUP &amp;lt;virtiofsd_PID&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;vm-nei-qing-li-huan-cun&quot;&gt;VM 内：清理缓存&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 创建定时脚本
cat &amp;gt; &amp;#x2F;usr&amp;#x2F;local&amp;#x2F;bin&amp;#x2F;manage_virtiofs_cache.sh &amp;lt;&amp;lt; &amp;#x27;EOF&amp;#x27;
#!&amp;#x2F;bin&amp;#x2F;bash
CACHED_MB=$(free -m | awk &amp;#x27;&amp;#x2F;^Mem:&amp;#x2F; {print $6}&amp;#x27;)
if [ $CACHED_MB -gt 4096 ]; then
    sync
    echo 3 &amp;gt; &amp;#x2F;proc&amp;#x2F;sys&amp;#x2F;vm&amp;#x2F;drop_caches
fi
EOF
chmod +x &amp;#x2F;usr&amp;#x2F;local&amp;#x2F;bin&amp;#x2F;manage_virtiofs_cache.sh

# crontab: 每 30 分钟执行
# *&amp;#x2F;30 * * * * &amp;#x2F;usr&amp;#x2F;local&amp;#x2F;bin&amp;#x2F;manage_virtiofs_cache.sh
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;vm-nei-diao-zheng-nei-he-can-shu&quot;&gt;VM 内：调整内核参数&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;echo 1000 &amp;gt; &amp;#x2F;proc&amp;#x2F;sys&amp;#x2F;vm&amp;#x2F;vfs_cache_pressure
echo 1000 &amp;gt; &amp;#x2F;proc&amp;#x2F;sys&amp;#x2F;vm&amp;#x2F;dirty_writeback_centisecs

# 持久化
cat &amp;gt;&amp;gt; &amp;#x2F;etc&amp;#x2F;sysctl.conf &amp;lt;&amp;lt; EOF
vm.vfs_cache_pressure=1000
vm.dirty_writeback_centisecs=1000
EOF
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;yong-jiu-xiu-gai-libvirt-pei-zhi&quot;&gt;永久：修改 libvirt 配置&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;xml&quot; class=&quot;language-xml &quot;&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&amp;lt;filesystem type=&amp;#x27;mount&amp;#x27; accessmode=&amp;#x27;passthrough&amp;#x27;&amp;gt;
  &amp;lt;driver type=&amp;#x27;virtiofs&amp;#x27; queue=&amp;#x27;1024&amp;#x27;&amp;#x2F;&amp;gt;
  &amp;lt;source dir=&amp;#x27;&amp;#x2F;home&amp;#x2F;peter&amp;#x2F;project&amp;#x27;&amp;#x2F;&amp;gt;
  &amp;lt;target dir=&amp;#x27;project&amp;#x27;&amp;#x2F;&amp;gt;
  &amp;lt;binary path=&amp;#x27;&amp;#x2F;usr&amp;#x2F;libexec&amp;#x2F;virtiofsd&amp;#x27; xattr=&amp;#x27;on&amp;#x27;&amp;gt;
    &amp;lt;cache size=&amp;#x27;8192&amp;#x27;&amp;#x2F;&amp;gt;
  &amp;lt;&amp;#x2F;binary&amp;gt;
&amp;lt;&amp;#x2F;filesystem&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;he-xin-pai-cha-luo-ji&quot;&gt;核心排查逻辑&lt;&#x2F;h2&gt;
&lt;pre&gt;&lt;code&gt;file-nr 异常高
  → ps 找 virtiofsd 进程
    → ls &amp;#x2F;proc&amp;#x2F;&amp;lt;pid&amp;gt;&amp;#x2F;fd | wc -l 数 fd
      → ls -la &amp;#x2F;proc&amp;#x2F;&amp;lt;pid&amp;gt;&amp;#x2F;fd&amp;#x2F; 看类型
        → awk 按目录聚合 找来源
          → 定位 VM 内是什么进程在遍历文件
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>QEMU 虚拟机无法访问网关&#x2F;公网排查</title>
        <published>2026-06-13T02:30:00+08:00</published>
        <updated>2026-06-13T02:30:00+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2026/06/qemu-vm-network-debug/"/>
        <id>https://vercel.juzhong.xyz/2026/06/qemu-vm-network-debug/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2026/06/qemu-vm-network-debug/">&lt;h1 id=&quot;qemu-xu-ni-ji-wu-fa-fang-wen-wang-guan-gong-wang-pai-cha-wen-dang&quot;&gt;QEMU 虚拟机无法访问网关&#x2F;公网 排查文档&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;xian-xiang&quot;&gt;现象&lt;&#x2F;h2&gt;
&lt;p&gt;QEMU 虚拟机（libvirt）无法 ping 通网关 &lt;code&gt;192.168.2.1&lt;&#x2F;code&gt;，也无法访问公网。宿主机网络正常。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;huan-jing-xin-xi&quot;&gt;环境信息&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;项目&lt;&#x2F;th&gt;&lt;th&gt;值&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;宿主机 IP&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;192.168.2.100&#x2F;24&lt;&#x2F;code&gt; (vmbr0)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;网关&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;192.168.2.1&lt;&#x2F;code&gt; (MAC: &lt;code&gt;74:45:2d:96:7f:cc&lt;&#x2F;code&gt;)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;虚拟机 IP&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;192.168.2.156&lt;&#x2F;code&gt; (MAC: &lt;code&gt;52:54:00:3c:13:73&lt;&#x2F;code&gt;)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;物理网卡&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;eno1&lt;&#x2F;code&gt; (桥接到 vmbr0)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;虚拟网桥&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;vmbr0&lt;&#x2F;code&gt; (含 eno1 + vnet0)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TAP 设备&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;vnet0&lt;&#x2F;code&gt; (VM 接口，桥接到 vmbr0)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;虚拟化&lt;&#x2F;td&gt;&lt;td&gt;QEMU&#x2F;KVM (libvirt 管理)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;pai-cha-bu-zou&quot;&gt;排查步骤&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;1-que-ren-su-zhu-ji-wang-luo-zheng-chang&quot;&gt;1. 确认宿主机网络正常&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;ping -c 2 192.168.2.1
# 结果：正常，0% 丢包
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;2-que-ren-wang-qiao-tuo-bu-zheng-que&quot;&gt;2. 确认网桥拓扑正确&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;brctl show vmbr0
# vmbr0:
#   eno1    (物理网卡)
#   vnet0   (虚拟机 TAP 接口)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;3-zai-vmbr0-shang-zhua-bao-fa-xian-vm-fa-chu-de-icmp-qing-qiu&quot;&gt;3. 在 vmbr0 上抓包 — 发现 VM 发出的 ICMP 请求&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;tcpdump -i vmbr0 -e -n icmp
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;输出：&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;22:28:13.582982 52:54:00:3c:13:73 &amp;gt; 74:45:2d:96:7f:cc, ethertype IPv4 (0x0800), length 98: 192.168.2.156 &amp;gt; 192.168.2.1: ICMP echo request, id 10485, seq 68, length 64
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;结论：&lt;&#x2F;strong&gt; VM 发出的包到达了网桥 vmbr0，但没有收到任何 reply。&lt;&#x2F;p&gt;
&lt;h3 id=&quot;4-zai-wu-li-wang-qia-eno1-shang-zhua-bao-fa-xian-bao-mei-you-dao-da-wu-li-jie-kou&quot;&gt;4. 在物理网卡 eno1 上抓包 — 发现包没有到达物理接口&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;tcpdump -i eno1 -e -n icmp and host 192.168.2.156
# 结果：0 packets captured
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;结论：&lt;&#x2F;strong&gt; VM 的 ICMP 请求在 vmbr0 到 eno1 之间被丢弃了。&lt;&#x2F;p&gt;
&lt;h3 id=&quot;5-jian-cha-bridge-netfilter-she-zhi-fa-xian-guan-jian-wen-ti&quot;&gt;5. 检查 bridge netfilter 设置 — 发现关键问题&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sysctl net.bridge.bridge-nf-call-iptables
# net.bridge.bridge-nf-call-iptables = 1
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;关键发现：&lt;&#x2F;strong&gt; &lt;code&gt;bridge-nf-call-iptables=1&lt;&#x2F;code&gt; 意味着桥接的 L2 流量也会经过 iptables 处理。&lt;&#x2F;p&gt;
&lt;p&gt;虽然 &lt;code&gt;&#x2F;etc&#x2F;sysctl.conf&lt;&#x2F;code&gt; 中配置的是 &lt;code&gt;=0&lt;&#x2F;code&gt;，但 Docker 启动时会将其设为 &lt;code&gt;1&lt;&#x2F;code&gt;（Docker 依赖此设置来实现容器网络隔离和端口映射）。&lt;&#x2F;p&gt;
&lt;h3 id=&quot;6-jian-cha-iptables-forward-lian-que-ren-diu-bao-dian&quot;&gt;6. 检查 iptables FORWARD 链 — 确认丢包点&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;iptables -L FORWARD -n -v
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;Chain FORWARD (policy DROP 3727K packets, 1454M bytes)
 pkts bytes target     prot opt in     out     source               destination
  229 24446 ACCEPT     all  --  vmbr0  tun0    192.168.2.0&amp;#x2F;24       192.168.4.0&amp;#x2F;22
  477  513K ACCEPT     all  --  tun0   vmbr0   192.168.4.0&amp;#x2F;22       192.168.2.0&amp;#x2F;24
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;根因确认：&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;FORWARD 链默认策略为 &lt;code&gt;DROP&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;仅有的两条涉及 vmbr0 的规则只允许 &lt;code&gt;vmbr0 &amp;lt;-&amp;gt; tun0&lt;&#x2F;code&gt; 的 VPN 流量（192.168.2.0&#x2F;24 &amp;lt;-&amp;gt; 192.168.4.0&#x2F;22）&lt;&#x2F;li&gt;
&lt;li&gt;没有规则允许 vmbr0 的普通桥接流量（如 VM -&amp;gt; 网关）&lt;&#x2F;li&gt;
&lt;li&gt;因此 VM 发出的包在到达网桥后被 iptables DROP 掉，无法到达物理网卡 eno1&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;shu-ju-liu-shi-yi&quot;&gt;数据流示意&lt;&#x2F;h3&gt;
&lt;pre&gt;&lt;code&gt;VM (192.168.2.156)
    │
    ▼ ICMP echo request
 vnet0 ─── vmbr0 ─── ✗ iptables FORWARD DROP ─── eno1 (物理网卡)
                       (无匹配规则)                │
                                                   ▼
                                             Gateway (192.168.2.1)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;xiu-fu-fang-an&quot;&gt;修复方案&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;li-ji-xiu-fu&quot;&gt;立即修复&lt;&#x2F;h3&gt;
&lt;p&gt;添加规则允许桥接流量通过 iptables：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;iptables -I FORWARD -m physdev --physdev-is-bridged -j ACCEPT
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-m physdev --physdev-is-bridged&lt;&#x2F;code&gt; 精确匹配经过桥接转发的流量&lt;&#x2F;li&gt;
&lt;li&gt;将该规则插入 FORWARD 链首部，优先于 Docker 的链&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;chi-jiu-hua&quot;&gt;持久化&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;netfilter-persistent save
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;该命令将当前 iptables 规则保存到 &lt;code&gt;&#x2F;etc&#x2F;iptables&#x2F;rules.v4&lt;&#x2F;code&gt;，重启后自动恢复。&lt;&#x2F;p&gt;
&lt;h3 id=&quot;yan-zheng&quot;&gt;验证&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;iptables -L FORWARD -n -v
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;Chain FORWARD (policy DROP)
 pkts bytes target     prot opt in     out     source               destination
  155 44480 ACCEPT     all  --  *      *       0.0.0.0&amp;#x2F;0            0.0.0.0&amp;#x2F;0            PHYSDEV match --physdev-is-bridged
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;tcpdump -i eno1 -e -n icmp
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;22:30:08.217904 52:54:00:3c:13:73 &amp;gt; 74:45:2d:96:7f:cc: 192.168.2.156 &amp;gt; 192.168.2.1: ICMP echo request
22:30:08.218266 74:45:2d:96:7f:cc &amp;gt; 52:54:00:3c:13:73: 192.168.2.1 &amp;gt; 192.168.2.156: ICMP echo reply
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;VM 的 ICMP 请求和网关的回复均已正常到达物理网卡，问题解决。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bei-xuan-fang-an&quot;&gt;备选方案&lt;&#x2F;h2&gt;
&lt;p&gt;如果不想依赖 iptables 规则，也可以禁用 bridge netfilter：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sysctl -w net.bridge.bridge-nf-call-iptables=0
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;但此方案会导致 Docker 的端口映射和容器间隔离失效，&lt;strong&gt;不推荐&lt;&#x2F;strong&gt;在有 Docker 运行的环境中采用。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;guan-jian-ming-ling-su-cha&quot;&gt;关键命令速查&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;用途&lt;&#x2F;th&gt;&lt;th&gt;命令&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;查看网桥成员&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;brctl show&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;查看 bridge netfilter 状态&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;sysctl net.bridge.bridge-nf-call-iptables&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;查看 iptables FORWARD 链&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;iptables -L FORWARD -n -v&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;网桥上抓包&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;tcpdump -i vmbr0 -e -n icmp&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;物理接口上抓包&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;tcpdump -i eno1 -e -n icmp&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;保存 iptables 规则&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;netfilter-persistent save&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>批量添加 GitHub 仓库协作者</title>
        <published>2026-06-13T01:43:45+08:00</published>
        <updated>2026-06-13T01:43:45+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2026/06/batch-add-github-collaborator/"/>
        <id>https://vercel.juzhong.xyz/2026/06/batch-add-github-collaborator/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2026/06/batch-add-github-collaborator/">&lt;h1 id=&quot;gai-shu&quot;&gt;概述&lt;&#x2F;h1&gt;
&lt;p&gt;使用 Playwright CLI 连接远程浏览器，批量为 &lt;code&gt;peterlishihu&lt;&#x2F;code&gt; 用户下全部 29 个仓库添加 &lt;code&gt;moxuetianya&lt;&#x2F;code&gt; 作为协作者。&lt;&#x2F;p&gt;
&lt;h1 id=&quot;huan-jing&quot;&gt;环境&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;本地机器&lt;&#x2F;strong&gt;: 通过 SSH 隧道转发远程 Chrome 调试端口&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;远程浏览器&lt;&#x2F;strong&gt;: Chrome 149, 以 &lt;code&gt;--remote-debugging-port=9222 --remote-debugging-address=0.0.0.0&lt;&#x2F;code&gt; 启动&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Playwright CLI&lt;&#x2F;strong&gt;: 通过 CDP 协议连接 &lt;code&gt;http:&#x2F;&#x2F;127.0.0.1:9222&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 远程机器启动 Chrome
google-chrome --remote-debugging-port=9222 --remote-debugging-address=0.0.0.0 --user-data-dir=&amp;#x2F;tmp&amp;#x2F;chrome-debug

# 本地建立 SSH 隧道
ssh -L 9222:127.0.0.1:9222 user@192.168.2.100

# 连接远程浏览器
playwright-cli attach --cdp=http:&amp;#x2F;&amp;#x2F;127.0.0.1:9222
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;cao-zuo-liu-cheng&quot;&gt;操作流程&lt;&#x2F;h1&gt;
&lt;p&gt;对每个仓库执行以下步骤：&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;导航到仓库的 Collaborators 设置页 (&lt;code&gt;&#x2F;&amp;lt;owner&amp;gt;&#x2F;&amp;lt;repo&amp;gt;&#x2F;settings&#x2F;access&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;检查页面是否已包含 &lt;code&gt;@moxuetianya&lt;&#x2F;code&gt;，若有则跳过&lt;&#x2F;li&gt;
&lt;li&gt;点击 &lt;strong&gt;&quot;Add people&quot;&lt;&#x2F;strong&gt; 按钮&lt;&#x2F;li&gt;
&lt;li&gt;在弹出的对话框中输入 &lt;code&gt;moxuetianya&lt;&#x2F;code&gt; 搜索用户&lt;&#x2F;li&gt;
&lt;li&gt;检查搜索结果是否已禁用（表示已邀请），若是则关闭对话框跳过&lt;&#x2F;li&gt;
&lt;li&gt;选中 &lt;code&gt;@moxuetianya&lt;&#x2F;code&gt; 选项&lt;&#x2F;li&gt;
&lt;li&gt;点击 &lt;strong&gt;&quot;Add moxuetianya&quot;&lt;&#x2F;strong&gt; 确认添加&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h1 id=&quot;playwright-jiao-ben&quot;&gt;Playwright 脚本&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;javascript&quot; class=&quot;language-javascript &quot;&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;async page =&amp;gt; {
  const repos = [&amp;quot;proxy-shoes&amp;quot;,&amp;quot;learn-frontend&amp;quot;,&amp;quot;learn-architecture&amp;quot;,&amp;quot;his&amp;quot;,&amp;#x2F;* ... 共29个 *&amp;#x2F;];

  for (const repo of repos) {
    await page.goto(`https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;peterlishihu&amp;#x2F;${repo}&amp;#x2F;settings&amp;#x2F;access`, { waitUntil: &amp;#x27;load&amp;#x27; });
    await page.waitForTimeout(2500);

    &amp;#x2F;&amp;#x2F; 检查是否已存在
    const text = await page.evaluate(() =&amp;gt; document.body.innerText);
    if (text.includes(&amp;#x27;@moxuetianya&amp;#x27;)) continue;

    &amp;#x2F;&amp;#x2F; 打开添加对话框
    await page.getByRole(&amp;#x27;button&amp;#x27;, { name: &amp;#x27;Add people&amp;#x27; }).click();
    await page.waitForTimeout(1000);

    &amp;#x2F;&amp;#x2F; 搜索用户
    await page.getByRole(&amp;#x27;combobox&amp;#x27;, { name: &amp;#x27;Find people&amp;#x27; }).fill(&amp;#x27;moxuetianya&amp;#x27;);
    await page.waitForTimeout(2000);

    &amp;#x2F;&amp;#x2F; 检查是否已禁用（已邀请）
    const disabled = await page.evaluate(() =&amp;gt; {
      const opt = document.querySelector(&amp;#x27;[role=&amp;quot;option&amp;quot;][aria-disabled=&amp;quot;true&amp;quot;]&amp;#x27;);
      return opt &amp;amp;&amp;amp; opt.textContent.includes(&amp;#x27;moxuetianya&amp;#x27;);
    });
    if (disabled) { await page.keyboard.press(&amp;#x27;Escape&amp;#x27;); continue; }

    &amp;#x2F;&amp;#x2F; 选中并确认
    await page.getByRole(&amp;#x27;option&amp;#x27;, { name: &amp;#x27;@moxuetianya&amp;#x27; }).click();
    await page.getByRole(&amp;#x27;button&amp;#x27;, { name: &amp;#x2F;Add moxuetianya&amp;#x2F; }).click();
    await page.waitForTimeout(2000);
  }
};
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;jie-guo-tong-ji&quot;&gt;结果统计&lt;&#x2F;h1&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;状态&lt;&#x2F;th&gt;&lt;th&gt;数量&lt;&#x2F;th&gt;&lt;th&gt;仓库&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;本次添加&lt;&#x2F;td&gt;&lt;td&gt;15&lt;&#x2F;td&gt;&lt;td&gt;learn-frontend, his, learn-pipewire-bluetooth, mobile-smb, obsidian, trace-learn, learn-langchain, learn-protobuf, learn-tcpip, bt-learn, wifi-learn, zod-learn, p2p-learn, my-skills, Qwen3.5&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;已存在&lt;&#x2F;td&gt;&lt;td&gt;14&lt;&#x2F;td&gt;&lt;td&gt;proxy-shoes, learn-architecture, learn-tpm-grub, learn-linux, linux-translate, linux-dlna, learn-opencode, juzhong, phone-access-card, claude-config, learn-vless, learn-ssh, learn-tls, learn-socks5&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;&lt;strong&gt;全部 29 个仓库均已完成。&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>deploy blog to github cloudflare vercel</title>
        <published>2026-06-13T00:17:10+08:00</published>
        <updated>2026-06-13T00:17:10+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2026/06/deploy-blog-to-github-cloudflare-vercel/"/>
        <id>https://vercel.juzhong.xyz/2026/06/deploy-blog-to-github-cloudflare-vercel/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2026/06/deploy-blog-to-github-cloudflare-vercel/">&lt;h1 id=&quot;zhun-bei-gong-zuo&quot;&gt;准备工作&lt;&#x2F;h1&gt;
&lt;p&gt;先构建站点，确认 &lt;code&gt;public&#x2F;&lt;&#x2F;code&gt; 目录正常生成：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;zola build
ls public&amp;#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;github-pages&quot;&gt;GitHub Pages&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;chuang-jian-cang-ku&quot;&gt;创建仓库&lt;&#x2F;h2&gt;
&lt;p&gt;创建 &lt;code&gt;github.com&#x2F;&amp;lt;你的用户名&amp;gt;&#x2F;&amp;lt;你的用户名&amp;gt;.github.io&lt;&#x2F;code&gt; 仓库，这是 GitHub 的 user site，域名固定为 &lt;code&gt;https:&#x2F;&#x2F;&amp;lt;用户名&amp;gt;.github.io&lt;&#x2F;code&gt;。&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git init
git remote add origin git@github.com:&amp;lt;用户名&amp;gt;&amp;#x2F;&amp;lt;用户名&amp;gt;.github.io.git
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;github-actions-zi-dong-bu-shu&quot;&gt;GitHub Actions 自动部署&lt;&#x2F;h2&gt;
&lt;p&gt;创建 &lt;code&gt;.github&#x2F;workflows&#x2F;deploy.yml&lt;&#x2F;code&gt;：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;yaml&quot; class=&quot;language-yaml &quot;&gt;&lt;code class=&quot;language-yaml&quot; data-lang=&quot;yaml&quot;&gt;name: Deploy Zola Blog

on:
  push:
    branches: [master]

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions&amp;#x2F;checkout@v4
        with:
          submodules: recursive

      - name: Install Zola
        run: |
          ZOLA_VERSION=$(curl -s https:&amp;#x2F;&amp;#x2F;api.github.com&amp;#x2F;repos&amp;#x2F;getzola&amp;#x2F;zola&amp;#x2F;releases&amp;#x2F;latest | grep tag_name | cut -d &amp;#x27;&amp;quot;&amp;#x27; -f4)
          curl -sL &amp;quot;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;getzola&amp;#x2F;zola&amp;#x2F;releases&amp;#x2F;download&amp;#x2F;${ZOLA_VERSION}&amp;#x2F;zola-${ZOLA_VERSION}-x86_64-unknown-linux-gnu.tar.gz&amp;quot; | tar xz
          sudo mv zola &amp;#x2F;usr&amp;#x2F;local&amp;#x2F;bin&amp;#x2F;

      - name: Build
        run: zola build

      - name: Deploy
        uses: peaceiris&amp;#x2F;actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: .&amp;#x2F;public
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;推送后 GitHub Actions 自动构建并部署到 &lt;code&gt;gh-pages&lt;&#x2F;code&gt; 分支。在仓库 Settings → Pages 中选择 &lt;code&gt;gh-pages&lt;&#x2F;code&gt; 分支作为部署源。&lt;&#x2F;p&gt;
&lt;h1 id=&quot;cloudflare-pages&quot;&gt;Cloudflare Pages&lt;&#x2F;h1&gt;
&lt;p&gt;Cloudflare Pages 直接托管静态站点，支持自定义域名 &lt;code&gt;juzhong.xyz&lt;&#x2F;code&gt; 或子域名如 &lt;code&gt;blog.juzhong.xyz&lt;&#x2F;code&gt;。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;lian-jie-github-cang-ku&quot;&gt;连接 GitHub 仓库&lt;&#x2F;h2&gt;
&lt;p&gt;在 Cloudflare Dashboard → Workers &amp;amp; Pages → Pages → 创建项目，连接 GitHub 仓库。&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;构建配置：&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;配置项&lt;&#x2F;th&gt;&lt;th&gt;值&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;构建命令&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;zola build&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;输出目录&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;public&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;环境变量&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;ZOLA_VERSION=0.19.2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Cloudflare Pages 内置了 Zola 支持，会自动下载对应版本。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zi-ding-yi-yu-ming&quot;&gt;自定义域名&lt;&#x2F;h2&gt;
&lt;p&gt;Pages 项目 → 自定义域 → 添加 &lt;code&gt;blog.juzhong.xyz&lt;&#x2F;code&gt;。&lt;&#x2F;p&gt;
&lt;p&gt;需要在 &lt;code&gt;juzhong.xyz&lt;&#x2F;code&gt; 的 DNS 中添加 CNAME 记录：&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;blog.juzhong.xyz  CNAME  &amp;lt;项目名&amp;gt;.pages.dev
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Cloudflare 代理（橙色云朵）开启后自动提供 HTTPS。&lt;&#x2F;p&gt;
&lt;h1 id=&quot;vercel&quot;&gt;Vercel&lt;&#x2F;h1&gt;
&lt;p&gt;Vercel 也支持 Zola 静态站点，但默认构建环境没有 Zola 版本太低，需要自定义构建命令。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;lian-jie-cang-ku-yu-gou-jian-pei-zhi&quot;&gt;连接仓库与构建配置&lt;&#x2F;h2&gt;
&lt;p&gt;访问 &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;vercel.com&#x2F;new&quot;&gt;vercel.com&#x2F;new&lt;&#x2F;a&gt; 导入 GitHub 仓库。&lt;&#x2F;p&gt;
&lt;p&gt;Vercel 可能无法自动识别 Zola 项目，手动配置构建参数：&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;配置项&lt;&#x2F;th&gt;&lt;th&gt;值&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Framework&lt;&#x2F;td&gt;&lt;td&gt;Other&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Build Command&lt;&#x2F;td&gt;&lt;td&gt;&lt;em&gt;见下方自定义命令&lt;&#x2F;em&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Output Directory&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;public&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;&lt;strong&gt;自定义构建命令&lt;&#x2F;strong&gt;（下载指定版本 Zola 并构建）：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;curl -sL https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;getzola&amp;#x2F;zola&amp;#x2F;releases&amp;#x2F;download&amp;#x2F;v0.19.2&amp;#x2F;zola-v0.19.2-x86_64-unknown-linux-gnu.tar.gz | tar -xzf - &amp;amp;&amp;amp; .&amp;#x2F;zola build --base-url https:&amp;#x2F;&amp;#x2F;vercel.juzhong.xyz
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;拆解说明：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;curl -sL ... | tar -xzf -&lt;&#x2F;code&gt; —— 下载 Zola v0.19.2 二进制包并解压到当前目录&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;.&#x2F;zola build --base-url https:&#x2F;&#x2F;vercel.juzhong.xyz&lt;&#x2F;code&gt; —— 用本地 Zola 构建，&lt;code&gt;--base-url&lt;&#x2F;code&gt; 指定站点根 URL，确保绝对路径（如 RSS、sitemap）正确&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;&#x2F;strong&gt;：将 &lt;code&gt;vercel.juzhong.xyz&lt;&#x2F;code&gt; 替换为你的实际域名；如果没有自定义域名，使用 Vercel 分配的 &lt;code&gt;xxx.vercel.app&lt;&#x2F;code&gt; 域名。&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;zi-ding-yi-yu-ming-pei-zhi-yi-cloudflare-wei-li&quot;&gt;自定义域名配置（以 Cloudflare 为例）&lt;&#x2F;h2&gt;
&lt;p&gt;下面以子域名 &lt;code&gt;vercel.juzhong.xyz&lt;&#x2F;code&gt; 为例，DNS 解析由 Cloudflare 管理。&lt;&#x2F;p&gt;
&lt;h3 id=&quot;di-yi-jie-duan-vercel-ping-tai-cao-zuo&quot;&gt;第一阶段：Vercel 平台操作&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;进入项目仪表板，点击顶部 &lt;strong&gt;Settings&lt;&#x2F;strong&gt; → 左侧菜单 &lt;strong&gt;Domains&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;输入完整域名（例如 &lt;code&gt;vercel.juzhong.xyz&lt;&#x2F;code&gt;），点击 &lt;strong&gt;Add&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;页面会提示 &lt;em&gt;Invalid Configuration&lt;&#x2F;em&gt;（正常），点击域名旁边的 &lt;strong&gt;View&lt;&#x2F;strong&gt; 查看需要的 DNS 记录&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Vercel 通常建议添加以下记录：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A 记录&lt;&#x2F;strong&gt;：将根域名指向 &lt;code&gt;76.76.21.21&lt;&#x2F;code&gt;（Vercel 的 IP）&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;CNAME 记录&lt;&#x2F;strong&gt;：将子域名指向 &lt;code&gt;cname.vercel-dns.com&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;cname.vercel-dns.com — 全球通用&lt;&#x2F;li&gt;
&lt;li&gt;cname-china.vercel-dns.com — 国内专用节点，中国大陆访问速度更快、更稳定&lt;&#x2F;li&gt;
&lt;li&gt;由于你在国内使用，强烈推荐使用 cname-china.vercel-dns.com。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote&gt;
&lt;p&gt;本项目使用子域名，只需 CNAME 记录即可。&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;di-er-jie-duan-cloudflare-dns-cao-zuo&quot;&gt;第二阶段：Cloudflare DNS 操作&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;登录 Cloudflare 仪表板 → 选择域名 &lt;code&gt;juzhong.xyz&lt;&#x2F;code&gt; → &lt;strong&gt;DNS&lt;&#x2F;strong&gt; → &lt;strong&gt;记录&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;点击 &lt;strong&gt;添加记录&lt;&#x2F;strong&gt;，配置如下：&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;字段&lt;&#x2F;th&gt;&lt;th&gt;值&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;类型&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;CNAME&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;名称&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;vercel&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;目标&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;cname.vercel-dns.com&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;代理状态&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;仅 DNS&lt;&#x2F;strong&gt;（灰色云朵 ☁️）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;&lt;strong&gt;关键&lt;&#x2F;strong&gt;：代理状态务必选择灰色云朵（仅 DNS），不要开启橙色云朵（代理）。&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;为什么？&lt;&#x2F;strong&gt; Vercel 使用 Let&#x27;s Encrypt 自动签发 SSL 证书，需要通过 ACME 协议验证域名所有权。Cloudflare 橙色代理会拦截 ACME 验证请求，导致证书签发失败、域名始终显示 &lt;em&gt;Invalid Configuration&lt;&#x2F;em&gt;。&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;strong&gt;特殊情况：根域名配置&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;DNS 标准不允许根域名（&lt;code&gt;@&lt;&#x2F;code&gt;）使用 CNAME 记录。Cloudflare 通过 &lt;strong&gt;CNAME Flattening&lt;&#x2F;strong&gt; 技术自动将根域名的 CNAME 转换为 A 记录，你只需正常添加 CNAME 记录，名称写 &lt;code&gt;@&lt;&#x2F;code&gt; 即可。&lt;&#x2F;p&gt;
&lt;p&gt;如果 Vercel 提示根域名需要 A 记录，则改为：&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;字段&lt;&#x2F;th&gt;&lt;th&gt;值&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;类型&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;A&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;名称&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;@&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;IPv4 地址&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;76.76.21.21&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;di-san-jie-duan-yan-zheng-yu-sheng-xiao&quot;&gt;第三阶段：验证与生效&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;DNS 记录全球生效通常需要几分钟到几十分钟&lt;&#x2F;li&gt;
&lt;li&gt;回到 Vercel 项目 &lt;strong&gt;Domains&lt;&#x2F;strong&gt; 页面，状态从红色 &lt;em&gt;Invalid Configuration&lt;&#x2F;em&gt; 变为绿色 &lt;em&gt;Valid Configuration&lt;&#x2F;em&gt; 即表示成功&lt;&#x2F;li&gt;
&lt;li&gt;SSL 证书自动签发，通常 1-3 分钟内完成&lt;&#x2F;li&gt;
&lt;li&gt;访问 &lt;code&gt;https:&#x2F;&#x2F;vercel.juzhong.xyz&lt;&#x2F;code&gt; 确认站点正常&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;e-wai-pei-zhi-url-zhong-ding-xiang-ke-xuan&quot;&gt;额外配置：URL 重定向（可选）&lt;&#x2F;h3&gt;
&lt;p&gt;在 Vercel 的 Domains 页面，点击域名旁边的 &lt;strong&gt;Edit&lt;&#x2F;strong&gt;，可设置：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;将 &lt;code&gt;www.vercel.juzhong.xyz&lt;&#x2F;code&gt; 重定向到 &lt;code&gt;vercel.juzhong.xyz&lt;&#x2F;code&gt;（或反之）&lt;&#x2F;li&gt;
&lt;li&gt;如需同时使用 www 子域名，需在 Cloudflare 再添加一条名称 &lt;code&gt;www.vercel&lt;&#x2F;code&gt; 的 CNAME 记录，并同样加入 Vercel 项目&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;chang-jian-wen-ti-pai-cha&quot;&gt;常见问题排查&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;问题&lt;&#x2F;th&gt;&lt;th&gt;原因&lt;&#x2F;th&gt;&lt;th&gt;解决&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;状态一直 &lt;em&gt;Invalid&lt;&#x2F;em&gt;&lt;&#x2F;td&gt;&lt;td&gt;Cloudflare 代理未关闭（橙色云朵）&lt;&#x2F;td&gt;&lt;td&gt;将 DNS 记录的代理状态改为灰色（仅 DNS）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;DNS 记录冲突&lt;&#x2F;td&gt;&lt;td&gt;Cloudflare 中存在旧 A&#x2F;AAAA 记录与 CNAME 冲突&lt;&#x2F;td&gt;&lt;td&gt;删除无关的解析记录，只保留 Vercel 所需的&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;www 子域名无法访问&lt;&#x2F;td&gt;&lt;td&gt;Vercel 不会自动添加 www 子域名&lt;&#x2F;td&gt;&lt;td&gt;手动在 Vercel 中添加 &lt;code&gt;www.vercel.juzhong.xyz&lt;&#x2F;code&gt;，并添加对应的 Cloudflare DNS 记录&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;SSL 证书续期失败&lt;&#x2F;td&gt;&lt;td&gt;后续开启了 Cloudflare 代理（橙色云朵），拦截了 ACME 验证&lt;&#x2F;td&gt;&lt;td&gt;在 Cloudflare Zero Trust 中为路径 &lt;code&gt;&#x2F;.well-known&#x2F;acme-challenge&#x2F;*&lt;&#x2F;code&gt; 设置 Bypass 策略；或在证书续期期间临时关闭代理&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h1 id=&quot;san-ping-tai-dui-bi&quot;&gt;三平台对比&lt;&#x2F;h1&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;&#x2F;th&gt;&lt;th&gt;GitHub Pages&lt;&#x2F;th&gt;&lt;th&gt;Cloudflare Pages&lt;&#x2F;th&gt;&lt;th&gt;Vercel&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;免费额度&lt;&#x2F;td&gt;&lt;td&gt;无限&lt;&#x2F;td&gt;&lt;td&gt;无限&lt;&#x2F;td&gt;&lt;td&gt;100GB&#x2F;月带宽&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;自定义域名&lt;&#x2F;td&gt;&lt;td&gt;支持&lt;&#x2F;td&gt;&lt;td&gt;支持&lt;&#x2F;td&gt;&lt;td&gt;支持&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;HTTPS&lt;&#x2F;td&gt;&lt;td&gt;自动&lt;&#x2F;td&gt;&lt;td&gt;自动&lt;&#x2F;td&gt;&lt;td&gt;自动&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;构建时间&lt;&#x2F;td&gt;&lt;td&gt;10min&#x2F;次&lt;&#x2F;td&gt;&lt;td&gt;500次&#x2F;月&lt;&#x2F;td&gt;&lt;td&gt;6000min&#x2F;月&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;域名&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;xxx.github.io&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;xxx.pages.dev&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;xxx.vercel.app&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;适用场景&lt;&#x2F;td&gt;&lt;td&gt;简单托管&lt;&#x2F;td&gt;&lt;td&gt;需要自定义域名 + CDN&lt;&#x2F;td&gt;&lt;td&gt;开发预览&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;&lt;strong&gt;推荐方案&lt;&#x2F;strong&gt;：源码放 GitHub，用 Cloudflare Pages 部署到 &lt;code&gt;blog.juzhong.xyz&lt;&#x2F;code&gt;。GitHub 负责版本管理，Cloudflare 提供全球 CDN 和免费 HTTPS。&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>启动libvirt失败</title>
        <published>2026-03-23T15:41:47+08:00</published>
        <updated>2026-03-23T15:41:47+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2026/03/启动libvirt失败/"/>
        <id>https://vercel.juzhong.xyz/2026/03/启动libvirt失败/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2026/03/启动libvirt失败/">&lt;h1 id=&quot;bao-cuo-nei-rong&quot;&gt;报错内容&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo virsh start debian13
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text &quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;error: 启动域 &amp;#x27;debian13&amp;#x27; 失败 
error: 内部错误：连接监控的过程中进程退出: 2026-03-23T03:21:25.801780Z qemu-system-x86_64: -blockdev {&amp;quot;driver&amp;quot;:&amp;quot;file&amp;quot;,&amp;quot;filename&amp;quot;:&amp;quot;&amp;#x2F;data&amp;#x2F;sharing&amp;#x2F;iso&amp;#x2F;debian13&amp;#x2F;debian-13.3.0-amd64-DVD-1.iso&amp;quot;,&amp;quot;node-name&amp;quot;:&amp;quot;libvirt-1-storage&amp;quot;,&amp;quot;read-only&amp;quot;:true}: Could not open &amp;#x27;&amp;#x2F;data&amp;#x2F;sharing&amp;#x2F;iso&amp;#x2F;debian13&amp;#x2F;debian-13.3.0-amd64-DVD-1.iso&amp;#x27;: Permission denied
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;pai-cha-guo-cheng&quot;&gt;排查过程&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 检查iso文件读权限
sudo -u libvirt-qemu test -r &amp;#x2F;data&amp;#x2F;sharing&amp;#x2F;iso&amp;#x2F;debian13&amp;#x2F;debian-13.3.0-amd64-DVD-1.iso &amp;amp;&amp;amp; echo OK || echo FAIL

# 检查apparmor
sudo dmesg | grep -i apparmor | grep DENIED
sudo vim &amp;#x2F;etc&amp;#x2F;apparmor.d&amp;#x2F;local&amp;#x2F;usr.sbin.libvirtd
# &amp;#x2F;data&amp;#x2F;sharing&amp;#x2F;iso&amp;#x2F; r,
# &amp;#x2F;data&amp;#x2F;sharing&amp;#x2F;iso&amp;#x2F;** rk,
# r: 代表读取权限。
# k: 代表文件锁定权限（虚拟机运行 ISO 有时需要）
sudo apparmor_parser -r &amp;#x2F;etc&amp;#x2F;apparmor.d&amp;#x2F;local&amp;#x2F;usr.sbin.libvirtd
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>linux 网络不通网卡缺陷排查记录</title>
        <published>2026-03-20T01:56:07+00:00</published>
        <updated>2026-03-20T01:56:07+00:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2026/03/linux 网络不通网卡缺陷排查记录/"/>
        <id>https://vercel.juzhong.xyz/2026/03/linux 网络不通网卡缺陷排查记录/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2026/03/linux 网络不通网卡缺陷排查记录/">&lt;h1 id=&quot;xian-xiang&quot;&gt;现象&lt;&#x2F;h1&gt;
&lt;p&gt;查看&lt;code&gt;ip route&lt;&#x2F;code&gt; &lt;code&gt;ip link&lt;&#x2F;code&gt; &lt;code&gt;ip -4 addr&lt;&#x2F;code&gt; &lt;code&gt;bridge show&lt;&#x2F;code&gt; 等多个命令，没有发现明显问题
怀疑是linux网桥导致的问题，后面发现是物理网卡hung了&lt;&#x2F;p&gt;
&lt;h1 id=&quot;cha-kan-dmesg&quot;&gt;查看dmesg&lt;&#x2F;h1&gt;
&lt;p&gt;sudo dmesg -w&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;txt&quot; class=&quot;language-txt &quot;&gt;&lt;code class=&quot;language-txt&quot; data-lang=&quot;txt&quot;&gt;[318451.739250] e1000e 0000:00:1f.6 enp0s31f6: Detected Hardware Unit Hang:
                  TDH                  &amp;lt;ed&amp;gt;
                  TDT                  &amp;lt;10&amp;gt;
                  next_to_use          &amp;lt;10&amp;gt;
                  next_to_clean        &amp;lt;ec&amp;gt;
                buffer_info[next_to_clean]:
                  time_stamp           &amp;lt;110b9fd62&amp;gt;
                  next_to_watch        &amp;lt;ed&amp;gt;
                  jiffies              &amp;lt;112f6a400&amp;gt;
                  next_to_watch.status &amp;lt;0&amp;gt;
                MAC Status             &amp;lt;40080083&amp;gt;
                PHY Status             &amp;lt;796d&amp;gt;
                PHY 1000BASE-T Status  &amp;lt;3800&amp;gt;
                PHY Extended Status    &amp;lt;3000&amp;gt;
                PCI Status             &amp;lt;10&amp;gt;

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;zhen-duan-jie-guo-he-xin-zhen-duan&quot;&gt;诊断结果 核心诊断&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;硬件型号：Intel I219-LM (rev 11)。这是 Dell OptiPlex 7090 等商用机常见的板载网卡。&lt;&#x2F;li&gt;
&lt;li&gt;内核版本：6.17.0-19-generic。这是一个非常新的内核（Ubuntu 24.04 的 HWE 边缘或开发版内核）。&lt;&#x2F;li&gt;
&lt;li&gt;故障原因：新版内核中的 e1000e 驱动与 I219-LM (rev 11) 存在兼容性问题。&lt;&#x2F;li&gt;
&lt;li&gt;Intel I219 系列网卡在 Linux 下以“挑剔”著称，经常在新内核中出现 Hardware Unit Hang。&lt;&#x2F;li&gt;
&lt;li&gt;错误日志显示驱动检测到发送&#x2F;接收队列死锁，这通常是因为新内核的电源管理策略（ASPM）或中断处理逻辑与该特定修订版（rev 11）的硬件不匹配导致的。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;jie-jue-fang-an&quot;&gt;解决方案&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;lin-shi-ce-shi-wu-xu-zhong-qi-yun-xing-yi-xia-ming-ling-guan-bi-gai-wang-qia-de-aspm-zhu-dong-zhuang-tai-dian-yuan-guan-li&quot;&gt;临时测试（无需重启）： 运行以下命令关闭该网卡的 ASPM（主动状态电源管理）：&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 注意：需要 root 权限
sudo setpci -s 00:1f.6 0x50.B=0x00
# 如果命令提示找不到 setpci，请先安装：
sudo apt install pciutils
执行完上述命令后，重置网卡：
``` bash
sudo ip link set enp0s31f6 down
sudo ip link set enp0s31f6 up
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;yong-jiu-sheng-xiao-xiu-gai-grub&quot;&gt;永久生效（修改 GRUB）：&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;如果临时测试有效，需要修改启动参数永久生效：&lt;&#x2F;li&gt;
&lt;li&gt;sudo nano &#x2F;etc&#x2F;default&#x2F;grub&lt;&#x2F;li&gt;
&lt;li&gt;找到 GRUB_CMDLINE_LINUX_DEFAULT 这一行，在引号内添加 pcie_aspm=off。&lt;&#x2F;li&gt;
&lt;li&gt;GRUB_CMDLINE_LINUX_DEFAULT=&quot;quiet splash pcie_aspm=off&quot;&lt;&#x2F;li&gt;
&lt;li&gt;保存退出后，更新 GRUB 并重启：&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo update-grub
sudo reboot
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;jin-yong-te-ding-de-wang-qia-jie-neng-gong-neng&quot;&gt;禁用特定的网卡节能功能&lt;&#x2F;h2&gt;
&lt;p&gt;如果方案一无效，尝试通过 ethtool 禁用网卡内部的节能选项。&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt install ethtool
sudo ethtool enp0s31f6 | grep -E &amp;quot;Wake-on|Energy&amp;quot;
# 关闭 Wake-on-LAN
sudo ethtool -s enp0s31f6 wol d

# 关闭 Energy Efficient Ethernet (EEE) - 这对 I219 很重要
sudo ethtool --set-eee enp0s31f6 eee off
# 注：如果 --set-eee 提示不支持，可以忽略该行。
# 为了让这些设置在重启后依然有效，你可以创建一个 systemd 服务或将其放入 &amp;#x2F;etc&amp;#x2F;network&amp;#x2F;interfaces (如果是旧版 networking) 或 Netplan 的配置中。
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;快速临时测试脚本：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo ip link set enp0s31f6 down
sudo ethtool -s enp0s31f6 wol d
sudo ethtool --set-eee enp0s31f6 eee off 2&amp;gt;&amp;#x2F;dev&amp;#x2F;null
sudo ip link set enp0s31f6 up
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>sshd 安全加固</title>
        <published>2026-03-02T14:21:16+08:00</published>
        <updated>2026-03-02T14:21:16+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2026/03/sshd 安全加固/"/>
        <id>https://vercel.juzhong.xyz/2026/03/sshd 安全加固/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2026/03/sshd 安全加固/">&lt;h1 id=&quot;an-zhuang-fail2ban&quot;&gt;安装fail2ban&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt install fail2ban
sudo systemctl enable --now fail2ban
sudo fail2ban status sshd
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;sshd-pei-zhi&quot;&gt;sshd 配置&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;ini&quot; class=&quot;language-ini &quot;&gt;&lt;code class=&quot;language-ini&quot; data-lang=&quot;ini&quot;&gt;# &amp;#x2F;etc&amp;#x2F;ssh&amp;#x2F;sshd_config

AllowUsers peter.home peter@192.168.2.*
AllowUsers peter@localhost peter@127.0.0.*

# ========== 全局安全策略 ==========
Port 22
Protocol 2
# 默认仅允许密钥登录（公网策略）
PasswordAuthentication no
PubkeyAuthentication yes
# 禁用不安全的认证方式
ChallengeResponseAuthentication no
KbdInteractiveAuthentication no
# 禁用 root 登录
PermitRootLogin no

# ========== 内网访问：允许密码登录 ==========
# 方案 A：基于服务器本地网卡地址
Match LocalAddress 192.168.* 10.* 172.16.* 172.17.*
    PasswordAuthentication yes
# 方案 B：基于客户端源地址（二选一，不要同时使用）
Match Address 192.168.0.0&amp;#x2F;16,10.0.0.0&amp;#x2F;8,172.16.0.0&amp;#x2F;12
    PasswordAuthentication yes
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>性能分析工具</title>
        <published>2026-01-27T13:36:21+08:00</published>
        <updated>2026-01-27T13:36:21+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2026/01/性能分析工具/"/>
        <id>https://vercel.juzhong.xyz/2026/01/性能分析工具/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2026/01/性能分析工具/">&lt;h1 id=&quot;xing-neng-fen-xi-gong-ju&quot;&gt;性能分析工具&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;gprof：这是一个GNU的性能分析工具，主要用于分析程序的函数调用关系，以及每个函数的运行时间等。&lt;&#x2F;li&gt;
&lt;li&gt;Valgrind：这是一个用于内存调试、内存泄漏检测以及性能分析的开源工具集。其中，Valgrind的Callgrind工具可以收集程序运行时的函数调用信息，用于性能分析。&lt;&#x2F;li&gt;
&lt;li&gt;perf：这是Linux下的一个性能分析工具，可以收集CPU使用情况、缓存命中率、分支预测错误等多种性能数据。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;gprof&quot;&gt;gprof&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;gprof 通常作为 GNU Binutils 的一部分，在大多数 Linux 发行版中都是默认安装的。&lt;&#x2F;li&gt;
&lt;li&gt;gprof 是一个GNU项目中的性能分析工具，用于分析C和C++程序的函数调用图和每个函数的CPU使用时间。它通过测量程序执行过程中的函数调用频率和运行时间来帮助你识别出那些占用了最多运行时间的函数，从而定位可能的性能瓶颈。&lt;&#x2F;li&gt;
&lt;li&gt;使用 -pg 选项来告诉编译器包含 gprof 的分析代码&lt;&#x2F;li&gt;
&lt;li&gt;gprof 会收集运行时信息，并将这些信息写入一个名为 gmon.out 的文件&lt;&#x2F;li&gt;
&lt;li&gt;使用 gprof 工具来分析 gmon.out 文件中的数据&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;##编译代码
g++ -pg -o myprogram hello.cpp
## 执行代码,生成调用文件
.&amp;#x2F;myprogram
## 分析日志
gprof myprogram gmon.out &amp;gt; analysis.txt
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;perf&quot;&gt;perf&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;perf 工具通常已经预装在 kernel-tools 或 kernel-tools-libs 包中&lt;&#x2F;li&gt;
&lt;li&gt;使用 perf record 命令来运行你的程序，并收集性能数据：CPU 使用情况、缓存命中、分支预测错误等性能数据&lt;&#x2F;li&gt;
&lt;li&gt;使用 perf report 命令来查看收集到的性能数据报告
perf report 会展示一个交互式的文本界面，其中包含每个函数的 CPU 使用时间百分比、调用次数等信息。你可以使用箭头键来浏览不同的函数，按 Enter 键来深入查看特定函数的调用栈&lt;&#x2F;li&gt;
&lt;li&gt;perf top：实时显示当前运行的程序的热点函数。&lt;&#x2F;li&gt;
&lt;li&gt;perf annotate：显示特定函数的源代码注释，包括每个代码行的执行次数。&lt;&#x2F;li&gt;
&lt;li&gt;perf stat：显示程序的总体性能统计信息，如指令数、缓存未命中次数等。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;## 编译代码
g++ -O2 -o myprogram  hello.cpp
## 执行程序
perf record .&amp;#x2F;myprogram
## 分析结果
perf report
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;valgrind&quot;&gt;valgrind&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;Valgrind 是一个用于内存调试、内存泄漏检测以及性能分析的开源工具。它可以在程序运行时检测多种问题，如内存泄漏、未初始化的内存、使用已释放的内存等&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;## 直接执行程序 进行检查（就是执行有点慢）
valgrind --tool=memcheck .&amp;#x2F;myprogram
## 检测内存泄漏
valgrind --leak-check=full .&amp;#x2F;hello
## callgrind 工具可以用来收集程序运行时的函数调用信息，这对于性能分析非常有用。使用 callgrind 运行程序, 生成callgrind.out.&amp;lt;pid&amp;gt;文件
valgrind --tool=callgrind .&amp;#x2F;myprogram
# 使用 kcachegrind 工具来查看和分析这些数据：
kcachegrind callgrind.out.&amp;lt;pid&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;nei-cun-xie-lou-jian-ce&quot;&gt;内存泄漏检测&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;valgrind --leak-check=full .&amp;#x2F;your_program
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;用途：检测程序在运行过程中分配但未被释放的内存，帮助发现内存泄漏。&lt;&#x2F;li&gt;
&lt;li&gt;选项说明：--leak-check=full 会报告所有可能的内存泄漏，包括那些仍然可访问的。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;dui-zhan-gen-zong&quot;&gt;堆栈跟踪&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;valgrind --tool=memcheck --trace-children=yes .&amp;#x2F;your_program
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;用途：跟踪程序中函数的调用栈，可以帮助定位问题发生的源头。&lt;&#x2F;li&gt;
&lt;li&gt;选项说明：--trace-children=yes 会跟踪由 your_program 创建的子进程的函数调用。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;huan-cun-mo-ni&quot;&gt;缓存模拟&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;valgrind --tool=cachegrind --I1=32k,2,8 --D1=32k,2,8 .&amp;#x2F;your_program
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;用途：模拟 CPU 缓存的行为，以评估程序对缓存的利用率和可能的性能瓶颈。&lt;&#x2F;li&gt;
&lt;li&gt;选项说明：--I1 和 --D1 分别设置一级指令缓存和一级数据缓存的大小、关联性和替换策略。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;diao-yong-tu-fen-xi&quot;&gt;调用图分析&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;valgrind --tool=callgrind .&amp;#x2F;your_program
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;运行完毕后，可以使用 kcachegrind 或其他工具查看生成的调用图数据：&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;kcachegrind callgrind.out.&amp;lt;pid&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;用途：收集程序运行时的函数调用信息，生成调用图，用于性能分析和优化。&lt;&#x2F;li&gt;
&lt;li&gt;说明：callgrind.out.&lt;pid&gt; 是 callgrind 工具生成的数据文件，其中 &lt;pid&gt; 是运行程序的进程ID。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;shu-ju-jing-zheng-jian-ce&quot;&gt;数据竞争检测&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;valgrind --tool=drd .&amp;#x2F;your_program
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;用途：检测多线程程序中的数据竞争问题，即多个线程同时访问和修改同一内存位置而没有适当的同步。&lt;&#x2F;li&gt;
&lt;li&gt;说明：drd 工具可以帮助发现多线程编程中的潜在问题。&lt;&#x2F;li&gt;
&lt;li&gt;这些只是 valgrind 提供的一些常用工具和选项的示例。valgrind 的功能非常强大，还包含其他工具，并且每个工具都有许多选项可以调整。为了充分利用 valgrind，建议查阅其官方文档或手册页（使用 man valgrind 命令）以获取更详细的信息和用法示例。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>qemu启动pve qcow2虚拟机镜像排查</title>
        <published>2026-01-25T13:28:12+08:00</published>
        <updated>2026-01-25T13:28:12+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2026/01/qemu启动pve qcow2虚拟机镜像排查/"/>
        <id>https://vercel.juzhong.xyz/2026/01/qemu启动pve qcow2虚拟机镜像排查/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2026/01/qemu启动pve qcow2虚拟机镜像排查/">&lt;h1 id=&quot;xiu-fu-qcow2wen-jian-mu-lu&quot;&gt;修复qcow2文件目录&lt;&#x2F;h1&gt;
&lt;p&gt;最后发现时rootfs中缺少了 &#x2F;dev 和 &#x2F;sys 两个目录，导致initrd中切换到systemd时缺少挂载点后panic了&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;qemu-system-x86_64 --enable-kvm -smp 2 -m 4096  -hda vm-7044.qcow2 -snapshot -serial stdio
modprobe nbd
sudo modprobe nbd max_part=8
lsblk
qemu-nbd --help
qemu-nbd -c &amp;#x2F;dev&amp;#x2F;nbd0 vm-7044.qcow2
mkdir vm-7044 &amp;amp;&amp;amp; cd vm-7044&amp;#x2F;
mkdir part{1,5}
mount &amp;#x2F;dev&amp;#x2F;nbd0p1 part1&amp;#x2F;
mount &amp;#x2F;dev&amp;#x2F;nbd0p5 part5
cd part5&amp;#x2F;boot&amp;#x2F;
file initrd.img
mkdir initrd &amp;amp;&amp;amp; cd initrd&amp;#x2F;
cpio -idmv &amp;lt; ..&amp;#x2F;initrd.img-5.15.0-139-generic
qemu-system-x86_64 -smp 2 -m 4096 -kernel vmlinuz-5.15.0-139-generic -initrd initrd.img-5.15.0-139-generic  -append &amp;quot;console=ttyS0&amp;quot;
cp initrd.img ..&amp;#x2F;..&amp;#x2F;
cp vmlinuz ..&amp;#x2F;..&amp;#x2F;
umount part1
umount part5
qemu-nbd -d &amp;#x2F;dev&amp;#x2F;nbd0
qemu-system-x86_64 --enable-kvm -smp 2 -m 4096 -kernel vmlinuz -initrd initrd.img  -append &amp;quot;console=ttyS0&amp;quot;
qemu-system-x86_64 --enable-kvm -smp 2 -m 4096  -hda ..&amp;#x2F;vm-7044.qcow2
qemu-system-x86_64 --enable-kvm -smp 2 -m 4096 -kernel vmlinuz -initrd initrd.img  -append &amp;quot;console=ttyS0&amp;quot; -hda ..&amp;#x2F;vm-7044.qcow2
qemu-system-x86_64 --enable-kvm -smp 2 -m 4096 -kernel vmlinuz -initrd initrd.img  -append &amp;quot;console=ttyS0 root=&amp;#x2F;dev&amp;#x2F;sda5&amp;quot; -hda ..&amp;#x2F;vm-7044.qcow2

# 最后发现qcow2中的文件系统缺少&amp;#x2F;dev 和 &amp;#x2F;sys 两个目录（导致init启动时没有devfs&amp;#x2F;tmpfs的挂载点）
qemu-system-x86_64 --enable-kvm -smp 2 -m 4096 -hda vm-7044.qcow2
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;qemuxu-ni-ji-qi-dong-hou-ru-he-qie-huan-tty&quot;&gt;qemu虚拟机启动后如何切换tty&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;tty1中的启动程序没有完全成功，导致卡死在启动过程，且没有shell供用户输入&lt;&#x2F;li&gt;
&lt;li&gt;qemu GUI中使用monitor0, 可以发送命令,切换其他tty登录&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;(qemu) sendkey ctrl+alt+f3

# 登录系统后， 修改grub
sudo nano &amp;#x2F;etc&amp;#x2F;defautl&amp;#x2F;grub
# 注释掉hide和选项
# GRUB_TIMEOUT_STYLE=hide
GRUB_CMDLINE_LINUX_DEFAULT=&amp;#x27;loglevel=7&amp;#x27;
GRUB_CMDLINE_LINUX=&amp;quot;console=tty0 console=ttyS0,115200n8 earlyprintk=ttyS0,115200 systemd.show_status=1&amp;quot;

sudo update-grub
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;grub-shellchang-yong-ming-ling&quot;&gt;grub shell常用命令&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;ls	列出设备、分区或目录内容	ls, ls (hd0,1)&#x2F;boot&lt;&#x2F;li&gt;
&lt;li&gt;set	查看或设置环境变量	set root=(hd0,gpt2)&lt;&#x2F;li&gt;
&lt;li&gt;linux	加载内核文件	linux &#x2F;vmlinuz root=&#x2F;dev&#x2F;sda5&lt;&#x2F;li&gt;
&lt;li&gt;initrd	加载初始化 RAM 磁盘	initrd &#x2F;initrd.img&lt;&#x2F;li&gt;
&lt;li&gt;boot	启动已经加载好的内核	boot&lt;&#x2F;li&gt;
&lt;li&gt;insmod	加载动态模块（如 normal, ext2）	insmod normal&lt;&#x2F;li&gt;
&lt;li&gt;cat	查看文件内容（常用于检查 grub.cfg）	cat (hd0,1)&#x2F;etc&#x2F;default&#x2F;grub&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;grub&amp;gt; configfile (hd0,msdos1)&amp;#x2F;boot&amp;#x2F;grub&amp;#x2F;grub.cfg
# 或尝试使用 search 命令自动查找
grub&amp;gt; search --file --set=root &amp;#x2F;boot&amp;#x2F;grub&amp;#x2F;grub.cfg
grub&amp;gt; configfile &amp;#x2F;boot&amp;#x2F;grub&amp;#x2F;grub.cfg

grub&amp;gt; ls (hd0,msdos5)&amp;#x2F;
# 如果显示了 vmlinuz, initrd.img 等文件，说明找对了

# 第二步：设置根分区
# 查看当前 root &amp;#x2F; prefix
grub&amp;gt; set
grub&amp;gt; set root=(hd0,msdos5)
grub&amp;gt; insmod normal
grub&amp;gt; insmod linux
grub&amp;gt; insmod ext2     # ext2&amp;#x2F;ext4 都是这个

# 第三步：加载内核 (关键步骤)
# 你需要指定内核文件，并手动告诉它根目录在哪里。在这里加上 nomodeset 来解决你之前的卡死问题。
# 注意：利用 Tab 键补全文件名，因为内核版本号很长
grub&amp;gt; linux &amp;#x2F;boot&amp;#x2F;vmlinuz-xxx-generic root=&amp;#x2F;dev&amp;#x2F;sda5 nomodeset

# 第四步：加载 initrd
grub&amp;gt; initrd &amp;#x2F;boot&amp;#x2F;initrd.img-xxx-generic
grub&amp;gt; boot
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>linux 键盘按键频率统计</title>
        <published>2026-01-05T12:05:46+08:00</published>
        <updated>2026-01-05T12:05:46+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2026/01/linux 键盘按键频率统计/"/>
        <id>https://vercel.juzhong.xyz/2026/01/linux 键盘按键频率统计/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2026/01/linux 键盘按键频率统计/">&lt;h1 id=&quot;an-jian-pin-lu-key-frequency&quot;&gt;按键频率（key frequency）&lt;&#x2F;h1&gt;
&lt;p&gt;统计 Linux 下自己实际敲击的 按键频率（key frequency），从而为 键盘布局优化（如重映射高频键到更符合人体工学的位置）提供数据支持&lt;&#x2F;p&gt;
&lt;h2 id=&quot;chang-yong-de-jian-kong-an-jian-de-gong-ju&quot;&gt;常用的监控按键的工具&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;wev(wayland)
&lt;ul&gt;
&lt;li&gt;通过wayland(libinput)读取eventX(evdev)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;libinput list-devices
&lt;ul&gt;
&lt;li&gt;apt install libinput-tools&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;xev(x11)
&lt;ul&gt;
&lt;li&gt;通过x11(xkb)读取eventX&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;xinput(x11)&lt;&#x2F;li&gt;
&lt;li&gt;evtest
&lt;ul&gt;
&lt;li&gt;apt install evtest&lt;&#x2F;li&gt;
&lt;li&gt;直接读取eventX&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;showkey
&lt;ul&gt;
&lt;li&gt;通过内核tty系统读物eventX&lt;&#x2F;li&gt;
&lt;li&gt;只能在 VT（Ctrl+Alt+Fx）&lt;&#x2F;li&gt;
&lt;li&gt;看的是 内核 tty keycode &#x2F; scancode&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;uinput
&lt;ul&gt;
&lt;li&gt;创建虚拟输入设备&#x2F;dev&#x2F;intput&#x2F;eventY&lt;&#x2F;li&gt;
&lt;li&gt;&#x2F;dev&#x2F;uinput（虚拟设备注入点）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&#x2F;dev&#x2F;input&#x2F;eventX
&lt;ul&gt;
&lt;li&gt;内核输入子系统 (evdev)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;键盘映射系统级修改：修改内核键码映射（setkeycodes）或控制台映射（loadkeys）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;shi-yong-evtest-zi-ding-yi-jiao-ben-tui-jian-an-quan-di-ceng-bu-yi-lai-gui&quot;&gt;使用 evtest + 自定义脚本（推荐，安全、底层、不依赖 GUI）&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;所有数据仅保存在 ~&#x2F;.local&#x2F;share&#x2F;keyfreq&#x2F;，不记录键值内容（如不区分 a&#x2F;A，只记录 KEY_A）。&lt;&#x2F;li&gt;
&lt;li&gt;无法恢复原始文本，仅统计物理按键频率，不构成键盘记录器（keylogger）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt install evtest  # Debian&amp;#x2F;Ubuntu
sudo evtest

sudo apt install python3-pip
sudo usermod -aG input $USER
# 重新登录使组生效
pip3 install --user evdev
# 目录结构
# ~&amp;#x2F;.local&amp;#x2F;bin&amp;#x2F;keyfreqd
# ~&amp;#x2F;.config&amp;#x2F;systemd&amp;#x2F;user&amp;#x2F;keyfreqd.service
# ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;keyfreq&amp;#x2F;  # 日志目录
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;python&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;#!&amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;env python3
import sys
import struct
import os
from collections import Counter

# 从 evtest 或 &amp;#x2F;usr&amp;#x2F;include&amp;#x2F;linux&amp;#x2F;input-event-codes.h 获取 keycode 映射
KEY_NAMES = {
    1: &amp;#x27;ESC&amp;#x27;, 2: &amp;#x27;1&amp;#x27;, 3: &amp;#x27;2&amp;#x27;, 4: &amp;#x27;3&amp;#x27;, 5: &amp;#x27;4&amp;#x27;, 6: &amp;#x27;5&amp;#x27;, 7: &amp;#x27;6&amp;#x27;, 8: &amp;#x27;7&amp;#x27;, 9: &amp;#x27;8&amp;#x27;, 10: &amp;#x27;9&amp;#x27;, 11: &amp;#x27;0&amp;#x27;,
    12: &amp;#x27;MINUS&amp;#x27;, 13: &amp;#x27;EQUAL&amp;#x27;, 14: &amp;#x27;BACKSPACE&amp;#x27;,
    15: &amp;#x27;TAB&amp;#x27;, 16: &amp;#x27;Q&amp;#x27;, 17: &amp;#x27;W&amp;#x27;, 18: &amp;#x27;E&amp;#x27;, 19: &amp;#x27;R&amp;#x27;, 20: &amp;#x27;T&amp;#x27;, 21: &amp;#x27;Y&amp;#x27;, 22: &amp;#x27;U&amp;#x27;, 23: &amp;#x27;I&amp;#x27;, 24: &amp;#x27;O&amp;#x27;, 25: &amp;#x27;P&amp;#x27;,
    26: &amp;#x27;LEFTBRACE&amp;#x27;, 27: &amp;#x27;RIGHTBRACE&amp;#x27;, 28: &amp;#x27;ENTER&amp;#x27;,
    29: &amp;#x27;LEFTCTRL&amp;#x27;, 30: &amp;#x27;A&amp;#x27;, 31: &amp;#x27;S&amp;#x27;, 32: &amp;#x27;D&amp;#x27;, 33: &amp;#x27;F&amp;#x27;, 34: &amp;#x27;G&amp;#x27;, 35: &amp;#x27;H&amp;#x27;, 36: &amp;#x27;J&amp;#x27;, 37: &amp;#x27;K&amp;#x27;, 38: &amp;#x27;L&amp;#x27;,
    39: &amp;#x27;SEMICOLON&amp;#x27;, 40: &amp;#x27;APOSTROPHE&amp;#x27;, 41: &amp;#x27;GRAVE&amp;#x27;,
    42: &amp;#x27;LEFTSHIFT&amp;#x27;, 43: &amp;#x27;BACKSLASH&amp;#x27;, 44: &amp;#x27;Z&amp;#x27;, 45: &amp;#x27;X&amp;#x27;, 46: &amp;#x27;C&amp;#x27;, 47: &amp;#x27;V&amp;#x27;, 48: &amp;#x27;B&amp;#x27;, 49: &amp;#x27;N&amp;#x27;, 50: &amp;#x27;M&amp;#x27;,
    51: &amp;#x27;COMMA&amp;#x27;, 52: &amp;#x27;DOT&amp;#x27;, 53: &amp;#x27;SLASH&amp;#x27;, 54: &amp;#x27;RIGHTSHIFT&amp;#x27;,
    56: &amp;#x27;LEFTALT&amp;#x27;, 57: &amp;#x27;SPACE&amp;#x27;, 58: &amp;#x27;CAPSLOCK&amp;#x27;,
    97: &amp;#x27;RIGHTCTRL&amp;#x27;, 100: &amp;#x27;RIGHTALT&amp;#x27;,
    # 方向键等
    103: &amp;#x27;UP&amp;#x27;, 105: &amp;#x27;LEFT&amp;#x27;, 106: &amp;#x27;RIGHT&amp;#x27;, 108: &amp;#x27;DOWN&amp;#x27;,
}

def main(device_path):
    counter = Counter()
    with open(device_path, &amp;#x27;rb&amp;#x27;) as f:
        while True:
            data = f.read(24)  # input_event 结构体大小
            if not data:
                break
            tv_sec, tv_usec, type_, code, value = struct.unpack(&amp;#x27;llHHi&amp;#x27;, data)
            if type_ == 1 and value == 1:  # EV_KEY 且按下（非释放）
                key_name = KEY_NAMES.get(code, f&amp;#x27;KEY_{code}&amp;#x27;)
                counter[key_name] += 1
                print(f&amp;quot;\r{len(counter)} keys recorded...&amp;quot;, end=&amp;#x27;&amp;#x27;, flush=True)
    return counter

if __name__ == &amp;#x27;__main__&amp;#x27;:
    if len(sys.argv) != 2:
        print(&amp;quot;Usage: sudo python3 keyfreq.py &amp;#x2F;dev&amp;#x2F;input&amp;#x2F;eventX&amp;quot;)
        sys.exit(1)
    device = sys.argv[1]
    print(f&amp;quot;Recording key presses from {device} (Press Ctrl+C to stop)...&amp;quot;)
    try:
        counter = main(device)
    except KeyboardInterrupt:
        print(&amp;quot;\nStopped.&amp;quot;)
    # 输出排序结果
    print(&amp;quot;\n=== Key Frequency ===&amp;quot;)
    for key, count in counter.most_common():
        print(f&amp;quot;{key:12} : {count}&amp;quot;)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;python&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;#!&amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;env python3
# ~&amp;#x2F;.local&amp;#x2F;bin&amp;#x2F;keyfreqd

import os
import json
import time
from datetime import datetime, date
from collections import defaultdict
from pathlib import Path

from evdev import InputDevice, categorize, ecodes, list_devices

# 配置
LOG_DIR = Path.home() &amp;#x2F; &amp;quot;.local&amp;#x2F;share&amp;#x2F;keyfreq&amp;quot;
LOG_DIR.mkdir(parents=True, exist_ok=True)

# 过滤出键盘设备（基于名称或 capability）
def is_keyboard(dev):
    if not dev.capabilities().get(ecodes.EV_KEY):
        return False
    name = dev.name.lower()
    # 常见键盘关键词
    keywords = [&amp;#x27;keyboard&amp;#x27;, &amp;#x27;keypad&amp;#x27;, &amp;#x27;at keyboard&amp;#x27;, &amp;#x27;input device&amp;#x27;]
    return any(kw in name for kw in keywords) or &amp;#x27;kbd&amp;#x27; in name

def main():
    # 获取所有输入设备
    devices = [InputDevice(fn) for fn in list_devices()]
    keyboards = [dev for dev in devices if is_keyboard(dev)]

    if not keyboards:
        print(&amp;quot;No keyboard devices found. Check permissions (add user to &amp;#x27;input&amp;#x27; group).&amp;quot;, file=os.sys.stderr)
        return

    print(f&amp;quot;Monitoring {len(keyboards)} keyboard(s): {[d.name for d in keyboards]}&amp;quot;)

    # 当天的计数器
    today = date.today()
    counter = defaultdict(int)

    try:
        while True:
            # 检查日期是否变更
            new_day = date.today()
            if new_day != today:
                # 保存旧数据
                save_day_log(today, counter)
                # 重置
                today = new_day
                counter = defaultdict(int)

            # 读取事件（非阻塞轮询）
            for dev in keyboards:
                try:
                    for event in dev.read():
                        if event.type == ecodes.EV_KEY:
                            key_event = categorize(event)
                            if hasattr(key_event, &amp;#x27;keycode&amp;#x27;):
                                # 只记录按下（避免重复计数）
                                if event.value == 1:  # key press
                                    counter[key_event.keycode] += 1
                except BlockingIOError:
                    continue  # 无事件可读
                except OSError as e:
                    if e.errno == 19:  # 设备被拔出
                        keyboards = [d for d in keyboards if d != dev]
                        print(f&amp;quot;Device removed: {dev.name}&amp;quot;, file=os.sys.stderr)
                    else:
                        raise

            time.sleep(0.01)  # 减少 CPU 占用

    except KeyboardInterrupt:
        save_day_log(today, counter)
        print(&amp;quot;\nExiting and saving final log.&amp;quot;)

def save_day_log(day: date, counter: dict):
    if not counter:
        return
    log_file = LOG_DIR &amp;#x2F; f&amp;quot;{day.isoformat()}.json&amp;quot;
    # 合并已有数据（以防重复运行）
    if log_file.exists():
        with open(log_file, &amp;#x27;r&amp;#x27;) as f:
            existing = json.load(f)
        for k, v in counter.items():
            existing[k] = existing.get(k, 0) + v
        counter = existing
    with open(log_file, &amp;#x27;w&amp;#x27;) as f:
        json.dump(dict(counter), f, indent=2, sort_keys=True)
    print(f&amp;quot;Saved {sum(counter.values())} keystrokes to {log_file}&amp;quot;)

if __name__ == &amp;quot;__main__&amp;quot;:
    main()
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;systemd 用户服务&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;cat ~&amp;#x2F;.config&amp;#x2F;systemd&amp;#x2F;user&amp;#x2F;keyfreqd.service
systemctl --user daemon-reload
systemctl --user enable --now keyfreqd.service
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;服务配置&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;ini&quot; class=&quot;language-ini &quot;&gt;&lt;code class=&quot;language-ini&quot; data-lang=&quot;ini&quot;&gt;[Unit]
Description=Keyboard Key Frequency Logger
After=graphical-session.target

[Service]
ExecStart=%h&amp;#x2F;.local&amp;#x2F;bin&amp;#x2F;keyfreqd
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=default.target
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;fen-xi-jiao-ben&quot;&gt;分析脚本&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;#!&amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;env python3
# ~&amp;#x2F;.local&amp;#x2F;bin&amp;#x2F;keyfreq-analyze

import json
import sys
from pathlib import Path
from collections import defaultdict

LOG_DIR = Path.home() &amp;#x2F; &amp;quot;.local&amp;#x2F;share&amp;#x2F;keyfreq&amp;quot;

def main(days=7):
    total = defaultdict(int)
    count = 0
    for log in sorted(LOG_DIR.glob(&amp;quot;*.json&amp;quot;))[-days:]:
        with open(log) as f:
            data = json.load(f)
            for k, v in data.items():
                total[k] += v
        count += 1

    if not total:
        print(&amp;quot;No data found.&amp;quot;)
        return

    print(f&amp;quot;Top 30 keys in last {count} day(s):&amp;quot;)
    print(&amp;quot;-&amp;quot; * 40)
    for key, freq in sorted(total.items(), key=lambda x: -x[1])[:30]:
        print(f&amp;quot;{key:15} : {freq:&amp;gt;8}&amp;quot;)

if __name__ == &amp;quot;__main__&amp;quot;:
    days = int(sys.argv[1]) if len(sys.argv) &amp;gt; 1 else 7
    main(days)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Super(Win)键失效无法开启gnome搜索功能</title>
        <published>2026-01-01T23:08:03+08:00</published>
        <updated>2026-01-01T23:08:03+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2026/01/Super(Win)键失效无法开启gnome搜索功能/"/>
        <id>https://vercel.juzhong.xyz/2026/01/Super(Win)键失效无法开启gnome搜索功能/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2026/01/Super(Win)键失效无法开启gnome搜索功能/">&lt;h1 id=&quot;zhuo-mian-huan-jing-huo-chuang-kou-guan-li-qi-wei-zheng-que-pei-zhi-super-jian-xing-wei&quot;&gt;桌面环境或窗口管理器未正确配置 Super 键行为&lt;&#x2F;h1&gt;
&lt;p&gt;Super 键默认绑定到“显示活动概览”（Activities Overview），其中包含搜索框。
若该绑定被修改、禁用，或 GNOME Shell 未完全加载，Super 键可能无响应。
可通过以下命令检查绑定：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;gsettings get org.gnome.mutter overlay-key
gsettings reset org.gnome.mutter overlay-key
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;shu-ru-fa-huo-jian-pan-bu-ju-gan-rao&quot;&gt;输入法或键盘布局干扰&lt;&#x2F;h2&gt;
&lt;p&gt;某些输入法框架（如 fcitx5、ibus）在特定状态下会“捕获”Super 键。
某些非标准键盘布局（如自定义 xkb 配置）可能重映射了 Super 键。
可通过以下命令临时测试原始键码：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;echo $XDG_SESSION_TYPE
xev  # 在 X11 下
xev | grep -A2 -B2 keycode
# 或
sudo evtest  # 在 Wayland 下（需 root）
sudo apt install wev
wev
# 在 TTY 中用 
showkey -s # 再次验证
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;按下 Super 键，观察是否输出 Super_L 或 Super_R。如果没有，说明系统未识别该键。&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>libvirt 优化windows11虚拟机配置</title>
        <published>2025-12-30T11:45:03+08:00</published>
        <updated>2025-12-30T11:45:03+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/12/libvirt 优化windows11虚拟机配置/"/>
        <id>https://vercel.juzhong.xyz/2025/12/libvirt 优化windows11虚拟机配置/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/12/libvirt 优化windows11虚拟机配置/">&lt;h1 id=&quot;xu-ni-ji-you-hua&quot;&gt;虚拟机优化&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;使用spice协议, 优化本地访问&lt;&#x2F;li&gt;
&lt;li&gt;配置ballooning, 优化内存使用
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;fedorapeople.org&#x2F;groups&#x2F;virt&#x2F;virtio-win&#x2F;direct-downloads&#x2F;stable-virtio&#x2F;virtio-win.iso&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;安装 SPICE Guest Tools, 优化鼠标
&lt;ul&gt;
&lt;li&gt;spice-vdagent：实现鼠标无缝、剪贴板共享、分辨率自动调整&lt;&#x2F;li&gt;
&lt;li&gt;自动禁用 Guest 内鼠标指针（避免双鼠标）&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;www.spice-space.org&#x2F;download.html?spm=a2ty_o01.29997173.0.0.54145171JWAMq5&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>linux 键盘映射xremap</title>
        <published>2025-12-25T17:17:27+08:00</published>
        <updated>2025-12-25T17:17:27+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/12/linux 键盘映射xremap/"/>
        <id>https://vercel.juzhong.xyz/2025/12/linux 键盘映射xremap/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/12/linux 键盘映射xremap/">&lt;h1 id=&quot;xremap&quot;&gt;xremap&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;xremap is a key remapper for Linux. Unlike xmodmap, it supports app-specific remapping and Wayland.&lt;&#x2F;li&gt;
&lt;li&gt;xremap 和 evdev 都是 Linux 下的键盘重映射工具，主要区别在于 xremap 专注于应用层，提供更灵活的组合键和上下文感知（如窗口特定、虚拟修饰键）功能，而 evdev（底层驱动）则更侧重硬件&#x2F;驱动层面的低级事件捕获与重映射，xremap 可以基于 evdev 实现高级功能，两者常结合使用，xremap 更易用，evdev 性能更低延迟。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;cargo install xremap --features gnome   # GNOME Wayland
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;cha-kan-dang-qian-uinput-she-bei-xu-yao-root&quot;&gt;查看当前 uinput 设备（需要 root）&lt;&#x2F;h2&gt;
&lt;p&gt;xremap 使用 &#x2F;dev&#x2F;uinput 创建虚拟输入设备。异常退出可能导致设备未释放。&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo cat &amp;#x2F;sys&amp;#x2F;class&amp;#x2F;misc&amp;#x2F;uinput&amp;#x2F;dev

# 查看 uinput 使用者（粗略判断是否被占用）
lsof &amp;#x2F;dev&amp;#x2F;uinput
# 或
fuser &amp;#x2F;dev&amp;#x2F;uinput
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;running-xremap-without-sudo&quot;&gt;Running xremap without sudo&lt;&#x2F;h2&gt;
&lt;p&gt;To do so, your normal user should be able to use evdev and uinput without sudo. In Ubuntu, this can be configured by running the following commands and rebooting your machine.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo gpasswd -a YOUR_USER input
echo &amp;#x27;KERNEL==&amp;quot;uinput&amp;quot;, GROUP=&amp;quot;input&amp;quot;, TAG+=&amp;quot;uaccess&amp;quot;&amp;#x27; | sudo tee &amp;#x2F;etc&amp;#x2F;udev&amp;#x2F;rules.d&amp;#x2F;input.rules

lsmod | grep uinput
# If it shows up empty:
echo uinput | sudo tee &amp;#x2F;etc&amp;#x2F;modules-load.d&amp;#x2F;uinput.conf

Reboot the machine afterwards or try:

sudo modprobe uinput
sudo udevadm control --reload-rules &amp;amp;&amp;amp; sudo udevadm trigger
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;gnome-wayland&quot;&gt;GNOME Wayland&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Install xremap&#x27;s GNOME Shell extension from this link, switching OFF to ON.&lt;&#x2F;li&gt;
&lt;li&gt;If you use sudo to run xremap, also click here.&lt;&#x2F;li&gt;
&lt;li&gt;Update &#x2F;usr&#x2F;share&#x2F;dbus-1&#x2F;session.conf as follows, and reboot your machine.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;xml&quot; class=&quot;language-xml &quot;&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;   &amp;lt;policy context=&amp;quot;default&amp;quot;&amp;gt;
+    &amp;lt;allow user=&amp;quot;root&amp;quot;&amp;#x2F;&amp;gt;
     &amp;lt;!-- Allow everything to be sent --&amp;gt;
     &amp;lt;allow send_destination=&amp;quot;*&amp;quot; eavesdrop=&amp;quot;true&amp;quot;&amp;#x2F;&amp;gt;
     &amp;lt;!-- Allow everything to be received --&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;example&quot;&gt;example&lt;&#x2F;h2&gt;
&lt;p&gt;This allows a key to be held indefinitely without triggering its held state, which is ideal for keys that also serve as modifiers. For example, you can make the Space key act as Shift when held and combined with another key, but still type a regular Space when tapped.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;yml&quot; class=&quot;language-yml &quot;&gt;&lt;code class=&quot;language-yml&quot; data-lang=&quot;yml&quot;&gt;modmap:
  - name: Space as Shift
    remap:
      Space:
        held: Shift_L
        alone: Space
        free_hold: true # Optional, defaults to false.
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;wen-ti-pai-cha&quot;&gt;问题排查&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 普通用户执行要求
sudo usermod -aG input $USER

# 创建 udev 规则： 新建文件 &amp;#x2F;etc&amp;#x2F;udev&amp;#x2F;rules.d&amp;#x2F;99-input.rules，内容如下：
KERNEL==&amp;quot;uinput&amp;quot;, GROUP=&amp;quot;input&amp;quot;, MODE=&amp;quot;0660&amp;quot;

sudo udevadm control --reload-rules &amp;amp;&amp;amp; sudo udevadm trigger

# 查找你的键盘设备 寻找 Name=&amp;quot;...Keyboard...&amp;quot; 的条目，记下它的 Handlers（例如 event3）
cat &amp;#x2F;proc&amp;#x2F;bus&amp;#x2F;input&amp;#x2F;devices

&amp;#x2F;home&amp;#x2F;peter&amp;#x2F;.cargo&amp;#x2F;bin&amp;#x2F;xremap &amp;#x2F;home&amp;#x2F;peter&amp;#x2F;project&amp;#x2F;tools&amp;#x2F;dotfiles&amp;#x2F;keymap.yml --device &amp;#x2F;dev&amp;#x2F;input&amp;#x2F;event3
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;cuo-wu-ju-li&quot;&gt;错误举例&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;如果 xremap 以错误权限启动并崩溃，它可能已经打开了虚拟设备但没有正常关闭，导致 GNOME 认为有一个“死键”一直被按下。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;xremap-hui-chuang-jian-yi-ge-ming-wei-xremap-de-xu-ni-jian-pan-ru-guo-cheng-xu-beng-kui-liao-dan-she-bei-huan-zai-gnome-hui-ji-xu-chang-shi-cong-zhe-ge-jiang-shi-she-bei-du-qu-shu-ru&quot;&gt;xremap 会创建一个名为 xremap 的虚拟键盘。如果程序崩溃了但设备还在，GNOME 会继续尝试从这个“僵尸”设备读取输入&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;lsinput
# 或者使用更通用的命令
grep -E &amp;#x27;Name|Handlers&amp;#x27; &amp;#x2F;proc&amp;#x2F;bus&amp;#x2F;input&amp;#x2F;devices
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;寻找关键字： 在输出中找名称包含 &quot;xremap&quot; 的设备。&lt;&#x2F;li&gt;
&lt;li&gt;判断异常： 如果 xremap 进程已经杀掉了，但 xremap 虚拟设备依然出现在列表中，说明设备未正常卸载，这通常就是导致 GNOME 异常的元凶。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;shi-yong-libinput-jian-kong-shi-shi-shi-jian&quot;&gt;使用 libinput 监控实时事件&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;你可以实时观察到底是哪个设备在“发疯”（比如不停发送 Ctrl 信号）。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo libinput debug-events
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;观察输出： * 如果你没有按键，但屏幕滚动显示 KEY_LEFTCTRL 或 KEY_RIGHTALT 的 pressed 事件，说明存在“死键”。&lt;&#x2F;li&gt;
&lt;li&gt;看输出条目左侧的设备名称。如果是来自 xremap 设备，说明是驱动层模拟出的问题；如果是来自你的物理键盘，说明物理设备可能被锁死在了按下状态&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;pai-cha-she-bei-suo-si-eviocgrab&quot;&gt;排查设备“锁死”（EVIOCGRAB）&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;xremap 运行时会“抓取”物理键盘。如果它崩溃时没有释放抓取权限，物理键盘的信号就无法到达 GNOME，导致你感觉键盘“失灵”。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;ps aux | grep xremap
sudo killall -9 xremap
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;通常进程结束后，内核会自动释放设备抓取。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;kuai-su-hui-fu-shou-duan&quot;&gt;快速恢复手段&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;如果你正处于“环境异常”（键盘乱跳或没反应）中，尝试以下组合拳：&lt;&#x2F;li&gt;
&lt;li&gt;拔插键盘： 如果是外接键盘，拔掉重插可以强制重置内核对该设备的输入状态。&lt;&#x2F;li&gt;
&lt;li&gt;强制销毁虚拟设备： 如果 xremap 已经退出但设备还在，尝试移除 uinput 模块（慎用，仅在没反应时尝试）：&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo modprobe -r uinput &amp;amp;&amp;amp; sudo modprobe uinput
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;重启 GNOME Shell：&lt;&#x2F;li&gt;
&lt;li&gt;X11 环境： 按 Alt + F2，输入 r 然后回车。&lt;&#x2F;li&gt;
&lt;li&gt;Wayland 环境： 只能通过登出（Log out）并重新登录来重置输入状态。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;zhong-ji-shou-duan-zhong-zhi-uinput-zi-xi-tong&quot;&gt;终极手段：重置 uinput 子系统&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 卸载并重载 uinput 模块（需 root，会断开所有虚拟输入设备）
sudo rmmod uinput
sudo modprobe uinput
# 此操作会使所有依赖 uinput 的程序（如 xremap、keyd、interception-tools）失效，需重启它们
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;qiang-zhi-shi-fang-suo-you-qia-zhu-de-xiu-shi-jian-zui-chang-yong-zui-you-xiao&quot;&gt;强制释放所有“卡住”的修饰键（最常用、最有效）&lt;&#x2F;h2&gt;
&lt;p&gt;在 GNOME&#x2F;X11 下，模拟释放所有修饰键即可快速恢复：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 方法 1：使用 xdotool（推荐）
xdotool keyup Shift_L Shift_R Control_L Control_R Alt_L Alt_R Super_L Super_R

# 方法 2：使用 xte（来自 xautomation 包）
xte &amp;#x27;keyup Shift_L&amp;#x27; &amp;#x27;keyup Control_L&amp;#x27; &amp;#x27;keyup Alt_L&amp;#x27; &amp;#x27;keyup Super_L&amp;#x27;

# 方法 3：重启输入法&amp;#x2F;IM 框架（有时 IBus&amp;#x2F;Rime 会缓存按键状态）
ibus restart
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;zai-gnome-wayland-hui-hua-zhong-xdotool-ke-neng-shi-xiao-yin-fei-x11-hou-duan-ci-shi&quot;&gt;在 GNOME Wayland 会话中，xdotool 可能失效（因非 X11 后端），此时：&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;Ctrl+Alt+F3 → 登录 → Ctrl+Alt+F1（或 F2）回到 GNOME
# 这会强制重置输入栈。

# 重启 GNOME Shell（不注销）：
# 在 GNOME 中按 Alt+F2，输入：
r
# 或终端执行
busctl --user call org.gnome.Shell &amp;#x2F;org&amp;#x2F;gnome&amp;#x2F;Shell org.gnome.Shell Eval s &amp;#x27;global.reexec_self()&amp;#x27;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;shi-jian-jian-ting&quot;&gt;事件监听&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt install evtest
# 列出所有 X 输入设备
xinput list

# 查找类似 “xremap virtual keyboard” 的设备
xinput list --short | grep -i remap

# 若找到，检查其按键状态（需 evtest）
sudo evtest
# → 选择对应设备编号，观察是否有持续的 KEY_XXX (code xxx) DOWN 事件

# xremap 默认创建一个 uinput virtual device，名字可能为 xremap virtual keyboard 或类似。
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;xremap-de-shi-xian-yuan-li&quot;&gt;xremap 的实现原理&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;code&gt;xremap&lt;&#x2F;code&gt; 的工作流程可以分为：&lt;strong&gt;拦截 (Grab) -&amp;gt;&lt;&#x2F;strong&gt;  &lt;strong&gt;转换 (Remap) -&amp;gt;&lt;&#x2F;strong&gt;  &lt;strong&gt;重发 (Emit)&lt;&#x2F;strong&gt; 。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;1-lan-jie-ceng-evdev-eviocgrab&quot;&gt;1. 拦截层 (evdev + EVIOCGRAB)&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;读取：&lt;&#x2F;strong&gt;  Linux 内核通过 &lt;code&gt;&#x2F;dev&#x2F;input&#x2F;event*&lt;&#x2F;code&gt; 暴露出原始的输入事件。&lt;code&gt;xremap&lt;&#x2F;code&gt; 启动后，会打开你的物理键盘设备文件。&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;独占锁：&lt;&#x2F;strong&gt;  这是关键。它会对物理键盘调用 &lt;code&gt;ioctl(fd, EVIOCGRAB, 1)&lt;&#x2F;code&gt;。这会告诉内核：“除了我，谁也不要把这个键盘的事件发给别人”。&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;结果：&lt;&#x2F;strong&gt;  此时你按下键盘，GNOME 或 X11 是接收不到任何信号的，信号全被 &lt;code&gt;xremap&lt;&#x2F;code&gt; 截获了。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;2-luo-ji-zhuan-huan-ceng-logic&quot;&gt;2. 逻辑转换层 (Logic)&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;xremap&lt;&#x2F;code&gt; 内部维护一个状态机。当你按下 $Alt\_R$ 时，它不会立即动作，而是根据你的配置文件（如 &lt;code&gt;application&lt;&#x2F;code&gt; 过滤）检查当前活跃窗口。&lt;&#x2F;li&gt;
&lt;li&gt;在 &lt;strong&gt;Wayland&lt;&#x2F;strong&gt; 下，它通过特定的合成器协议或 GNOME 扩展获取窗口信息；在 &lt;strong&gt;X11&lt;&#x2F;strong&gt; 下，它通过 Xlib 获取 &lt;code&gt;_NET_ACTIVE_WINDOW&lt;&#x2F;code&gt;。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;3-zhong-fa-ceng-uinput&quot;&gt;3. 重发层 (uinput)&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;虚拟设备：&lt;&#x2F;strong&gt;  &lt;code&gt;xremap&lt;&#x2F;code&gt; 调用 &lt;code&gt;&#x2F;dev&#x2F;uinput&lt;&#x2F;code&gt; 模块，在系统中注册一个全新的&lt;strong&gt;虚拟键盘&lt;&#x2F;strong&gt;（通常名字就叫 &lt;code&gt;xremap&lt;&#x2F;code&gt;）。&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;转换输出：&lt;&#x2F;strong&gt;  当它拦截到 $Alt\_R$ 并判断需要映射时，它会向 &lt;code&gt;uinput&lt;&#x2F;code&gt; 设备写入 $Control\_L$ 的事件序列。&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;接收：&lt;&#x2F;strong&gt;  GNOME 看到的是来自这个“虚拟键盘”的 $Control\_L$ 信号，从而执行相应的操作&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;lei-si-gong-ju&quot;&gt;类似工具&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;github.com&#x2F;jtroo&#x2F;kanata&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;github.com&#x2F;kmonad&#x2F;kmonad&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;loadkeys-console-keymap&quot;&gt;loadkeys（console keymap）&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;这是 Linux 控制台专用 的键盘映射。&lt;&#x2F;li&gt;
&lt;li&gt;dumpkeys &amp;gt; keymap.map&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 编辑 keymap.map
sudo loadkeys keymap.map
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;直接作用在 VT&lt;&#x2F;li&gt;
&lt;li&gt;内核级&lt;&#x2F;li&gt;
&lt;li&gt;稳定&lt;&#x2F;li&gt;
&lt;li&gt;不支持复杂逻辑&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;kbd-console-setup&quot;&gt;kbd &#x2F; console-setup&lt;&#x2F;h2&gt;
&lt;p&gt;用于&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;服务器&lt;&#x2F;li&gt;
&lt;li&gt;rescue&lt;&#x2F;li&gt;
&lt;li&gt;initramfs&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo dpkg-reconfigure keyboard-configuration
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;qi-ta-lei-si-xiang-mu&quot;&gt;其他类似项目&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;项目&lt;&#x2F;th&gt;&lt;th&gt;架构&lt;&#x2F;th&gt;&lt;th&gt;Wayland&lt;&#x2F;th&gt;&lt;th&gt;特点&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;xremap&lt;&#x2F;td&gt;&lt;td&gt;evdev + uinput&lt;&#x2F;td&gt;&lt;td&gt;⚠️&lt;&#x2F;td&gt;&lt;td&gt;YAML，灵活&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;keyd&lt;&#x2F;td&gt;&lt;td&gt;evdev + uinput&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;稳定、简单&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;kmonad&lt;&#x2F;td&gt;&lt;td&gt;evdev + uinput&lt;&#x2F;td&gt;&lt;td&gt;⚠️&lt;&#x2F;td&gt;&lt;td&gt;Lisp DSL&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;interception-tools&lt;&#x2F;td&gt;&lt;td&gt;evdev&lt;&#x2F;td&gt;&lt;td&gt;⚠️&lt;&#x2F;td&gt;&lt;td&gt;管道式&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;setxkbmap&lt;&#x2F;td&gt;&lt;td&gt;XKB&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;最稳&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;xmodmap&lt;&#x2F;td&gt;&lt;td&gt;X11&lt;&#x2F;td&gt;&lt;td&gt;❌&lt;&#x2F;td&gt;&lt;td&gt;已过时&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Karabiner (macOS)&lt;&#x2F;td&gt;&lt;td&gt;HID&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;架构标杆&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;ul&gt;
&lt;li&gt;路线 A：evdev + uinput（xremap 路线）
&lt;ul&gt;
&lt;li&gt;做系统级 remap&lt;&#x2F;li&gt;
&lt;li&gt;不依赖 Wayland 应用识别&lt;&#x2F;li&gt;
&lt;li&gt;能接受 input 权限&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;路线 B：XKB 层（最稳）
&lt;ul&gt;
&lt;li&gt;不抓设备&lt;&#x2F;li&gt;
&lt;li&gt;改的是 键位语义&lt;&#x2F;li&gt;
&lt;li&gt;compositor 原生支持&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;路线 C：Wayland Compositor 插件（最干净）
&lt;ul&gt;
&lt;li&gt;在 compositor 内部改键&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>dbus 工具</title>
        <published>2025-12-23T20:24:10+08:00</published>
        <updated>2025-12-23T20:24:10+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/12/dbus 工具/"/>
        <id>https://vercel.juzhong.xyz/2025/12/dbus 工具/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/12/dbus 工具/">&lt;h1 id=&quot;xue-xi-xiang-mu&quot;&gt;学习项目&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;zbus https:&#x2F;&#x2F;github.com&#x2F;z-galaxy&#x2F;zbus&lt;&#x2F;li&gt;
&lt;li&gt;pydbus https:&#x2F;&#x2F;github.com&#x2F;LEW21&#x2F;pydbus&lt;&#x2F;li&gt;
&lt;li&gt;python-dbus-next https:&#x2F;&#x2F;github.com&#x2F;altdesktop&#x2F;python-dbus-next&lt;&#x2F;li&gt;
&lt;li&gt;pystemd https:&#x2F;&#x2F;github.com&#x2F;systemd&#x2F;pystemd&lt;&#x2F;li&gt;
&lt;li&gt;bluez-test https:&#x2F;&#x2F;github.com&#x2F;bluez&#x2F;bluez&#x2F;tree&#x2F;master&#x2F;test&lt;&#x2F;li&gt;
&lt;li&gt;Ulauncher https:&#x2F;&#x2F;github.com&#x2F;Ulauncher&#x2F;Ulauncher&lt;&#x2F;li&gt;
&lt;li&gt;busctl https:&#x2F;&#x2F;github.com&#x2F;systemd&#x2F;systemd&#x2F;tree&#x2F;main&#x2F;src&#x2F;busctl&lt;&#x2F;li&gt;
&lt;li&gt;xdg-desktop-portal https:&#x2F;&#x2F;github.com&#x2F;flatpak&#x2F;xdg-desktop-portal&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;github-shi-zhan-xiang-mu-ke-zhi-jie-yun-xing-gong-xian&quot;&gt;GitHub 实战项目（可直接运行&#x2F;贡献）&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;system76-scheduler&lt;&#x2F;th&gt;&lt;th&gt;调度器 GUI，用 DBus 控制 systemd&#x2F;CPU&lt;&#x2F;th&gt;&lt;th&gt;Python + pydbus&lt;&#x2F;th&gt;&lt;th&gt;org.freedesktop.systemd1, logind&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;gnome-shell-screenshot&lt;&#x2F;td&gt;&lt;td&gt;类 Flameshot 工具&lt;&#x2F;td&gt;&lt;td&gt;JS + DBus&lt;&#x2F;td&gt;&lt;td&gt;portal.Screenshot, portal.Clipboard&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;blueman&lt;&#x2F;td&gt;&lt;td&gt;蓝牙管理器（Python）&lt;&#x2F;td&gt;&lt;td&gt;pydbus + GTK&lt;&#x2F;td&gt;&lt;td&gt;org.bluez, obex 协议&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;udisks2-wrapper&lt;&#x2F;td&gt;&lt;td&gt;磁盘挂载示例&lt;&#x2F;td&gt;&lt;td&gt;pydbus&lt;&#x2F;td&gt;&lt;td&gt;org.freedesktop.UDisks2&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;dbus-gong-ju-lei&quot;&gt;DBus 工具类&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;项目&lt;&#x2F;th&gt;&lt;th&gt;描述&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;d-spy&lt;&#x2F;td&gt;&lt;td&gt;GTK DBus Inspector（看接口&#x2F;发请求） ✅ 强烈推荐安装&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;dbus-next&lt;&#x2F;td&gt;&lt;td&gt;纯 Python async DBus 实现（兼容性好）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;xdg-desktop-portal&lt;&#x2F;td&gt;&lt;td&gt;官方测试用例（含 Python）→ 学 a{sv} 参数构造&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;portal-test&lt;&#x2F;td&gt;&lt;td&gt;专测 portal 接口的工具&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h1 id=&quot;kuai-su-shang-shou-5-ge-chang-yong-fu-wu-shi-zhan-dai-ma&quot;&gt;快速上手：5 个常用服务实战代码&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;依赖：pip install pydbus（初学）或 pip install zbus（进阶）&lt;&#x2F;li&gt;
&lt;li&gt;1️⃣ 发送桌面通知（org.freedesktop.Notifications）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;python&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;# notify.py
from pydbus import SessionBus

bus = SessionBus()
notif = bus.get(&amp;#x27;.Notifications&amp;#x27;)

# 发送通知
notif.Notify(
    &amp;quot;MyApp&amp;quot;,   # app_name
    0,         # replaces_id
    &amp;quot;&amp;quot;,        # app_icon
    &amp;quot;标题&amp;quot;,    # summary
    &amp;quot;消息内容&amp;quot;, # body
    [],        # actions
    {&amp;quot;urgency&amp;quot;: 1},  # hints (a{sv})
    5000       # timeout ms
)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;✅ 运行：python3 notify.py → 右上角弹出通知&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;2️⃣ 控制蓝牙开关（org.bluez）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;python&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;# bluetooth.py
from pydbus import SystemBus

bus = SystemBus()
# 获取默认适配器（如 hci0）
adapter = bus.get(&amp;#x27;org.bluez&amp;#x27;, &amp;#x27;&amp;#x2F;org&amp;#x2F;bluez&amp;#x2F;hci0&amp;#x27;)

print(&amp;quot;Powered:&amp;quot;, adapter.Powered)
adapter.Powered = False  # 关闭蓝牙
# adapter.Powered = True  # 开启
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;⚠️ 需权限：sudo usermod -aG bluetooth $USER + 重登&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;3️⃣ 查询电池状态（org.freedesktop.UPower）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;python&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;# battery.py
from pydbus import SystemBus

bus = SystemBus()
upower = bus.get(&amp;#x27;org.freedesktop.UPower&amp;#x27;, &amp;#x27;&amp;#x2F;org&amp;#x2F;freedesktop&amp;#x2F;UPower&amp;#x27;)

for dev_path in upower.EnumerateDevices():
    dev = bus.get(&amp;#x27;org.freedesktop.UPower&amp;#x27;, dev_path)
    if dev.Type == 2:  # 2 = Battery
        print(f&amp;quot;电量: {dev.Percentage:.1f}% | 状态: {dev.State}&amp;quot;)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;4️⃣ 调用截图 portal（解决你的 Flameshot 问题！）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;python&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;# portal_screenshot.py
from pydbus import SessionBus
import time

bus = SessionBus()
portal = bus.get(&amp;#x27;org.freedesktop.portal.Desktop&amp;#x27;,
                 &amp;#x27;&amp;#x2F;org&amp;#x2F;freedesktop&amp;#x2F;portal&amp;#x2F;desktop&amp;#x27;)

# 创建 Request 对象
request = bus.get(&amp;#x27;org.freedesktop.portal.Desktop&amp;#x27;,
                  portal.Request.CreateRequest(&amp;#x27;&amp;#x27;, &amp;#x27;&amp;#x27;)[0])

# 触发截图（interactive 模式）
opts = {
    &amp;#x27;modal&amp;#x27;: True,
    &amp;#x27;interactive&amp;#x27;: True
}
portal.Screenshot(request, opts)

# 监听 Response（简化版）
def on_response(response, results):
    if response == 0:  # 0 = success
        print(&amp;quot;截图保存路径:&amp;quot;, results.get(&amp;#x27;uri&amp;#x27;))
    else:
        print(&amp;quot;用户取消或失败&amp;quot;)

request.onResponse = on_response
time.sleep(10)  # 等待用户操作
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;✅ 运行后弹出 GNOME 截图界面 → 标注后保存路径打印到终端&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;5️⃣ 重启 systemd 用户服务（org.freedesktop.systemd1）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;python&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;# restart_service.py
from pydbus import SessionBus

bus = SessionBus()
systemd = bus.get(&amp;#x27;.systemd1&amp;#x27;)

# 重启 flameshot 服务（若配置了 autostart）
systemd.RestartUnit(&amp;#x27;flameshot.service&amp;#x27;, &amp;#x27;replace&amp;#x27;)
print(&amp;quot;Flameshot 服务已重启&amp;quot;)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;diao-shi-ji-qiao-jie-he-ni-zhi-qian-de-huan-jing&quot;&gt;调试技巧（结合你之前的环境）&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;快速定位 portal 问题：&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 1. 监控 portal 通信
busctl --session monitor --match=&amp;quot;interface=&amp;#x27;org.freedesktop.portal.*&amp;#x27;&amp;quot;

# 2. 检查 polkit 规则
pkaction --verbose --action-id org.freedesktop.portal.desktop.screenshot

# 3. 手动测试权限
gdbus call --session \
  --dest org.freedesktop.portal.Desktop \
  --object-path &amp;#x2F;org&amp;#x2F;freedesktop&amp;#x2F;portal&amp;#x2F;desktop \
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>linux 桌面效率工具</title>
        <published>2025-12-23T15:03:08+08:00</published>
        <updated>2025-12-23T15:03:08+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/12/linux 桌面效率工具/"/>
        <id>https://vercel.juzhong.xyz/2025/12/linux 桌面效率工具/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/12/linux 桌面效率工具/">&lt;h1 id=&quot;jie-tu-gong-ju&quot;&gt;截图工具&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;flameshot&quot;&gt;flameshot&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt install flameshot
# 配置系统快捷键: 直接配置快捷键命令&amp;quot;flameshot gui&amp;quot; 执行报错
sh -c &amp;quot;env QT_QPA_PLATFORM=wayland flameshot gui&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;ksnip-qt-bian-xie-kua-zhuo-mian-you-hao&quot;&gt;Ksnip（Qt 编写，跨桌面友好）&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# Debian&amp;#x2F;Ubuntu 推荐从 GitHub 下载 .deb
wget https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;ksnip&amp;#x2F;ksnip&amp;#x2F;releases&amp;#x2F;latest&amp;#x2F;download&amp;#x2F;ksnip_*_amd64.deb
sudo apt install .&amp;#x2F;ksnip_*.deb
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;snipaste&quot;&gt;Snipaste&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;gnome-screenshot&quot;&gt;gnome-screenshot&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;gnome-screenshot 本身较基础，但配合以下可大幅提升：&lt;&#x2F;li&gt;
&lt;li&gt;GNOME Shell 扩展：Screenshot Tool&lt;&#x2F;li&gt;
&lt;li&gt;添加标注、OCR、历史记录、多区域截图等功能，集成度高。&lt;&#x2F;li&gt;
&lt;li&gt;快捷：Ctrl+Alt+Print 截全屏 + 自动进编辑器（GNOME 45+ 原生支持简易标注，但功能弱于 Flameshot）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;bian-qian&quot;&gt;便签&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;flatpak install flathub com.vixalien.sticky&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;yuan-cheng-zhuo-mian&quot;&gt;远程桌面&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;remmina&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;ping-mu-biao-zhu&quot;&gt;屏幕标注&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;gromit-mpx&quot;&gt;Gromit-MPX&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt install gnome-software-plugin-flatpak
flatpak remote-add --if-not-exists flathub https:&amp;#x2F;&amp;#x2F;flathub.org&amp;#x2F;repo&amp;#x2F;flathub.flatpakrepo
flatpak install flathub net.christianbeier.Gromit-MPX
flatpak run net.christianbeier.Gromit-MPX
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;zi-dian-fan-yi-gong-ju&quot;&gt;字典、翻译工具&lt;&#x2F;h1&gt;
&lt;h1 id=&quot;lu-ping-gong-ju&quot;&gt;录屏工具&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;obs&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;bo-fang-gong-ju&quot;&gt;播放工具&lt;&#x2F;h1&gt;
&lt;h1 id=&quot;nautilus&quot;&gt;nautilus&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;sftp:&#x2F;&#x2F;192.168.7.99&lt;&#x2F;li&gt;
&lt;li&gt;smb:&#x2F;&#x2F;192.168.7.99&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;kai-qi-re-dian-gong-ju-wifihotspot&quot;&gt;开启热点工具wifihotspot&lt;&#x2F;h1&gt;
&lt;h1 id=&quot;tu-pian-bian-ji-gimp&quot;&gt;图片编辑GIMP&lt;&#x2F;h1&gt;
&lt;h1 id=&quot;shi-pin-bian-ji-shotcut&quot;&gt;视频编辑shotcut&lt;&#x2F;h1&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>linux pipewire 蓝牙耳机无声</title>
        <published>2025-12-22T20:23:01+08:00</published>
        <updated>2025-12-22T20:23:01+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/12/linux pipewire 蓝牙耳机无声/"/>
        <id>https://vercel.juzhong.xyz/2025/12/linux pipewire 蓝牙耳机无声/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/12/linux pipewire 蓝牙耳机无声/">&lt;h1 id=&quot;jie-jue-fang-an&quot;&gt;解决方案&lt;&#x2F;h1&gt;
&lt;p&gt;修改bluetooth策略&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo vim &amp;#x2F;etc&amp;#x2F;bluetooth&amp;#x2F;main.conf
[Policy]
AutoEnable=true
JustWorksRepairing=always
AutoConnect=true
#  end config

# 删除后重新配置
bluetoothctl devices
sudo cat &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;bluetooth&amp;#x2F;88:D8:2E:2B:20:09&amp;#x2F;41:AA:00:56:F4:FC&amp;#x2F;info
bluetoothctl remove 41:AA:00:56:F4:FC

sudo systemctl restart bluetooth
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;chang-yong-pei-zhi-yu-diao-shi-gong-ju-hui-zong&quot;&gt;常用配置与调试工具汇总&lt;&#x2F;h1&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;工具&lt;&#x2F;th&gt;&lt;th&gt;用途&lt;&#x2F;th&gt;&lt;th&gt;示例命令&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;bluetoothctl&lt;&#x2F;td&gt;&lt;td&gt;蓝牙配对&#x2F;连接底层控制&lt;&#x2F;td&gt;&lt;td&gt;info, connect, trust&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;pactl&lt;&#x2F;td&gt;&lt;td&gt;PipeWire Pulse 兼容控制&lt;&#x2F;td&gt;&lt;td&gt;list sinks&#x2F;cards, set-card-profile&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;pw-cli&lt;&#x2F;td&gt;&lt;td&gt;PipeWire 原生节点检查&lt;&#x2F;td&gt;&lt;td&gt;list-objects, inspect &lt;id&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;wireplumber 日志&lt;&#x2F;td&gt;&lt;td&gt;策略&#x2F;自动路由分析&lt;&#x2F;td&gt;&lt;td&gt;journalctl --user-unit=wireplumber -f&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;helvum (GUI)&lt;&#x2F;td&gt;&lt;td&gt;PipeWire 节点连接可视化&lt;&#x2F;td&gt;&lt;td&gt;helvum（需安装）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;qpwgraph (GUI)&lt;&#x2F;td&gt;&lt;td&gt;类似 helvum，Qt 版&lt;&#x2F;td&gt;&lt;td&gt;qpwgraph&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;btmon&lt;&#x2F;td&gt;&lt;td&gt;蓝牙 HCI 层抓包&lt;&#x2F;td&gt;&lt;td&gt;sudo btmon&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;dmesg -w&lt;&#x2F;td&gt;&lt;td&gt;内核蓝牙错误&lt;&#x2F;td&gt;&lt;td&gt;dmesg -w&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 1. 检查蓝牙服务是否运行
systemctl --user status pipewire wireplumber
# 必须都是 active (running)
systemctl --user restart wireplumber pipewire pipewire-pulse
sudo systemctl restart bluetooth

# 2. 确认蓝牙硬件启用
rfkill list bluetooth
# 若 soft&amp;#x2F;hard blocked，执行：
# rfkill unblock bluetooth

# 3. 检查内核模块
lsmod | grep -E &amp;#x27;btusb|bluetooth|snd_bt_sco&amp;#x27;
# 应有 bluetooth、btusb、可能还有 snd_bt_sco（用于 HFP）

# 使用 speaker-test 向默认蓝牙设备发送测试音
# 可能需要先用 `aplay -L` 查找具体设备名
speaker-test -D bluez:&amp;lt;设备名&amp;gt; -t wav -c 2
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;chang-yong-ming-ling&quot;&gt;常用命令&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;wpctl status     # 最常用。控制WirePlumber会话管理器，查看&amp;#x2F;切换默认设备，调节音量。
wpctl set-mute [ID] 0      # 取消静音
wpctl set-volume [ID] 0.5   # 设置音量为 50%

pw-cli info all  # PipeWire的命令行接口，用于直接与服务器交互，进行低级操作。
pw-dump &amp;gt; dump.json  # 将所有PipeWire对象（节点、设备等）的状态以JSON格式导出，用于详细分析或提交Bug报告
pw-top               #  类似系统top命令，实时显示音频处理节点的性能数据（如延迟、X运行次数）
pw-play .&amp;#x2F;test.mp3   # 用于直接播放或录制音频文件，进行快速测试

pactl list cards

apt install helvum
helvum
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;lan-ya&quot;&gt;蓝牙&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;bluetoothctl
&amp;gt; list               # 查看适配器
&amp;gt; show               # 当前适配器详情
&amp;gt; devices            # 已知设备
&amp;gt; info &amp;lt;MAC&amp;gt;         # 查看耳机详情：是否 Connected: yes, Trusted: yes
&amp;gt; connect &amp;lt;MAC&amp;gt;      # 手动连接（有时 GUI 配对未真正连通音频）

# 实时监听 BlueZ D-Bus 消息（高级）
sudo busctl monitor org.bluez
# 或用 btmon（需 root）
sudo btmon
# 这里发现是配对认证失败: 密钥不匹配：你的耳机里可能保存了与这台电脑或其他设备配对的旧密钥: 或者系统升级后默认策略收紧
sudo cat &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;bluetooth&amp;#x2F;11:11:2E:2B:20:09&amp;#x2F;22:22:00:56:F4:FC&amp;#x2F;info
# 这里保存了旧的协商密钥
# 删除耳机，重新配对后正常
bluetoothctl remove 41:AA:00:56:F4:FC
bluetoothctl
&amp;gt; scan on
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;pipewire-diao-shi&quot;&gt;pipewire 调试&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 列出所有 sink（输出设备）
pactl list sinks short
# 更详细（关键！看 active port 和 profile）
pactl list sinks

# 列出所有 PipeWire 节点（比 pactl 更底层）
pw-cli list-objects | grep -A5 -B5 -i bluetooth
# 查看蓝牙设备节点属性
pw-cli inspect &amp;lt;node-id&amp;gt;  # 如 42

cp &amp;#x2F;usr&amp;#x2F;share&amp;#x2F;wireplumber&amp;#x2F;bluez-monitor.d&amp;#x2F;50-bluez-config.lua ~&amp;#x2F;.config&amp;#x2F;wireplumber&amp;#x2F;bluez-monitor.d&amp;#x2F;
cat &amp;gt; ~&amp;#x2F;.config&amp;#x2F;wireplumber&amp;#x2F;bluez-monitor.d&amp;#x2F;50-bluez-config.lua&amp;lt;&amp;lt;EOF
bluez_monitor.properties = {
  [&amp;quot;bluez5.auto-switch&amp;quot;] = true,
  [&amp;quot;bluez5.headset-voice&amp;quot;] = true,   -- ← 若你不需要通话，可设为 false
}
EOF

systemctl --user restart wireplumber

# PipeWire 层
pactl get-sink-volume @DEFAULT_SINK@
pactl get-sink-mute @DEFAULT_SINK@

# ALSA 层（有时 PipeWire 未接管）
alsamixer -D pipewire
# 或
alsamixer        # 按 F6 选蓝牙设备（若有）

sudo apt install helvum qpwgraph pavucontrol
# 用 pactl 指定 sink 播放测试音
pactl play-sample bell-window bluez_output.XX_XX_XX_XX_XX_XX.a2dp-sink
# 或用 pw-play（PipeWire 原生命令）
pw-play --target=bluez_output.XX_XX_XX_XX_XX_XX.a2dp-sink &amp;#x2F;usr&amp;#x2F;share&amp;#x2F;sounds&amp;#x2F;alsa&amp;#x2F;Front_Center.wav
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;pai-cha-ji-lu&quot;&gt;排查记录&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;zhi-you-sheng-yin-mei-you-mai-ke-feng&quot;&gt;只有声音没有麦克风？&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;通常是因为蓝牙协议在“高音质播放”和“双向通话”之间切换失败，或者系统默认选择了错误的音频配置文件（Profile）&lt;&#x2F;li&gt;
&lt;li&gt;蓝牙耳机通常有两种工作模式：
&lt;ul&gt;
&lt;li&gt;A2DP (High Fidelity Playback)：高音质立体声输出，麦克风不可用。&lt;&#x2F;li&gt;
&lt;li&gt;HSP&#x2F;HFP (Headset Head Unit)：低音质单声道&#x2F;立体声，麦克风可用（用于通话）。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;jie-jue-fang-an-1&quot;&gt;解决方案&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;直接在系统配置中切换, 设置 (Settings) -&amp;gt; 声音 (Sound),将配置从 High Fidelity Playback (A2DP Sink) 改为 Headset Head Unit (HSP&#x2F;HFP) 或 Handsfree Head Unit (HFP)&lt;&#x2F;li&gt;
&lt;li&gt;系统自带设置找不到切换profile选项，使用pavucontrol (PulseAudio Volume Control) 是最有效的工具。即使你使用的是 PipeWire，它也兼容
&lt;ul&gt;
&lt;li&gt;最右侧的 配置 (Configuration) 选项卡&lt;&#x2F;li&gt;
&lt;li&gt;配置文件 (Profile) 从 High Fidelity Playback (A2DP Sink) 修改为 Headset Head Unit (HSP&#x2F;HFP)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>linux 打印机的使用</title>
        <published>2025-12-22T13:55:04+08:00</published>
        <updated>2025-12-22T13:55:04+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/12/linux 打印机的使用/"/>
        <id>https://vercel.juzhong.xyz/2025/12/linux 打印机的使用/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/12/linux 打印机的使用/">&lt;h1 id=&quot;pei-zhi-yang-li&quot;&gt;配置样例&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;ippfind
avahi-resolve -n EPSON4DDFDF.local
getent hosts EPSON4DDFDF.local

ipptool -tv ipp:&amp;#x2F;&amp;#x2F;EPSON4DDFDF.local:631&amp;#x2F;ipp&amp;#x2F;print &amp;#x2F;usr&amp;#x2F;share&amp;#x2F;cups&amp;#x2F;ipptool&amp;#x2F;get-printer-attributes.test | grep -i device-id -C3

# 无驱动安装打印机（最简单、最稳定）
lpip=192.168.4.143  # ← 替换为你的打印机 IP
sudo lpadmin -p Epson_L4160_Driverless \
  -E \
  -v &amp;quot;ipp:&amp;#x2F;&amp;#x2F;$lpip:631&amp;#x2F;ipp&amp;#x2F;print&amp;quot; \
  -m everywhere

lpip=192.168.4.143  # ← 替换为你的打印机 IP
sudo apt update &amp;amp;&amp;amp; sudo apt install printer-driver-escpr
lpinfo -m | grep -i &amp;quot;L4160&amp;quot;
sudo lpadmin -p Epson_L4160_Full \
  -E \
  -v &amp;quot;ipp:&amp;#x2F;&amp;#x2F;$lpip&amp;#x2F;ipp&amp;#x2F;print&amp;quot; \
  -m &amp;quot;epson-inkjet-printer-escpr&amp;#x2F;Epson-L4160_Series-epson-escpr-en.ppd&amp;quot;

# 删除打印机
sudo lpadmin -x Epson_L4160_Driverless Epson_L4160_Full

lpinfo -m | grep -i &amp;#x27;m329\|laserjet.pro.*mfp&amp;#x27; | grep -v &amp;#x27;generic&amp;#x27;

ip=192.168.1.100  # ← 替换为你的打印机 IP
sudo lpadmin -p M329 \
             -v &amp;quot;ipp:&amp;#x2F;&amp;#x2F;$ip:631&amp;#x2F;ipp&amp;#x2F;print&amp;quot; \
             -m postscript-hp:0&amp;#x2F;ppd&amp;#x2F;hplip&amp;#x2F;HP&amp;#x2F;hp-laserjet_pro_mfp_m329-ps.ppd \
             -E

# 设为默认打印机
sudo lpadmin -d M329
# 测试打印
echo &amp;quot;✅ M329 驱动配置成功&amp;quot; | lp
tail -f &amp;#x2F;var&amp;#x2F;log&amp;#x2F;cups&amp;#x2F;error_log

# 使用无驱动打印 这是最简单的方式，直接使用系统发现的驱动
# -m everywhere 参数告诉CUPS使用“无驱动”模式自动配置，这利用了你的打印机已经支持的 IPP Everywhere 标准
sudo lpadmin -p HP_LaserJet_Pro_M329 \
  -E \
  -v ipp:&amp;#x2F;&amp;#x2F;HP489EBD702C63.local:631&amp;#x2F;ipp&amp;#x2F;print \
  -m everywhere

echo &amp;quot;HP LaserJet Pro M329 测试页 - $(date)&amp;quot; | lpr -P HP_LaserJet_Pro_M329
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;chang-yong-gong-ju-gong-neng&quot;&gt;常用工具功能&lt;&#x2F;h1&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;工具&lt;&#x2F;th&gt;&lt;th&gt;包名&lt;&#x2F;th&gt;&lt;th&gt;用途&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;cupsd&lt;&#x2F;td&gt;&lt;td&gt;cups-daemon&lt;&#x2F;td&gt;&lt;td&gt;CUPS 后台服务（调度器）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;lp* 系列&lt;&#x2F;td&gt;&lt;td&gt;cups-client&lt;&#x2F;td&gt;&lt;td&gt;打印作业控制（lp, lpstat, lpadmin, cancel）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;ipptool&lt;&#x2F;td&gt;&lt;td&gt;cups-ipp-utils&lt;&#x2F;td&gt;&lt;td&gt;IPP 协议底层探测（诊断必备）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;avahi-browse&lt;&#x2F;td&gt;&lt;td&gt;avahi-utils&lt;&#x2F;td&gt;&lt;td&gt;浏览 DNS-SD 服务（发现打印机）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;system-config-printer（CLI 调用）&lt;&#x2F;td&gt;&lt;td&gt;system-config-printer&lt;&#x2F;td&gt;&lt;td&gt;文本界面配置（备选）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;|对象|	命令|	含义
|-|	-|	-
|Scheduler|	cupsd|	打印调度器
|Printer|	lpadmin|	打印队列
|Job|	lp &#x2F; lpr|	打印任务
|Options|	lpoptions|	打印参数&lt;&#x2F;p&gt;
&lt;h2 id=&quot;chang-yong-ming-ling-xing&quot;&gt;常用命令行&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;lp file.pdf                   # 用默认打印机
lp -d M329 file.pdf           # 指定打印机
lp -o sides=two-sided-long-edge file.pdf  # 双面（长边翻转）
lp -o number-up=2 file.pdf    # 1页打2版（节省纸）
cancel M329-123               # 取消作业ID 123
cancel -a M329                # 取消M329所有作业

sudo tail -f &amp;#x2F;var&amp;#x2F;log&amp;#x2F;cups&amp;#x2F;error_log
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;shou-dong-ce-shi-da-yin-rao-guo-cups-dui-lie&quot;&gt;手动测试打印（绕过 CUPS 队列）&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 直接发 PDF 到 IPP 端点（需打印机支持 IPP Everywhere）
curl -X POST \
     -H &amp;quot;Content-Type: application&amp;#x2F;pdf&amp;quot; \
     --data-binary @&amp;#x2F;etc&amp;#x2F;issue \
     &amp;#x27;ipp:&amp;#x2F;&amp;#x2F;192.168.1.100:631&amp;#x2F;ipp&amp;#x2F;print&amp;#x27; \
     -o &amp;#x2F;tmp&amp;#x2F;ipp-response.bin
# 检查响应：若 200 OK 且打印机出纸 → 底层 IPP 正常，问题在 CUPS 配置
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;guan-bi-cups-browsed&quot;&gt;关闭cups-browsed&lt;&#x2F;h2&gt;
&lt;p&gt;默认发现的打印机器常是implicitclassj性能低？？&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo systemctl stop cups-browsed
sudo systemctl disable cups-browsed
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;ming-ling-xing-shi-yong-da-yin-ji&quot;&gt;命令行使用打印机&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 第一步：发现打印机URI, 主动扫描局域网中所有支持 IPP 的设备（打印机、扫描仪、甚至 IPP 服务器）
ippfind  
# 第二步：测试连接
ipptool -tv &amp;#x27;ipp:&amp;#x2F;&amp;#x2F;EPSON4DDFDF.local:631&amp;#x2F;ipp&amp;#x2F;print&amp;#x27; &amp;#x2F;usr&amp;#x2F;share&amp;#x2F;cups&amp;#x2F;ipptool&amp;#x2F;get-printer-attributes.test
# 第三步：添加到CUPS
sudo lpadmin -p EPSON_L4160 \
  -E \
  -v &amp;quot;ipp:&amp;#x2F;&amp;#x2F;EPSON4DDFDF.local:631&amp;#x2F;ipp&amp;#x2F;print&amp;quot; \
  -m everywhere

# 查看DNS-SD服务详细信息
avahi-browse -rpt _ipp._tcp

# 查看所有打印机 # 列出 CUPS 当前已注册并管理的打印机 及其内部表示的设备 URI
lpstat -p -d
# 输出示例：
# printer EPSON_L4160 is idle. enabled since Mon 2023-01-01 10:00:00 CST
# printer HP_LaserJet is idle. enabled since Mon 2023-01-01 10:00:00 CST
# system default destination: EPSON_L4160

# 查看详细打印机信息
lpstat -l -v

# 查看打印队列
lpq
# 输出示例：
# EPSON_L4160 is ready
# no entries

# 查看打印机选项
lpoptions -p &amp;lt;printer_name&amp;gt; -l# 查看所有打印机
lpstat -p -d
# 查看详细打印机信息
lpstat -l -v

# 列出所有可用驱动
lpinfo -m
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;tian-jia-da-yin-ji&quot;&gt;添加打印机&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 添加网络打印机（IPP协议）
sudo lpadmin -p EPSON_L4160 -E \
  -v &amp;quot;ipp:&amp;#x2F;&amp;#x2F;192.168.1.100&amp;#x2F;ipp&amp;#x2F;print&amp;quot; \
  -m &amp;quot;drv:&amp;#x2F;&amp;#x2F;&amp;#x2F;sample.drv&amp;#x2F;generic.ppd&amp;quot; \
  -L &amp;quot;办公室&amp;quot;

# 参数解释：
# -p：打印机名称
# -E：启用打印机
# -v：设备URI
# -m：PPD驱动文件
# -L：位置描述

# 添加USB打印机
sudo lpadmin -p HP_Deskjet -E \
  -v &amp;quot;usb:&amp;#x2F;&amp;#x2F;HP&amp;#x2F;Deskjet?serial=XYZ123&amp;quot; \
  -m &amp;quot;ppd&amp;#x2F;hp-deskjet.ppd&amp;quot;

# 添加SMB共享打印机
sudo lpadmin -p Network_Printer -E \
  -v &amp;quot;smb:&amp;#x2F;&amp;#x2F;workgroup&amp;#x2F;user:password@server&amp;#x2F;printer&amp;quot; \
  -m &amp;quot;everywhere&amp;quot; \
  -o auth-info-required=username,password

# 发现网络打印机
ippfind
# 输出示例：ipp:&amp;#x2F;&amp;#x2F;EPSON%20L4160._ipp._tcp.local&amp;#x2F;

# 获取驱动信息
lpinfo --make-and-model &amp;quot;EPSON L4160&amp;quot; -m
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;pei-zhi-da-yin-ji&quot;&gt;配置打印机&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 设置默认打印机
sudo lpadmin -d EPSON_L4160

# 配置打印机选项
sudo lpadmin -p EPSON_L4160 \
  -o PageSize=A4 \
  -o Duplex=DuplexNoTumble \
  -o ColorModel=RGB \
  -o Resolution=600dpi

# 禁用&amp;#x2F;启用打印机
sudo cupsdisable EPSON_L4160
sudo cupsenable EPSON_L4160

# 拒绝&amp;#x2F;接受打印作业
cupsreject EPSON_L4160
cupsaccept EPSON_L4160
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;ji-ben-da-yin&quot;&gt;基本打印&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 基本打印
lpr document.pdf

# 指定打印机
lpr -P EPSON_L4160 document.pdf

# 指定份数
lpr -# 3 document.pdf

# 指定打印范围
lpr -o page-ranges=1-5,8,11-13 document.pdf

# 双面打印
lpr -o sides=two-sided-long-edge document.pdf

# 打印选项组合
lpr -P HP_LaserJet -o media=A4 -o sides=two-sided-short-edge -# 2 report.pdf
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;da-yin-dui-lie-guan-li&quot;&gt;打印队列管理&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 查看所有打印作业
lpstat -o

# 输出示例：
# EPSON_L4160-101 user1 1024 Mon 10:00:00
# HP_LaserJet-102 user2 2048 Mon 10:01:00

# 查看特定打印机的作业
lpq -P EPSON_L4160

# 取消打印作业
lprm 101
# 或取消所有作业
lprm -

# 移动作业到另一台打印机
lpmove 101 HP_LaserJet

# 查看作业详情
lpq -l -P EPSON_L4160
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;gao-ji-pei-zhi&quot;&gt;高级配置&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 主要配置文件
&amp;#x2F;etc&amp;#x2F;cups&amp;#x2F;cupsd.conf      # CUPS服务配置
&amp;#x2F;etc&amp;#x2F;cups&amp;#x2F;printers.conf   # 打印机定义
&amp;#x2F;etc&amp;#x2F;cups&amp;#x2F;ppd&amp;#x2F;            # PPD驱动文件目录
&amp;#x2F;var&amp;#x2F;spool&amp;#x2F;cups&amp;#x2F;          # 打印队列目录

# 查看CUPS错误日志
sudo tail -f &amp;#x2F;var&amp;#x2F;log&amp;#x2F;cups&amp;#x2F;error_log

# 查看访问日志
sudo tail -f &amp;#x2F;var&amp;#x2F;log&amp;#x2F;cups&amp;#x2F;access_log

# 设置日志级别
sudo cupsctl LogLevel=debug
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;qu-dong-fang-an-dui-bi-ji-yu-ni-de-cmd-lie-biao&quot;&gt;驱动方案对比（基于你的 CMD 列表）&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;驱动方案&lt;&#x2F;th&gt;&lt;th&gt;是否支持 PCLXL&lt;&#x2F;th&gt;&lt;th&gt;是否支持 PDF&lt;&#x2F;th&gt;&lt;th&gt;是否支持 POSTSCRIPT&lt;&#x2F;th&gt;&lt;th&gt;状态反馈&lt;&#x2F;th&gt;&lt;th&gt;推荐度&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;hpcups&lt;&#x2F;td&gt;&lt;td&gt;✅ 原生优化&lt;&#x2F;td&gt;&lt;td&gt;✅ 直接处理&lt;&#x2F;td&gt;&lt;td&gt;✅ Ghostscript 后端&lt;&#x2F;td&gt;&lt;td&gt;✅ 完整（墨量&#x2F;卡纸）&lt;&#x2F;td&gt;&lt;td&gt;⭐⭐⭐⭐⭐&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;IPP Everywhere (everywhere)&lt;&#x2F;td&gt;&lt;td&gt;❌ 转 PDF&lt;&#x2F;td&gt;&lt;td&gt;✅ 原生&lt;&#x2F;td&gt;&lt;td&gt;❌ 无 PostScript&lt;&#x2F;td&gt;&lt;td&gt;⚠️ 仅基础状态&lt;&#x2F;td&gt;&lt;td&gt;⭐⭐⭐&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Generic PostScript&lt;&#x2F;td&gt;&lt;td&gt;❌&lt;&#x2F;td&gt;&lt;td&gt;❌&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;❌&lt;&#x2F;td&gt;&lt;td&gt;⭐&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;white-check-mark-wei-shen-me-hpcups-geng-you&quot;&gt;✅ 为什么 hpcups 更优？&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;你的打印机广播了 PCLXL（高效二进制语言），而 hpcups 会：&lt;&#x2F;li&gt;
&lt;li&gt;直接生成 PCLXL → 比 PDF 转换快 20%+&lt;&#x2F;li&gt;
&lt;li&gt;利用 CID:HPLJPDLV1 启用硬件级双面校准&lt;&#x2F;li&gt;
&lt;li&gt;通过 PJL 查询 SN:CNDRP7P136 实现精确墨量监控&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>linux 中ntfs自动挂载</title>
        <published>2025-12-09T13:49:17+08:00</published>
        <updated>2025-12-09T13:49:17+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/12/linux 中ntfs自动挂载/"/>
        <id>https://vercel.juzhong.xyz/2025/12/linux 中ntfs自动挂载/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/12/linux 中ntfs自动挂载/">&lt;h1 id=&quot;zi-dong-gua-zai-windowsfen-qu&quot;&gt;自动挂载windows分区&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt install ntfs-3g
sudo ntfslabel &amp;#x2F;dev&amp;#x2F;sda2 &amp;quot;Windows&amp;quot; 
sudo mount -a
sudo systemctl restart udisks2.service
ls &amp;#x2F;media&amp;#x2F;peter&amp;#x2F;
sudo udevadm control --reload-rules &amp;amp;&amp;amp; sudo udevadm trigger
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>制作iso启动镜像</title>
        <published>2025-12-08T17:03:21+08:00</published>
        <updated>2025-12-08T17:03:21+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/12/制作iso启动镜像/"/>
        <id>https://vercel.juzhong.xyz/2025/12/制作iso启动镜像/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/12/制作iso启动镜像/">&lt;h1 id=&quot;shi-yong-lb-buildji-yu-debianshang-you-zhi-zuo-ni-de-linuxfa-xing-ban&quot;&gt;使用lb-build基于Debian上游制作你的Linux发行版&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;apt install live-build
mkdir TestOS
cd TestOS

# Ubuntu 系统的 live-build 会自动注入 Ubuntu 默认包： 使用debian环境构建
podman pull debian:bookworm
podman run --privileged -it --rm -v.&amp;#x2F;:&amp;#x2F;build&amp;#x2F; debian:bookworm bash

sudo sed -i &amp;#x27;s&amp;#x2F;deb.debian.org&amp;#x2F;mirrors.ustc.edu.cn&amp;#x2F;g&amp;#x27; &amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;sources.list.d&amp;#x2F;debian.sources
apt update
apt install -y live-build debootstrap debian-archive-keyring
cd &amp;#x2F;build&amp;#x2F;

sudo lb clean --purge
sudo rm config chroot cache -rf
lb config \
  --distribution bookworm \
  --archive-areas &amp;quot;main contrib non-free non-free-firmware&amp;quot; \
  --mirror-bootstrap https:&amp;#x2F;&amp;#x2F;mirrors.ustc.edu.cn&amp;#x2F;debian&amp;#x2F; \
  --mirror-chroot https:&amp;#x2F;&amp;#x2F;mirrors.ustc.edu.cn&amp;#x2F;debian&amp;#x2F; \
  --mirror-chroot-security https:&amp;#x2F;&amp;#x2F;mirrors.ustc.edu.cn&amp;#x2F;debian-security&amp;#x2F; \
  --mirror-binary-security https:&amp;#x2F;&amp;#x2F;mirrors.ustc.edu.cn&amp;#x2F;debian-security \
  --mirror-debian-installer https:&amp;#x2F;&amp;#x2F;mirrors.ustc.edu.cn&amp;#x2F;debian \
  --security true

sudo lb build

xorriso -as cdrecord -v dev=&amp;#x2F;dev&amp;#x2F;sr0 Blank=as_needed .&amp;#x2F;live-image-amd64.hybrid.iso
dd if=.&amp;#x2F;live-image-amd64.hybrid.iso of=&amp;#x2F;dev&amp;#x2F;sdb bs=64M conv=fsync status=progress

aptitude search &amp;#x27;~prequired|~pimportant&amp;#x27;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;zhuanlan.zhihu.com&#x2F;p&#x2F;643461882&quot;&gt;参考教程&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;shi-yong-ben-di-xi-tong-huo-debootstrapgou-jian-zui-xiao-gen-wen-jian-xi-tong&quot;&gt;使用本地系统或debootstrap构建最小根文件系统&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;an-zhuang-gong-ju-yu-zhun-bei-huan-jing&quot;&gt;安装工具与准备环境&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 安装核心工具
sudo apt update
sudo apt install debootstrap squashfs-tools xorriso grub-pc-bin grub-efi-amd64-bin isolinux
# sudo apt install syslinux-utils mtools genisoimage rsync

# 创建工作目录
mkdir ~&amp;#x2F;debian-custom-iso &amp;amp;&amp;amp; cd ~&amp;#x2F;debian-custom-iso
mkdir rootfs iso
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;gou-jian-zui-xiao-gen-wen-jian-xi-tong&quot;&gt;构建最小根文件系统&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 假设构建Debian 12 (Bookworm) 系统
sudo debootstrap --verbose --arch=amd64 bookworm .&amp;#x2F;rootfs http:&amp;#x2F;&amp;#x2F;deb.debian.org&amp;#x2F;debian
# 进入新系统进行基本配置
sudo mount -t proc proc rootfs&amp;#x2F;proc
sudo mount --rbind &amp;#x2F;sys rootfs&amp;#x2F;sys
sudo mount --rbind &amp;#x2F;dev rootfs&amp;#x2F;dev
sudo chroot .&amp;#x2F;rootfs &amp;#x2F;bin&amp;#x2F;bash
# 在chroot环境中执行以下命令
# 1. 安装一些最基础的软件和内核
apt update
apt install --no-install-recommends linux-image-amd64 systemd-sysv passwd
apt install live-boot live-config
# grub-pc-bin grub-efi-amd64 grub-efi-amd64-bin parted dosfstools openssh-server
# 2. 设置root密码（重要，否则可能无法登录）
echo custom-debian &amp;gt; &amp;#x2F;etc&amp;#x2F;hostname
echo &amp;quot;127.0.1.1 custom-debian&amp;quot; &amp;gt;&amp;gt; &amp;#x2F;etc&amp;#x2F;hosts
echo &amp;quot;root:root&amp;quot; | chpasswd
# 3. 配置网络（基础DHCP）
echo &amp;quot;auto eth0&amp;quot; &amp;gt;&amp;gt; &amp;#x2F;etc&amp;#x2F;network&amp;#x2F;interfaces.d&amp;#x2F;eth0
echo &amp;quot;iface eth0 inet dhcp&amp;quot; &amp;gt;&amp;gt; &amp;#x2F;etc&amp;#x2F;network&amp;#x2F;interfaces.d&amp;#x2F;eth0
# 4. 退出chroot环境
exit
sudo umount -l rootfs&amp;#x2F;{proc,sys,dev}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;zhi-zuo-squashfs-zuo-wei-live-xi-tong-root&quot;&gt;制作 squashfs（作为 live 系统 root）&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# sudo apt install live-boot live-config
chroot rootfs apt install live-boot live-config
chroot rootfs update-initramfs -u

mkdir -p iso&amp;#x2F;live
sudo mksquashfs rootfs iso&amp;#x2F;live&amp;#x2F;filesystem.squashfs -comp xz -wildcards
cp rootfs&amp;#x2F;boot&amp;#x2F;vmlinuz-* iso&amp;#x2F;live&amp;#x2F;vmlinuz
cp rootfs&amp;#x2F;boot&amp;#x2F;initrd.img-* iso&amp;#x2F;live&amp;#x2F;initrd.img
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;pei-zhi-qing-dan&quot;&gt;配置清单&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;mkdir iso&amp;#x2F;isolinux&amp;#x2F;
cp &amp;#x2F;usr&amp;#x2F;lib&amp;#x2F;ISOLINUX&amp;#x2F;isolinux.bin iso&amp;#x2F;isolinux&amp;#x2F;
cp &amp;#x2F;usr&amp;#x2F;lib&amp;#x2F;syslinux&amp;#x2F;modules&amp;#x2F;bios&amp;#x2F;ldlinux.c32 iso&amp;#x2F;isolinux&amp;#x2F;

cat &amp;gt; iso&amp;#x2F;isolinux&amp;#x2F;isolinux.cfg &amp;lt;&amp;lt;EOF
DEFAULT install
TIMEOUT 3
PROMPT 1
LABEL install
  SAY Booting custom Debian live system...
  MENU LABEL ^Install Debian (text mode)
  KERNEL &amp;#x2F;live&amp;#x2F;vmlinuz
  APPEND vga=788 initrd=&amp;#x2F;live&amp;#x2F;initrd.img boot=live quiet rd.debug 
EOF
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;uefiyin-dao-grub-efi&quot;&gt;UEFI引导(grub-efi)&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;mkdir -p iso&amp;#x2F;EFI&amp;#x2F;BOOT iso&amp;#x2F;boot&amp;#x2F;grub
cp &amp;#x2F;usr&amp;#x2F;lib&amp;#x2F;grub&amp;#x2F;x86_64-efi&amp;#x2F;monolithic&amp;#x2F;grubx64.efi iso&amp;#x2F;EFI&amp;#x2F;BOOT&amp;#x2F;BOOTX64.EFI


# 创建GRUB配置文件 (iso&amp;#x2F;boot&amp;#x2F;grub&amp;#x2F;grub.cfg)
cat &amp;gt; iso&amp;#x2F;boot&amp;#x2F;grub&amp;#x2F;grub.cfg &amp;lt;&amp;lt; &amp;#x27;EOF&amp;#x27;
set timeout=5
menuentry &amp;quot;Custom Debian Live&amp;quot; {
    linux &amp;#x2F;live&amp;#x2F;vmlinuz boot=live quiet
    initrd &amp;#x2F;live&amp;#x2F;initrd.img
}
EOF
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;sheng-cheng-ke-qi-dong-iso&quot;&gt;生成可启动ISO&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 注意！！！ 相对ISO 内路径是 &amp;#x2F;isolinux&amp;#x2F;isolinux.bin
# 注意！！！ 相对ISO 内路径是 &amp;#x2F;EFI&amp;#x2F;BOOT&amp;#x2F;BOOTX64.EFI
xorriso -as mkisofs \
  -o debian-custom.iso \
  -iso-level 3 \
  -full-iso9660-filenames \
  -volid &amp;quot;CUSTOM_DEBIAN&amp;quot; \
  -eltorito-boot isolinux&amp;#x2F;isolinux.bin \
  -eltorito-catalog isolinux&amp;#x2F;boot.cat \
  -no-emul-boot -boot-load-size 4 -boot-info-table \
  -eltorito-alt-boot \
  -e EFI&amp;#x2F;BOOT&amp;#x2F;BOOTX64.EFI \
  -no-emul-boot \
  iso&amp;#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;ke-xuan-jia-ru-ni-de-an-zhuang-jiao-ben-zi-ding-yi-installer&quot;&gt;（可选）：加入你的“安装脚本”（自定义 installer）&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 你自己的安装脚本可以把 rootfs 安装进真实硬盘：
# 你就拥有了一个 完全自己定制的 Debian 安装 ISO。
cat &amp;gt; iso&amp;#x2F;install.sh &amp;lt;&amp;lt;EOF
mkfs.ext4 &amp;#x2F;dev&amp;#x2F;sda1
mount &amp;#x2F;dev&amp;#x2F;sda1 &amp;#x2F;mnt
unsquashfs -f -d &amp;#x2F;mnt &amp;#x2F;live&amp;#x2F;filesystem.squashfs
grub-install &amp;#x2F;dev&amp;#x2F;sda
update-grub
EOF

cat &amp;gt;&amp;gt; grub.cfg &amp;lt;&amp;lt;EOF
menuentry &amp;quot;Run installer&amp;quot; {
    linux &amp;#x2F;live&amp;#x2F;vmlinuz boot=live autoexec=&amp;#x2F;install.sh
    initrd &amp;#x2F;live&amp;#x2F;initrd.img
}
EOF
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;ce-shi-yan-zheng&quot;&gt;测试验证&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# bios
qemu-system-x86_64 -m 1024 -cdrom debian-custom.iso -boot d -enable-kvm

# uefi 启动
sudo apt install ovmf
qemu-system-x86_64 -m 1024 \
-bios &amp;#x2F;usr&amp;#x2F;share&amp;#x2F;OVMF&amp;#x2F;OVMF.fd \
-cdrom debian-custom.iso \
-boot d -enable-kvm

# 可 dd 到 U 盘
sudo dd if=debian-custom.iso of=&amp;#x2F;dev&amp;#x2F;sdX bs=4M status=progress
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;diao-shi-pai-cha&quot;&gt;调试排查&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;xorriso -indev debian-custom.iso -ls | grep -i &amp;#x27;initrd\|vmlinuz&amp;#x27;
mkdir &amp;#x2F;tmp&amp;#x2F;iso
sudo mount -o loop debian-custom.iso &amp;#x2F;tmp&amp;#x2F;iso
find &amp;#x2F;tmp&amp;#x2F;iso -name &amp;quot;*initrd*&amp;quot; -o -name &amp;quot;*vmlinuz*&amp;quot; 2&amp;gt;&amp;#x2F;dev&amp;#x2F;null
sudo umount &amp;#x2F;tmp&amp;#x2F;iso
xorriso -indev debian-custom.iso -extract &amp;#x27;&amp;#x2F;isolinux&amp;#x2F;isolinux.cfg&amp;#x27; &amp;#x2F;tmp&amp;#x2F;isolinux.cfg 2&amp;gt;&amp;#x2F;dev&amp;#x2F;null || true
xorriso -indev debian-custom.iso -extract &amp;#x27;&amp;#x2F;boot&amp;#x2F;grub&amp;#x2F;grub.cfg&amp;#x27; &amp;#x2F;tmp&amp;#x2F;grub.cfg 2&amp;gt;&amp;#x2F;dev&amp;#x2F;null || true

cat &amp;#x2F;tmp&amp;#x2F;isolinux.cfg &amp;#x2F;tmp&amp;#x2F;grub.cfg 2&amp;gt;&amp;#x2F;dev&amp;#x2F;null | grep -A1 -B1 &amp;#x27;initrd\|vmlinuz&amp;#x27;

mkdir &amp;#x2F;tmp&amp;#x2F;initrd
cd &amp;#x2F;tmp&amp;#x2F;initrd
zcat &amp;#x2F;tmp&amp;#x2F;iso&amp;#x2F;live&amp;#x2F;initrd.img | cpio -idmv
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;debian-guan-fang-de-mini-live-zhi-zuo-liu-cheng&quot;&gt;Debian 官方的 mini live 制作流程&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# chroot 内安装 live-boot + rebuild initrd
chroot rootfs apt update
chroot rootfs apt install --no-install-recommends live-boot live-config systemd-sysv linux-image-amd64
chroot rootfs update-initramfs -u

# ISOLINUX 目录结构
mkdir -p iso&amp;#x2F;isolinux
cp &amp;#x2F;usr&amp;#x2F;lib&amp;#x2F;ISOLINUX&amp;#x2F;isolinux.bin iso&amp;#x2F;isolinux&amp;#x2F;
cp &amp;#x2F;usr&amp;#x2F;lib&amp;#x2F;syslinux&amp;#x2F;modules&amp;#x2F;bios&amp;#x2F;*.c32 iso&amp;#x2F;isolinux&amp;#x2F;

# 创建 UEFI FAT ESP
mkdir -p iso&amp;#x2F;efi-img
mkdir -p esp&amp;#x2F;EFI&amp;#x2F;BOOT
cp &amp;#x2F;usr&amp;#x2F;lib&amp;#x2F;grub&amp;#x2F;x86_64-efi&amp;#x2F;monolithic&amp;#x2F;grubx64.efi esp&amp;#x2F;EFI&amp;#x2F;BOOT&amp;#x2F;BOOTX64.EFI

# 制作 FAT 镜像
dd if=&amp;#x2F;dev&amp;#x2F;zero of=iso&amp;#x2F;efi.img bs=1M count=10
mkfs.vfat iso&amp;#x2F;efi.img
mcopy -i iso&amp;#x2F;efi.img -s esp&amp;#x2F;* ::&amp;#x2F;

# xorriso 构建正确的混合引导 ISO
xorriso -as mkisofs \
  -o debian-custom.iso \
  -iso-level 3 \
  -full-iso9660-filenames \
  -eltorito-boot isolinux&amp;#x2F;isolinux.bin \
    -eltorito-catalog isolinux&amp;#x2F;boot.cat \
    -no-emul-boot -boot-load-size 4 -boot-info-table \
  -eltorito-alt-boot \
    -e efi.img \
    -no-emul-boot \
  -append_partition 2 0xef iso&amp;#x2F;efi.img \
  iso&amp;#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>apt本地仓库</title>
        <published>2025-12-08T13:35:58+08:00</published>
        <updated>2025-12-08T13:35:58+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/12/apt本地仓库/"/>
        <id>https://vercel.juzhong.xyz/2025/12/apt本地仓库/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/12/apt本地仓库/">&lt;h1 id=&quot;pei-zhi-ben-di-debianyuan-cang-ku-fang-an&quot;&gt;配置本地Debian源仓库方案&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt install reprepro apt-rdepends
sudo mkdir -p &amp;#x2F;srv&amp;#x2F;localrepo&amp;#x2F;{conf,packages}
sudo chmod -R 755 &amp;#x2F;srv&amp;#x2F;localrepo
sudo chown peter:peter &amp;#x2F;srv&amp;#x2F;localrepo

sudo tee &amp;#x2F;srv&amp;#x2F;localrepo&amp;#x2F;conf&amp;#x2F;distributions &amp;lt;&amp;lt;EOF
Origin: LocalRepo
Label: LocalRepo
Codename: bookworm
Architectures: amd64
Components: main
Description: Minimal local Debian repo
EOF

mkdir -p &amp;#x2F;tmp&amp;#x2F;debs
cd &amp;#x2F;tmp&amp;#x2F;debs
pkgs=(&amp;quot;nginx&amp;quot; &amp;quot;curl&amp;quot;)
for pkg in ${pkgs}; do
  apt-rdepends $pkg | grep -v &amp;quot;^ &amp;quot;
done &amp;gt; &amp;#x2F;tmp&amp;#x2F;pkglist
while read pkg; do
    apt download &amp;quot;$pkg&amp;quot;
done &amp;lt; &amp;#x2F;tmp&amp;#x2F;pkglist

cd &amp;#x2F;srv&amp;#x2F;localrepo
for deb in &amp;#x2F;tmp&amp;#x2F;debs&amp;#x2F;*.deb; do
    reprepro includedeb bookworm &amp;quot;$deb&amp;quot;
done

echo &amp;quot;deb [trusted=yes, arch=amd64] file:&amp;#x2F;&amp;#x2F;&amp;#x2F;srv&amp;#x2F;localrepo bookworm main&amp;quot; | sudo tee &amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;sources.list.d&amp;#x2F;localrepo.list

# 每次新增包都要
reprepro export
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;zi-dong-di-gui-la-qu-bao-ji-yi-lai-dao-ben-di-cang-ku&quot;&gt;自动递归拉取包及依赖到本地仓库&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 你也可以让 reprepro 自动“抓取”远程仓库的包 + 所有依赖：
sudo tee &amp;#x2F;srv&amp;#x2F;localrepo&amp;#x2F;conf&amp;#x2F;updates&amp;lt;&amp;lt;EOF
Name: debian
Suite: bookworm
Components: main
Architectures: amd64
VerifyRelease: false
Method: http:&amp;#x2F;&amp;#x2F;deb.debian.org&amp;#x2F;debian
EOF

# 然后：
reprepro update
# ⚠️ 但 reprepro update 会拉 component 的所有包，不适合最小仓库，所以推荐手动 includedeb。
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>配置ipv4 ipv6优先级</title>
        <published>2025-12-06T09:18:31+08:00</published>
        <updated>2025-12-06T09:18:31+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/12/配置ipv4 ipv6优先级/"/>
        <id>https://vercel.juzhong.xyz/2025/12/配置ipv4 ipv6优先级/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/12/配置ipv4 ipv6优先级/">&lt;h1 id=&quot;linuxxi-tong-zhong-de-ipxuan-ze&quot;&gt;linux系统中的ip选择&lt;&#x2F;h1&gt;
&lt;p&gt;在 Linux 系统中，默认情况下，许多应用（尤其是使用 glibc 的 getaddrinfo() 的程序，如 curl、wget、ssh 等）会遵循 RFC 6724 的地址选择策略，优先选择 IPv6（若 AAAA 记录存在且网络支持），即使 IPv4 可用。&lt;&#x2F;p&gt;
&lt;p&gt;要让系统&#x2F;应用优先使用 IPv4，再回退到 IPv6，有以下几种常用方法（按推荐程度排序）：&lt;&#x2F;p&gt;
&lt;h2 id=&quot;xiu-gai-gai-conf-quan-ju-biao-zhun-tui-jian&quot;&gt;修改 gai.conf（全局、标准、推荐）&lt;&#x2F;h2&gt;
&lt;p&gt;这是最标准、影响范围可控的方式，只影响使用 getaddrinfo() 的应用。&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo vim &amp;#x2F;etc&amp;#x2F;gai.conf
# 优先 IPv4（将 ::ffff:0:0&amp;#x2F;96 的优先级调高）
# precedence ::ffff:0:0&amp;#x2F;96  100
sudo sed -i &amp;#x27;s&amp;#x2F;#precedence ::ffff:0:0\&amp;#x2F;96  10&amp;#x2F;precedence ::ffff:0:0\&amp;#x2F;96  100&amp;#x2F;&amp;#x27; &amp;#x2F;etc&amp;#x2F;gai.conf
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;原理：::ffff:0:0&#x2F;96 是 IPv4-mapped IPv6 地址（如 ::ffff:192.0.2.1）。提高其优先级后，当域名同时有 A 和 AAAA 记录时，getaddrinfo() 会优先返回 IPv4 地址。&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 无需重启，新进程立即生效。
getent ahostsv4 example.com | head -1   # 应返回 IPv4
getent ahostsv6 example.com | head -1   # 应返回 IPv6
# 测试解析顺序（注意顺序）：
python3 -c &amp;quot;import socket; print(socket.getaddrinfo(&amp;#x27;example.com&amp;#x27;, 80, socket.AF_UNSPEC, socket.SOCK_STREAM))&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;huan-jing-bian-liang-yong-hu-ji-lin-shi&quot;&gt;环境变量（用户级&#x2F;临时）&lt;&#x2F;h2&gt;
&lt;p&gt;适用于特定用户或会话，不影响系统全局：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;export GAI_CONF=&amp;#x2F;dev&amp;#x2F;null  # 禁用 gai.conf（回退到旧行为，常优先 IPv4）
# 或更精准：
export GAI_CONF=&amp;lt;(echo &amp;quot;precedence ::ffff:0:0&amp;#x2F;96 100&amp;quot;)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;xiu-gai-nei-he-di-zhi-xuan-ze-ce-lue-tui-jian-xing-wei-zui-jie-jin-ipv4-first&quot;&gt;修改内核地址选择策略（推荐，行为最接近“IPv4 first”）&lt;&#x2F;h2&gt;
&lt;p&gt;Linux 使用 RFC 3484 &#x2F; RFC 6724 地址选择规则，可以通过 ip addrlabel 调整优先级，让 IPv4 地址的地址标签优先级更高。&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;➤ 查看当前地址标签：&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;ip addrlabel list
# 通常看到：
# prefix ::ffff:0.0.0.0&amp;#x2F;96 label 4
# prefix ::&amp;#x2F;0                label 1
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;其中 ::ffff:0.0.0.0&#x2F;96 是 IPv4-mapped IPv6 地址。&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;➤ 让 IPv4-mapped 更优先：&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo ip addrlabel add prefix ::ffff:0.0.0.0&amp;#x2F;96 label 0
# 让它的 label 更小 → 优先级更高。
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;➤ 或者反过来降低 IPv6 的优先级：&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo ip addrlabel add prefix ::&amp;#x2F;0 label 10
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;bu-tui-jian-de-fang-fa-fu-zuo-yong-da&quot;&gt;不推荐的方法（副作用大）&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;禁用 IPv6（如 sysctl net.ipv6.conf.all.disable_ipv6=1）：
&lt;ul&gt;
&lt;li&gt;虽可强制走 IPv4，但破坏 IPv6 功能，不符合现代网络趋势，且某些服务依赖 IPv6 localhost（如部分 Docker&#x2F;LXC 配置），可能导致意外故障。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;修改 &#x2F;etc&#x2F;hosts：
&lt;ul&gt;
&lt;li&gt;手动将域名映射到 IPv4 地址仅对特定主机名有效，不具普适性。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;addrlable-conf-he-gai-conf-de-qu-bie&quot;&gt;addrlable.conf 和gai.conf 的区别&lt;&#x2F;h1&gt;
&lt;p&gt;&#x2F;etc&#x2F;iproute2&#x2F;addrlabel.conf 和 &#x2F;etc&#x2F;gai.conf 都涉及 IP 地址优先级&#x2F;排序，但它们的工作层级、目标、机制截然不同。下面我们从原理、作用域、典型场景三方面对比：&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;维度&lt;&#x2F;th&gt;&lt;th&gt;&#x2F;etc&#x2F;gai.conf&lt;&#x2F;th&gt;&lt;th&gt;&#x2F;etc&#x2F;iproute2&#x2F;addrlabel.conf&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;标准依据&lt;&#x2F;td&gt;&lt;td&gt;RFC 6724&lt;&#x2F;td&gt;&lt;td&gt;RFC 6724 §2.1 + Linux 内核实现&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;作用对象&lt;&#x2F;td&gt;&lt;td&gt;✅ 用户空间应用（通过 getaddrinfo()）：&lt;br&gt;curl, wget, ssh, python socket, systemd-resolved 等&lt;&#x2F;td&gt;&lt;td&gt;✅ 内核空间（net&#x2F;ipv6&#x2F;addrlabel.c）：&lt;br&gt;影响 内核生成的源地址标签（label），供 getaddrinfo() 读取参考&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;控制什么&lt;&#x2F;td&gt;&lt;td&gt;应用层 地址排序规则（getaddrinfo() 的输出顺序）&lt;&#x2F;td&gt;&lt;td&gt;内核为每个 IPv6 地址分配的 label 值（ip addrlabel list 可见），是 gai.conf 中 label 规则的数据源&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;是否必须配合使用&lt;&#x2F;td&gt;&lt;td&gt;❌ 可独立工作（可仅靠 precedence 规则）&lt;&#x2F;td&gt;&lt;td&gt;⚠️ 通常需配合 gai.conf 的 label 规则才生效；单独修改它不直接改变应用行为&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;典型配置项&lt;&#x2F;td&gt;&lt;td&gt;precedence, label, scopev4&lt;&#x2F;td&gt;&lt;td&gt;prefix label（如 ::1&#x2F;128 0）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;生效方式&lt;&#x2F;td&gt;&lt;td&gt;应用启动时读取（或按 GAI_CONF 环境变量）&lt;&#x2F;td&gt;&lt;td&gt;ip addrlabel 加载；内核维护 label 表；getaddrinfo() 查询该表&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;etc-gai-conf-yong-hu-kong-jian-de-jue-ce-yin-qing&quot;&gt;&#x2F;etc&#x2F;gai.conf：用户空间的“决策引擎”&lt;&#x2F;h2&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>默认路由到旁路由</title>
        <published>2025-12-05T00:04:27+08:00</published>
        <updated>2025-12-05T00:04:27+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/12/默认路由到旁路由/"/>
        <id>https://vercel.juzhong.xyz/2025/12/默认路由到旁路由/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/12/默认路由到旁路由/">&lt;h1 id=&quot;zhi-jie-xiu-gai-mo-ren-lu-you&quot;&gt;直接修改默认路由&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 目标机器修改默认路由
sudo ip route replace default via 172.17.66.222 dev enp125s0f3

# 旁路由开启路由转发
sysctl -w net.ipv4.ip_forward=1
sysctl -w &amp;#x27;net.ipv4.ip_forward = 1&amp;#x27;
sudo iptables -P FORWARD ACCPET
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;pei-zhi-ce-lue-lu-you&quot;&gt;配置策略路由&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# echo &amp;quot;2000 tor&amp;quot; &amp;gt;&amp;gt; &amp;#x2F;etc&amp;#x2F;iproute2&amp;#x2F;rt_tables     # 添加了这个映射后，table可以使用tor名称指定
ip route add default via 192.168.10.10 table 2000 

# 匹配所有流量到main表，但是不包括前缀是0的路由（即不匹配main中的默认路由）
sudo ip rule add priority 5000 table main suppress_prefixlength 0
# 如果不加 not iif lo，本机产生的流量（如 curl localhost）也会查表 2000，可能导致无法访问 127.0.0.1??
# 测试添加了not iif lo 本机器产生的所有流量都不匹配这个流量了？？
sudo ip rule add priority 5001 from all lookup 2000
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;pei-zhi-dns&quot;&gt;配置dns&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo tee -a &amp;#x2F;etc&amp;#x2F;systemd&amp;#x2F;resolved.conf&amp;lt;&amp;lt;EOF
DNS=223.5.5.5 8.8.8.8 8.8.4.4
FallbackDNS=1.1.1.1 1.0.0.1
# DNSStubListener=no
EOF

sudo systemctl restart systemd-resolved.service
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>uefi 安装启动</title>
        <published>2025-11-28T17:37:06+08:00</published>
        <updated>2025-11-28T17:37:06+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/11/uefi 安装启动/"/>
        <id>https://vercel.juzhong.xyz/2025/11/uefi 安装启动/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/11/uefi 安装启动/">&lt;h1 id=&quot;secure-boot-de-qian-ming-lian-pk-kek-db-zhong-de-ge-zi-de-zuo-yong&quot;&gt;Secure Boot 的签名链（PK&#x2F;KEK&#x2F;DB） 中的各自的作用？&lt;&#x2F;h1&gt;
&lt;p&gt;结合完整的 Secure Boot 启动链（shim → grub → kernel） 进行详细的解释&lt;&#x2F;p&gt;
&lt;h1 id=&quot;xin-ren-lian-de-gen-yuan-oem-gu-jian&quot;&gt;信任链的根源 (OEM&#x2F;固件)&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;首先，UEFI 安全启动的信任链始于固件（BIOS&#x2F;UEFI）。固件中预先存储了三个关键的密钥数据库：&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;平台密钥 (PK - Platform Key): 最高级的密钥，用于签署 KEK 的更新。由 PC 制造商 (OEM) 负责管理。&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;密钥交换密钥 (KEK - Key Exchange Key): 用于签署签名数据库 (db) 和禁止签名数据库 (dbx) 的更新。&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;签名数据库 (db - Signature Database): 包含了被允许执行的操作系统引导加载程序、驱动程序等组件的公钥或证书。&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;初始状态下，这个 db 数据库中通常包含：&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;OEM 自己的证书： 用于验证固件更新和 OEM 自己的工具。&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Microsoft Corporation UEFI CA 证书： 允许启动所有由微软签名的组件，包括 Windows 启动管理器以及由微软服务签名的第三方引导加载程序。&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;UEFI 固件内部存有四类关键数据库：&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;名称&lt;&#x2F;th&gt;&lt;th&gt;类型&lt;&#x2F;th&gt;&lt;th&gt;主要作用&lt;&#x2F;th&gt;&lt;th&gt;由谁管理&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;PK（Platform Key）&lt;&#x2F;td&gt;&lt;td&gt;公开证书 + 私钥在厂商手上&lt;&#x2F;td&gt;&lt;td&gt;管理平台最顶层权限（用来更新 KEK）&lt;&#x2F;td&gt;&lt;td&gt;OEM（华硕、联想等）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;KEK（Key Exchange Key）&lt;&#x2F;td&gt;&lt;td&gt;公开证书&lt;&#x2F;td&gt;&lt;td&gt;用来更新 DB &#x2F; DBX&lt;&#x2F;td&gt;&lt;td&gt;OEM、Microsoft&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;DB（Allowed Signatures）允许列表&lt;&#x2F;td&gt;&lt;td&gt;证书 + Hash&lt;&#x2F;td&gt;&lt;td&gt;允许启动的 EFI 程序的签名&lt;&#x2F;td&gt;&lt;td&gt;Microsoft（多数 PC），OEM，用户&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;DBX（Forbidden Signatures）禁止列表&lt;&#x2F;td&gt;&lt;td&gt;证书 + Hash&lt;&#x2F;td&gt;&lt;td&gt;被吊销&#x2F;恶意的 EFI 程序摘要&lt;&#x2F;td&gt;&lt;td&gt;Microsoft&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Secure Boot 的工作原则：UEFI 只允许 DB 中签名的文件启动，禁止 DBX 中的文件。&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;UEFI 会从 DB&#x2F;DBX 中取证书来验证 shim 的签名&lt;&#x2F;li&gt;
&lt;li&gt;shim.efi 验证 grubx64.efi（第二级验证）
&lt;ul&gt;
&lt;li&gt;shim 内置了一个 shim-own certificate (MOK)
&lt;ul&gt;
&lt;li&gt;→ 是从 Linux 发行版（或用户）生成的&lt;&#x2F;li&gt;
&lt;li&gt;→ 不需要微软参与&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;所以 shim 的验证过程：
&lt;ul&gt;
&lt;li&gt;shim 内的 MOK 列表（Machine Owner Keys）
↓ 验证 grub 是否被 MOK 签名
grub 才能启动&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;shim 的最大用途：让 Linux 自己管理信任链，而不依赖微软。&lt;&#x2F;li&gt;
&lt;li&gt;用户也可以加入自己的 MOK（mokutil --import）这样用户可以签：
&lt;ul&gt;
&lt;li&gt;grub&lt;&#x2F;li&gt;
&lt;li&gt;kernel&lt;&#x2F;li&gt;
&lt;li&gt;initrd&lt;&#x2F;li&gt;
&lt;li&gt;甚至自己写的 EFI 程序&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;grubx64.efi 验证 Linux kernel（第三级验证）
&lt;ul&gt;
&lt;li&gt;使用 shim 提供的验证接口（shim_lock）
&lt;ul&gt;
&lt;li&gt;↓ 验证 kernel 是否被 MOK（DB）签名&lt;&#x2F;li&gt;
&lt;li&gt;kernel 才能加载&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;通常：
&lt;ul&gt;
&lt;li&gt;在 Ubuntu &#x2F; Debian，kernel 已经用 Canonical 的私钥签名（内置在 shim MOK 内）&lt;&#x2F;li&gt;
&lt;li&gt;在 Fedora，kernel 用 Red Hat 的私钥签名&lt;&#x2F;li&gt;
&lt;li&gt;所以 grub加载内核时会调用 shim 的验证函数：&lt;&#x2F;li&gt;
&lt;li&gt;verify_pe_signature()&lt;&#x2F;li&gt;
&lt;li&gt;决定内核是否可信。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;wei-ruan-de-jiao-se-shang-ye-gong-si-de-dai-li-qian-ming&quot;&gt;微软的角色：商业公司的“代理签名”&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;微软确实在为其他商业公司签名方面扮演了核心角色，但不是直接负责。&lt;&#x2F;li&gt;
&lt;li&gt;机制： 微软提供了一个 UEFI CA (Certificate Authority) 证书，这个证书被全球几乎所有 OEM 预装在了 UEFI 固件的 db 数据库中。&lt;&#x2F;li&gt;
&lt;li&gt;服务： 许多第三方操作系统供应商或硬件&#x2F;驱动程序制造商（如主流的 Linux 发行版，如 Canonical&#x2F;Ubuntu、Red Hat 等）为了让他们的启动文件能在一台开启了安全启动的 Windows 电脑上运行，会向微软的 硬件仪表板（Hardware Dashboard） 提交他们的启动文件（例如 Linux 的 shim.efi）。&lt;&#x2F;li&gt;
&lt;li&gt;签名： 微软使用自己的 Microsoft UEFI CA 证书的私钥，为这些第三方文件进行数字签名。&lt;&#x2F;li&gt;
&lt;li&gt;结果： 固件检查启动文件时，发现它是由 Microsoft UEFI CA 签名的，而这个 CA 证书在 db 数据库中是被信任的，因此允许启动。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;zi-ji-qian-ming-secure-boot-de-shi-ji-liu-cheng-wan-zheng-bu-zou&quot;&gt;自己签名 Secure Boot 的实际流程（完整步骤）&lt;&#x2F;h1&gt;
&lt;p&gt;下面是 Linux 下常见的方式（OpenSSL + sbsigntools）：&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sheng-cheng-san-tao-mi-yao-pk-kek-db&quot;&gt;① 生成三套密钥（PK&#x2F;KEK&#x2F;DB）&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;openssl req -new -x509 -newkey rsa:2048 -sha256 -keyout PK.key -out PK.crt -subj &amp;quot;&amp;#x2F;CN=Custom PK&amp;#x2F;&amp;quot; -days 3650
openssl req -new -x509 -newkey rsa:2048 -sha256 -keyout KEK.key -out KEK.crt -subj &amp;quot;&amp;#x2F;CN=Custom KEK&amp;#x2F;&amp;quot; -days 3650
openssl req -new -x509 -newkey rsa:2048 -sha256 -keyout DB.key -out DB.crt -subj &amp;quot;&amp;#x2F;CN=Custom DB&amp;#x2F;&amp;quot; -days 3650
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;sheng-cheng-uefi-ke-shi-bie-de-auth-wen-jian&quot;&gt;② 生成 UEFI 可识别的 .auth 文件&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;cert-to-efi-sig-list -g &amp;quot;$(uuidgen)&amp;quot; PK.crt PK.esl
sign-efi-sig-list -k PK.key -c PK.crt PK PK.esl PK.auth
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;KEK&#x2F;DB 同理。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;jin-ru-bios-qie-huan-dao-custom-secure-boot&quot;&gt;③ 进入 BIOS，切换到 Custom Secure Boot&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text &quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;大多数设备 BIOS 中选择：
Secure Boot → Custom Mode
然后可以导入你的 PK.auth, KEK.auth, DB.auth
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;shi-yong-ni-de-db-si-yao-qian-ming-yin-dao-cheng-xu&quot;&gt;④ 使用你的 DB 私钥签名引导程序&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text &quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;例如对 GRUB2 EFI 文件签名：
sbsign --key DB.key --cert DB.crt --output grubx64.efi grubx64.efi
然后用这个签名过的 grubx64.efi 启动即可。
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>为什么ssh长时间空闲后，终端就卡死了</title>
        <published>2025-11-27T19:21:20+08:00</published>
        <updated>2025-11-27T19:21:20+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/11/为什么ssh长时间空闲后，终端就卡死了/"/>
        <id>https://vercel.juzhong.xyz/2025/11/为什么ssh长时间空闲后，终端就卡死了/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/11/为什么ssh长时间空闲后，终端就卡死了/">&lt;h1 id=&quot;wen-ti-yuan-yin&quot;&gt;问题原因&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;SSH 连接在长时间空闲后“卡死”（表现为终端无响应、输入无回显、Ctrl+C 无效等），\&lt;&#x2F;li&gt;
&lt;li&gt;通常不是 SSH 协议本身“卡”了，而是连接被中间网络设备（如 NAT 网关、防火墙）静默丢弃所致。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;ju-ti-fen-xi&quot;&gt;具体分析&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;TCP 连接超时被中间设备丢弃
&lt;ul&gt;
&lt;li&gt;多数 NAT 路由器或云服务商（如 AWS、阿里云）的防火墙&#x2F;安全组默认 TCP 空闲超时时间为 5–15 分钟（例如 AWS 默认 350 秒）。&lt;&#x2F;li&gt;
&lt;li&gt;若 SSH 会话长时间无数据包交换（即使你在终端看着 htop 不动也算“空闲”），中间设备会悄悄丢弃连接状态，但不向两端发送 RST&#x2F;FIN。&lt;&#x2F;li&gt;
&lt;li&gt;此时：
&lt;ul&gt;
&lt;li&gt;客户端仍以为连接 alive，输入无响应（包发出去但被丢，无 ACK）；&lt;&#x2F;li&gt;
&lt;li&gt;服务端也无感知，直到尝试写数据才发现对端已不可达（但可能延迟很久）。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;服务端或客户端的 TCP keepalive 默认关闭或间隔太长
&lt;ul&gt;
&lt;li&gt;Linux 默认的 TCP keepalive 是 net.ipv4.tcp_keepalive_time = 7200 秒（2 小时），远晚于中间设备的超时。&lt;&#x2F;li&gt;
&lt;li&gt;所以 keepalive 包来不及发送，连接已被丢弃。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;终端控制字符阻塞（较少见）
&lt;ul&gt;
&lt;li&gt;如误按 Ctrl+S（XOFF 流控），导致终端本地“卡住”，但此情况可通过 Ctrl+Q 解除，且不影响 SSH 底层连接。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;jie-jue-fang-an-tui-jian-zu-he-shi-yong&quot;&gt;解决方案（推荐组合使用）&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;qi-yong-ssh-ke-hu-duan-bao-huo-zui-chang-yong&quot;&gt;启用 SSH 客户端保活（最常用）&lt;&#x2F;h2&gt;
&lt;p&gt;在 客户端 的 ~&#x2F;.ssh&#x2F;config 中为对应主机配置：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;yaml&quot; class=&quot;language-yaml &quot;&gt;&lt;code class=&quot;language-yaml&quot; data-lang=&quot;yaml&quot;&gt;Host your-server  # 或 * 表示全局
    HostName example.com
    User peter
    ServerAliveInterval 60      # 每60秒客户端发一个空包探测
    ServerAliveCountMax 3       # 连续3次无响应则断开
    TCPKeepAlive yes            # 同时启用底层 TCP keepalive（可选）
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;✅ 效果：每 60 秒发一次 SSH_MSG_CHANNEL_REQUEST &quot;keepalive@openssh.com&quot;，穿透 NAT 设备，防止被丢弃。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;fu-wu-duan-bao-huo-xu-you-fu-wu-qi-quan-xian&quot;&gt;服务端保活（需有服务器权限）&lt;&#x2F;h2&gt;
&lt;p&gt;在服务端 &#x2F;etc&#x2F;ssh&#x2F;sshd_config 中添加：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;yaml&quot; class=&quot;language-yaml &quot;&gt;&lt;code class=&quot;language-yaml&quot; data-lang=&quot;yaml&quot;&gt;ClientAliveInterval 60
ClientAliveCountMax 3
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;重启 sshd：sudo systemctl restart sshd&lt;&#x2F;p&gt;
&lt;p&gt;⚠️ 注意：若中间设备超时 &amp;lt; 60 秒（如某些企业防火墙为 30 秒），可设为 30。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;xi-tong-ji-tcp-keepalive-diao-you-quan-ju-sheng-xiao&quot;&gt;系统级 TCP keepalive 调优（全局生效）&lt;&#x2F;h2&gt;
&lt;p&gt;临时调整（重启失效）：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# Debian&amp;#x2F;Ubuntu
sudo sysctl -w net.ipv4.tcp_keepalive_time=300
sudo sysctl -w net.ipv4.tcp_keepalive_intvl=60
sudo sysctl -w net.ipv4.tcp_keepalive_probes=3
# 永久生效：写入 &amp;#x2F;etc&amp;#x2F;sysctl.d&amp;#x2F;99-tcp-keepalive.conf
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;zhen-duan-ji-qiao&quot;&gt;诊断技巧&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;检查是否真“卡”：另开终端 ping your-server。若 ping 通但 SSH 卡住 → 确认为 SSH 连接被丢弃。&lt;&#x2F;li&gt;
&lt;li&gt;查看 SSH 日志（服务端）：journalctl -u ssh -f&lt;&#x2F;li&gt;
&lt;li&gt;抓包验证：sudo tcpdump -i any host your-server and port 22，看是否有 keepalive 包。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>为什么tcpdump抓包tcp校验和不对</title>
        <published>2025-11-27T19:11:03+08:00</published>
        <updated>2025-11-27T19:11:03+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/11/为什么tcpdump抓包tcp校验和不对/"/>
        <id>https://vercel.juzhong.xyz/2025/11/为什么tcpdump抓包tcp校验和不对/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/11/为什么tcpdump抓包tcp校验和不对/">&lt;h1 id=&quot;tcpdump-zhua-bao-tcpxiao-yan-he-cuo-wu-checksum-incorrect&quot;&gt;tcpdump 抓包tcp校验和错误 (checksum incorrect)&lt;&#x2F;h1&gt;
&lt;p&gt;cksum 0x7f33 (incorrect -&amp;gt; 0x3a5e) 表示校验和计算错误&lt;&#x2F;p&gt;
&lt;p&gt;这通常是 校验和卸载 (Checksum Offloading) 导致的&lt;&#x2F;p&gt;
&lt;p&gt;网卡在硬件层面计算校验和，但抓包时数据包还在内核队列中，校验和尚未计算&lt;&#x2F;p&gt;
&lt;h1 id=&quot;jie-jue-fang-an&quot;&gt;解决方案&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;jin-yong-xiao-yan-he-xie-zai-tui-jian&quot;&gt;禁用校验和卸载（推荐）&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 临时禁用 TX 校验和卸载
sudo ethtool -K enp0s31f6 tx off
# 临时禁用 RX 校验和卸载  
sudo ethtool -K enp0s31f6 rx off
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;tcpdump-hu-lue-xiao-yan-he-cuo-wu&quot;&gt;tcpdump 忽略校验和错误&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo tcpdump -i enp0s31f6 -v -n not tcp port 22  # 忽略校验和警告
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;yong-jiu-jin-yong-xiao-yan-he-xie-zai&quot;&gt;永久禁用校验和卸载&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;ethtool -K enp0s31f6 tx off rx off
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>sing-box旁路由配置</title>
        <published>2025-11-26T22:14:25+08:00</published>
        <updated>2025-11-26T22:14:25+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/11/sing-box旁路由配置/"/>
        <id>https://vercel.juzhong.xyz/2025/11/sing-box旁路由配置/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/11/sing-box旁路由配置/">&lt;h1 id=&quot;pang-lu-you&quot;&gt;旁路由&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 开启流量转发
echo &amp;quot;net.ipv4.ip_forward = 1&amp;quot; &amp;gt;&amp;gt; &amp;#x2F;etc&amp;#x2F;sysctl.d&amp;#x2F;90-override.conf

# 流量转发设备建议设置 default_qdisc 为 fq_codel，详细信息可以阅读：https:&amp;#x2F;&amp;#x2F;www.starduster.me&amp;#x2F;2020&amp;#x2F;03&amp;#x2F;02&amp;#x2F;linux-network-tuning-kernel-parameter&amp;#x2F;#netcoredefault_qdisc
echo &amp;quot;net.core.default_qdisc = fq_codel&amp;quot; &amp;gt;&amp;gt; &amp;#x2F;etc&amp;#x2F;sysctl.d&amp;#x2F;90-override.conf

# 用于控制反向路径过滤（Reverse Path Filtering）的一个内核参数，它决定了系统如何处理进入的数据包的源地址校验。
# 如果命令 sysctl -a | grep &amp;#x27;\.rp_filter&amp;#x27; 输出中你的网卡对应的值是 2 ，则需要重新覆盖设置为 0。
# 0：表示不开启源地址校验。系统不会检查进入的数据包的源地址，即使数据包的源地址不可达，也不会被系统丢弃。
# 1：表示开启严格的反向路径校验。系统会检查每个进入的数据包，确保其反向路径是最佳路径。如果不是，数据包将被丢弃。
# 2：表示开启松散的反向路径校验。系统会检查进入的数据包的源地址是否可达，即反向路径是否能通（通过任意网络接口）。如果反向路径不通，数据包将被丢弃。
echo &amp;quot;net.ipv4.conf.default.rp_filter = 0&amp;quot; &amp;gt;&amp;gt; &amp;#x2F;etc&amp;#x2F;sysctl.d&amp;#x2F;90-override.conf
echo &amp;quot;net.ipv4.conf.*.rp_filter = 0&amp;quot; &amp;gt;&amp;gt; &amp;#x2F;etc&amp;#x2F;sysctl.d&amp;#x2F;90-override.conf

# 使设置生效
sysctl --system
sysctl -p

sysctl -w net.ipv4.ip_forward=1
# iptables -t nat -A POSTROUTING -o &amp;lt;external_interface&amp;gt; -j MASQUERADE
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;snat&quot;&gt;SNAT&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;MASQUERADE 是 SNAT 的一个特例，主要区别在于目标源IP地址的获取方式。&lt;&#x2F;li&gt;
&lt;li&gt;SNAT 需要明确指定一个固定的IP地址或地址范围，而 MASQUERADE 则会自动从网卡上获取当前的IP地址。&lt;&#x2F;li&gt;
&lt;li&gt;因此，MASQUERADE 特别适用于IP地址是动态分配（如PPPoE拨号或DHCP）的场景，因为它不需要每次IP地址变化后都手动修改规则。&lt;&#x2F;li&gt;
&lt;li&gt;MASQUERADE 的效率稍低于 SNAT，因为它每次都需要查找可用的IP地址，而 SNAT 使用的IP地址是预先配置好的。&lt;&#x2F;li&gt;
&lt;li&gt;但在大多数情况下，这种性能差异非常微小，不会造成明显影响。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;zhu-ji-pei-zhi&quot;&gt;主机配置&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# lookup 是 table 的同义关键字（alias），源自早期 iproute2 的设计兼容性
# lookup 是历史遗留别名，虽可用，但新脚本建议统一用 table 避免歧义

# 使用main进行路由，且非main中默认路由的流量, 即直连网段的主机
sudo ip rule add priority 5000 from all table main suppress_prefixlength 0  
# main路由表未匹配的流量(main中原来需要走默认路由的流量), 即非直连网段的主机
sudo ip rule add priority 5001 from all table 5001
# 配置所有非直连网段的默认路由
sudo ip route add default via 192.168.66.1 dev enp3s0 proto static table 5001
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>ssh配置</title>
        <published>2025-11-26T11:16:39+08:00</published>
        <updated>2025-11-26T11:16:39+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/11/ssh配置/"/>
        <id>https://vercel.juzhong.xyz/2025/11/ssh配置/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/11/ssh配置/">&lt;h1 id=&quot;pei-zhi-yi-ge-jumperyong-hu&quot;&gt;配置一个jumper用户&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo useradd -m peter.jumper
sudo passwd peter.jumper
# 禁止用户登录
# 使用usermod命令
sudo usermod -s &amp;#x2F;sbin&amp;#x2F;nologin username
# 或使用chsh命令
sudo chsh -s &amp;#x2F;sbin&amp;#x2F;nologin username
# 直接编辑&amp;#x2F;etc&amp;#x2F;passwd文件
sudo vipw
# 找到对应用户行，将shell改为&amp;#x2F;sbin&amp;#x2F;nologin
# 锁定用户（会在密码前加!使其失效）
sudo usermod -L username
sudo passwd -l username
# 解锁用户
sudo usermod -U username
sudo passwd -u username
# 立即使用户账户过期
sudo usermod -e 1 username
# 设置特定过期日期
sudo usermod -e 2024-12-31 username
# 查看账户过期信息
sudo chage -l username

# 公钥登录
sudo -u peter.jumper mkdir -p &amp;#x2F;home&amp;#x2F;peter.jumper&amp;#x2F;.ssh
sudo -u peter.jumper chmod 700 &amp;#x2F;home&amp;#x2F;peter.jumper&amp;#x2F;.ssh
echo &amp;quot;粘贴您的公钥内容到这里&amp;quot; | sudo -u peter.jumper tee -a &amp;#x2F;home&amp;#x2F;peter.jumper&amp;#x2F;.ssh&amp;#x2F;authorized_keys
sudo -u peter.jumper chmod 600 &amp;#x2F;home&amp;#x2F;peter.jumper&amp;#x2F;.ssh&amp;#x2F;authorized_keys
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;sshd-config&quot;&gt;sshd_config&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;ini&quot; class=&quot;language-ini &quot;&gt;&lt;code class=&quot;language-ini&quot; data-lang=&quot;ini&quot;&gt;AllowUsers peter.jumper peter@192.168.1.*
AllowUsers peter@localhost peter@127.0.0.*
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;ssh-audit&quot;&gt;ssh-audit&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;pip3 install ssh-audit
ssh-audit server.com

sudo sshd -T
ssh -Q &amp;lt;Tab&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>常用网络工具</title>
        <published>2025-11-25T18:52:43+08:00</published>
        <updated>2025-11-25T18:52:43+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/11/常用网络工具/"/>
        <id>https://vercel.juzhong.xyz/2025/11/常用网络工具/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/11/常用网络工具/">&lt;h1 id=&quot;chang-yong-wang-luo-gong-ju&quot;&gt;常用网络工具&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;ping&lt;&#x2F;li&gt;
&lt;li&gt;curl&lt;&#x2F;li&gt;
&lt;li&gt;httpie&lt;&#x2F;li&gt;
&lt;li&gt;wget&lt;&#x2F;li&gt;
&lt;li&gt;tc&lt;&#x2F;li&gt;
&lt;li&gt;dig&#x2F;nslookup&lt;&#x2F;li&gt;
&lt;li&gt;whois&lt;&#x2F;li&gt;
&lt;li&gt;ssh&#x2F;scp&#x2F;rsync&lt;&#x2F;li&gt;
&lt;li&gt;ngrep 抓包grep命令的网络版&lt;&#x2F;li&gt;
&lt;li&gt;tcpdump&#x2F;wireshark&#x2F;tshark&lt;&#x2F;li&gt;
&lt;li&gt;tcpflow 捕获和重组TCP连接中的数据流&lt;&#x2F;li&gt;
&lt;li&gt;ifconfig&#x2F;route&lt;&#x2F;li&gt;
&lt;li&gt;ip&#x2F;arp&lt;&#x2F;li&gt;
&lt;li&gt;mitmproxy 中间人代理工具拦截修改观察流量&lt;&#x2F;li&gt;
&lt;li&gt;nmap 网络探测和安全审核工具&lt;&#x2F;li&gt;
&lt;li&gt;zenmap 图形界面管理和执行网络扫描任务&lt;&#x2F;li&gt;
&lt;li&gt;p0f 被动操作系统指纹识别网络流量分析工具&lt;&#x2F;li&gt;
&lt;li&gt;openvpn&#x2F;wiregaurd&lt;&#x2F;li&gt;
&lt;li&gt;nc&#x2F;socat&#x2F;telnet 数据传输和处理&lt;&#x2F;li&gt;
&lt;li&gt;ftp&#x2F;sftp&lt;&#x2F;li&gt;
&lt;li&gt;nestat&#x2F;ss&#x2F;lsof&lt;&#x2F;li&gt;
&lt;li&gt;iptables&#x2F;nftables&lt;&#x2F;li&gt;
&lt;li&gt;hping3 生成解析TCP&#x2F;IP协议 数据包 也是安全审计、防火墙测试工具&lt;&#x2F;li&gt;
&lt;li&gt;traceroute&#x2F;mtr&lt;&#x2F;li&gt;
&lt;li&gt;tcptraceroute 使用tcp协议进行路径跟踪&lt;&#x2F;li&gt;
&lt;li&gt;ethtool 查看和修改网络设备的驱动参数和硬件设置&lt;&#x2F;li&gt;
&lt;li&gt;iw&#x2F;iwconfig 配置和管理无线网络接口&lt;&#x2F;li&gt;
&lt;li&gt;sysctl 运行时配置内核参数&lt;&#x2F;li&gt;
&lt;li&gt;openssl&lt;&#x2F;li&gt;
&lt;li&gt;stunnel 开源跨平台进行通信加密&lt;&#x2F;li&gt;
&lt;li&gt;iptraf&#x2F;nethogs&#x2F;iftop&#x2F;ntop 网络流量监控&lt;&#x2F;li&gt;
&lt;li&gt;ab&#x2F;nload&#x2F;iperf3 网络性能测试和监控&lt;&#x2F;li&gt;
&lt;li&gt;python3 -m http.server&lt;&#x2F;li&gt;
&lt;li&gt;ipcalc 简单的ip地址计算&lt;&#x2F;li&gt;
&lt;li&gt;nsenter 进入指定进程命令空间下运行执行程序&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>qemu-user 启动失败排查</title>
        <published>2025-11-25T14:24:49+08:00</published>
        <updated>2025-11-25T14:24:49+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/11/qemu-user 启动失败排查/"/>
        <id>https://vercel.juzhong.xyz/2025/11/qemu-user 启动失败排查/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/11/qemu-user 启动失败排查/">&lt;h1 id=&quot;fuzzmo-hu-ce-shi-shi-yong-afl-qemu-trace-shi-bai&quot;&gt;fuzz模糊测试使用afl qemu trace 失败&lt;&#x2F;h1&gt;
&lt;p&gt;怀疑是环境变量导致额的， 最后定位到环境变量&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;...
&amp;quot;-E&amp;quot; &amp;quot;TMUX=&amp;#x2F;tmp&amp;#x2F;tmux-1000&amp;#x2F;default,18190,1&amp;quot; 
...
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;实验发现，是环境变量中的值存在‘，’ 就会启动失败&lt;&#x2F;p&gt;
&lt;p&gt;去掉&#x27;,&#x27;， 是可以正常启动的&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;...
&amp;quot;-E&amp;quot; &amp;quot;TMUX=&amp;#x2F;tmp&amp;#x2F;tmux-1000&amp;#x2F;default&amp;quot; 
...

# 或者
unset TMUX
unset no_proxy
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>apt 中的keyrings(gpg)</title>
        <published>2025-11-25T10:59:41+08:00</published>
        <updated>2025-11-25T10:59:41+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/11/apt 中的keyrings(gpg)/"/>
        <id>https://vercel.juzhong.xyz/2025/11/apt 中的keyrings(gpg)/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/11/apt 中的keyrings(gpg)/">&lt;h1 id=&quot;apt-gpg-zuo-yong&quot;&gt;apt gpg 作用&lt;&#x2F;h1&gt;
&lt;p&gt;在 APT 的工作流程中，GPG 签名验证（signed-by= 指定的公钥）是在 “获取 Release 文件并校验其完整性与真实性” 阶段起作用的，具体发生在 apt update 的早期阶段，早于包列表下载和安装决策。&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;解析 sources.list ，识别源 URL 和组件 ( bookworm , stable)&lt;&#x2F;li&gt;
&lt;li&gt;下载 InRelease 或 Release + Release.gpg 文件： → https:&#x2F;&#x2F;download.docker.com&#x2F;linux&#x2F;debian&#x2F;dists&#x2F;bookworm&#x2F;InRelease
或 → ...&#x2F;Release + ...&#x2F;Release.gpg 关键阶段&lt;&#x2F;li&gt;
&lt;li&gt;用 &#x2F;etc&#x2F;apt&#x2F;keyrings&#x2F;docker.asc 中的公钥验证 InRelease&#x2F;Release.gpg 签名 ️ GPG 认证生效点&lt;&#x2F;li&gt;
&lt;li&gt;若验证失败 → 立即报错退出 （如 NO_PUBKEY , GPG error , signature invalid ）&lt;&#x2F;li&gt;
&lt;li&gt;若验证成功 → 解析 Release 文件中的 SHA256 &#x2F; SHA512 校验和 （哈希校验，非 GPG）&lt;&#x2F;li&gt;
&lt;li&gt;下载 Packages.gz 等索引文件，并用 Release 中的哈希值校验完整性&lt;&#x2F;li&gt;
&lt;li&gt;建立本地包数据库（ &#x2F;var&#x2F;lib&#x2F;apt&#x2F;lists&#x2F;...  ）&lt;&#x2F;li&gt;
&lt;li&gt;apt install 时仅校验 .deb 包哈希（来自 Packages ）， 不再 GPG 验证&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 1. 故意破坏签名验证（删掉 keyring）
sudo rm &amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;keyrings&amp;#x2F;docker.asc
sudo apt update 2&amp;gt;&amp;amp;1 | grep -A2 -B2 &amp;quot;GPG\|NO_PUBKEY&amp;quot;
# → 报错：The following signatures couldn&amp;#x27;t be verified...
# 2. 或临时禁用验证（危险！仅测试）
sudo apt -o Acquire::Check-Valid-Until=false \
         -o Acquire::AllowInsecureRepositories=true \
         -o Acquire::AllowDowngradeToInsecureRepositories=true \
         update

# → 仍可能失败，因为 signed-by 指定了强制 key，除非改 sources.list 去掉 signed-by
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;shi-yong-jing-xiang-yuan-mirror-de-apt-fu-wu-huan-neng-zheng-chang-gpg-ren-zheng-ma&quot;&gt;使用镜像源（mirror）的 APT 服务，还能正常 GPG 认证吗？&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;可以，只要镜像同步了完整的 dists&#x2F; 目录（含 InRelease &#x2F; Release + Release.gpg）——绝大多数合规镜像都做到了。&lt;&#x2F;li&gt;
&lt;li&gt;APT 的 GPG 校验不依赖源服务器域名&#x2F;IP，只校验：
文件内容是否被篡改（哈希匹配）
Release 文件是否由可信私钥签名（GPG 签名校验）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;yan-zheng-shi-cao-tui-jian&quot;&gt;验证实操（推荐）&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 1. 下载 InRelease（中科大镜像）
wget https:&amp;#x2F;&amp;#x2F;mirrors.ustc.edu.cn&amp;#x2F;docker-ce&amp;#x2F;linux&amp;#x2F;debian&amp;#x2F;dists&amp;#x2F;bookworm&amp;#x2F;InRelease

# 2. 用你本地的 docker.asc 公钥验证
gpg --keyring &amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;keyrings&amp;#x2F;docker.asc \
    --verify InRelease
# 应输出：Good signature from &amp;quot;Docker Release (CE deb) ...&amp;quot;

# 3. 对比原始源（应完全一致）
diff InRelease \
  &amp;lt;(curl -s https:&amp;#x2F;&amp;#x2F;download.docker.com&amp;#x2F;linux&amp;#x2F;debian&amp;#x2F;dists&amp;#x2F;bookworm&amp;#x2F;InRelease)
# → 无输出（完全相同）
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;bao-cuo-pai-cha&quot;&gt;报错排查&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text &quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;gpg: [don&amp;#x27;t know]: invalid packet (ctb=2d)
gpg: keydb_search failed: 无效的数据包
gpg: 无法检查签名：缺少公钥
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;诊断依据
你从 https:&#x2F;&#x2F;download.docker.com&#x2F;linux&#x2F;debian&#x2F;gpg 下载的 gpg 文件（3.7KB）是 ASCII-armored 公钥&lt;&#x2F;li&gt;
&lt;li&gt;但 --keyring &#x2F;path&#x2F;to&#x2F;file 默认期望的是 二进制格式的 keyring（或 GnuPG native keybox）&lt;&#x2F;li&gt;
&lt;li&gt;当你直接把 ASCII-armored .asc 传给 --keyring，GPG 会把它当二进制解析 → 遇到 -----BEGIN 这种文本头 → 解析为“无效数据包”（ctb=2d 是 0x2d = &#x27;-&#x27; 字符）→ 失败 ❌&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;xian-dearmor-cheng-er-jin-zhi-zai-yan-zheng-tui-jian&quot;&gt;先 dearmor 成二进制，再验证（推荐）&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 1. 确保 docker.asc 是 ASCII-armored（检查开头）
head -n2 &amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;keyrings&amp;#x2F;docker.asc
# 应输出：-----BEGIN PGP PUBLIC KEY BLOCK-----
# 2. 转成二进制格式（例如 docker.gpg）
sudo gpg --dearmor -o &amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;keyrings&amp;#x2F;docker.gpg &amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;keyrings&amp;#x2F;docker.asc
# 3. 用 .gpg（二进制）验证
gpg --keyring &amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;keyrings&amp;#x2F;docker.gpg \
    --verify .&amp;#x2F;InRelease
# ✅ 此时应显示：Good signature from &amp;quot;Docker Release (CE deb)...&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;bu-zhi-ding-keyring-er-shi-xian-dao-ru-gong-yao-dao-lin-shi-keyring&quot;&gt;不指定 --keyring，而是先导入公钥到临时 keyring&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 创建临时 home
mkdir -p &amp;#x2F;tmp&amp;#x2F;gpghome &amp;amp;&amp;amp; chmod 700 &amp;#x2F;tmp&amp;#x2F;gpghome
# 导入公钥（自动 dearmor）
gpg --homedir &amp;#x2F;tmp&amp;#x2F;gpghome --import &amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;keyrings&amp;#x2F;docker.asc
# 用临时 keyring 验证
gpg --homedir &amp;#x2F;tmp&amp;#x2F;gpghome --verify .&amp;#x2F;InRelease
# 清理
rm -rf &amp;#x2F;tmp&amp;#x2F;gpghome
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;wei-shen-me-apt-ben-shen-neng-gong-zuo&quot;&gt;为什么 apt 本身能工作？&lt;&#x2F;h2&gt;
&lt;p&gt;因为 APT 内部 自动处理 dearmor！ 当你在 sources.list 写：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text &quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;deb [signed-by=&amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;keyrings&amp;#x2F;docker.asc] ...
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;APT 会： 检测 .asc 后缀或文件内容含 -----BEGIN → 自动 dearmor 后加载&lt;&#x2F;p&gt;
&lt;p&gt;不依赖 gpg CLI 行为 → 所以 apt update 正常，但你手动用 gpg --keyring 却失败。&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 查看二进制 keyring 内容
gpg --keyring &amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;keyrings&amp;#x2F;docker.gpg --list-packets &amp;lt;&amp;#x2F;dev&amp;#x2F;null
# 应显示 pub, sub 等 key packets，无 &amp;quot;invalid packet&amp;quot;

# 或直接看指纹（对比官网）
gpg --keyring &amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;keyrings&amp;#x2F;docker.gpg --with-fingerprint --list-keys
# 应含：7EA0 A9C3 F273 FCD8 （即你日志中的 RSA 密钥 ID）
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;zong-jie&quot;&gt;总结：&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;.asc 是文本格式，不能直接作 --keyring；必须 --dearmor 转 .gpg 二进制。&lt;&#x2F;li&gt;
&lt;li&gt;APT 能自动处理，但 gpg CLI 不会 —— 这是常见坑点&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>如何查看被mount --bind目录的内容</title>
        <published>2025-11-25T10:28:51+08:00</published>
        <updated>2025-11-25T10:28:51+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/11/如何查看被mount --bind目录的内容/"/>
        <id>https://vercel.juzhong.xyz/2025/11/如何查看被mount --bind目录的内容/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/11/如何查看被mount --bind目录的内容/">&lt;h1 id=&quot;mount-bind&quot;&gt;mount --bind&lt;&#x2F;h1&gt;
&lt;p&gt;当你用：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;mount -o bind &amp;#x2F;new-disk &amp;#x2F;var&amp;#x2F;lib
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;绑定挂载后的 &#x2F;var&#x2F;lib 就被 新的分区内容覆盖&lt;&#x2F;p&gt;
&lt;p&gt;原来真实的 &#x2F;var&#x2F;lib 内容仍然在磁盘上，但无法通过 &#x2F;var&#x2F;lib 直接访问&lt;&#x2F;p&gt;
&lt;p&gt;想在 不 umount 的情况下 查看原来目录的内容，有几种经典做法：&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zai-ba-yuan-shi-mu-lu-gua-zai-dao-qi-ta-lu-jing-zui-chang-yong&quot;&gt;再把原始目录挂载到其他路径（最常用）&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;mkdir &amp;#x2F;mnt&amp;#x2F;origin_root
mount --bind &amp;#x2F; &amp;#x2F;mnt&amp;#x2F;origin_root    # 临时挂载根不推荐；下面是推荐方式
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;zhi-jie-tong-guo-proc-pid-root-fang-wen-zui-chang-jian-zui-gan-jing-geng-tui-jian&quot;&gt;直接通过 &#x2F;proc&#x2F;[pid]&#x2F;root 访问（最常见最干净） 更推荐：&lt;&#x2F;h2&gt;
&lt;p&gt;找到任意仍在主根下运行的进程，如 systemd ：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;ls -l &amp;#x2F;proc&amp;#x2F;1&amp;#x2F;root&amp;#x2F;var&amp;#x2F;lib
# 但最好再 bind 一层：
mkdir &amp;#x2F;mnt&amp;#x2F;original
mount --bind &amp;#x2F;proc&amp;#x2F;1&amp;#x2F;root&amp;#x2F;var&amp;#x2F;lib &amp;#x2F;mnt&amp;#x2F;original
ls &amp;#x2F;mnt&amp;#x2F;original
# 你就可以浏览原来 &amp;#x2F;var&amp;#x2F;lib 中的内容了。
# 不需要 umount，不需要停止业务，不影响现有 &amp;#x2F;var&amp;#x2F;lib。
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;zhi-jie-tong-guo-proc-pid-root-fang-wen&quot;&gt;直接通过 &#x2F;proc&#x2F;[pid]&#x2F;root 访问&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 任意 pid 都行，例如：
ls &amp;#x2F;proc&amp;#x2F;1&amp;#x2F;root&amp;#x2F;var&amp;#x2F;lib
# 就是没被覆盖的 &amp;#x2F;var&amp;#x2F;lib。
# 但这种方式只是临时查看，比 bind 挂载不方便操作。
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;ti-qian-chuang-jian-tao-sheng-ru-kou-jing-yan-ji-qiao&quot;&gt;提前创建 “逃生入口”（经验技巧）&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 以后遇到类似场景：
mkdir &amp;#x2F;var&amp;#x2F;lib.real
mount --bind &amp;#x2F;var&amp;#x2F;lib &amp;#x2F;var&amp;#x2F;lib.real
mount --bind &amp;#x2F;newdisk &amp;#x2F;var&amp;#x2F;lib
# 这样以后变成：
# &amp;#x2F;var&amp;#x2F;lib → 新分区
# &amp;#x2F;var&amp;#x2F;lib.real → 原目录仍可访问
# 但必须在第一次 bind 前做。
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;zui-tui-jian-ban-fa-zong-jie&quot;&gt;最推荐办法总结&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;mkdir &amp;#x2F;mnt&amp;#x2F;original
mount --bind &amp;#x2F;proc&amp;#x2F;1&amp;#x2F;root&amp;#x2F;var&amp;#x2F;lib &amp;#x2F;mnt&amp;#x2F;original
ls &amp;#x2F;mnt&amp;#x2F;original
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>linux 多架构支持</title>
        <published>2025-11-24T22:39:41+08:00</published>
        <updated>2025-11-24T22:39:41+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/11/linux 多架构支持/"/>
        <id>https://vercel.juzhong.xyz/2025/11/linux 多架构支持/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/11/linux 多架构支持/">&lt;h1 id=&quot;debian-duo-jia-gou-multiarch-yu-kua-jia-gou-mo-ni-qemu-binfmt-misc&quot;&gt;Debian 多架构（Multiarch） 与 跨架构模拟（QEMU + binfmt_misc）&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;dpkg --add-architecture + apt install -d 不依赖 QEMU&#x2F;binfmt&lt;&#x2F;li&gt;
&lt;li&gt;但若想 运行 vim:arm64，就必须用 QEMU&#x2F;binfmt&lt;&#x2F;li&gt;
&lt;li&gt;Multiarch 解决“如何下载&#x2F;解压 arm64 包”&lt;&#x2F;li&gt;
&lt;li&gt;QEMU&#x2F;binfmt 解决“如何执行 arm64 二进制”&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;dpkg --print-architecture
dpkg --print-foreign-architectures

# 即使没装 qemu-user-static，也能下载
sudo apt purge qemu-user-static 2&amp;gt;&amp;#x2F;dev&amp;#x2F;null
sudo apt clean
sudo dpkg --add-architecture arm64
sudo apt update
sudo apt-get install -d vim:arm64  # ✅ 成功！
dpkg -x &amp;#x2F;var&amp;#x2F;cache&amp;#x2F;apt&amp;#x2F;archives&amp;#x2F;vim_*.deb .&amp;#x2F;vim-arm64
# 尝试运行
.&amp;#x2F;vim-arm64&amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;vim --version
# ❌ 报错：bash: .&amp;#x2F;vim-arm64&amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;vim: cannot execute binary file: Exec format error
sudo apt install qemu-user-static
.&amp;#x2F;vim-arm64&amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;vim --version
# ✅ 成功
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;目标&lt;&#x2F;th&gt;&lt;th&gt;所需技术&lt;&#x2F;th&gt;&lt;th&gt;命令示例&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;下载 arm64 .deb&lt;&#x2F;td&gt;&lt;td&gt;Multiarch&lt;&#x2F;td&gt;&lt;td&gt;dpkg --add-architecture arm64 &amp;amp;&amp;amp; apt install -d vim:arm64&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;解压 arm64 文件&lt;&#x2F;td&gt;&lt;td&gt;Multiarch&lt;&#x2F;td&gt;&lt;td&gt;dpkg -x vim_arm64.deb .&#x2F;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;运行 arm64 二进制&lt;&#x2F;td&gt;&lt;td&gt;QEMU + binfmt&lt;&#x2F;td&gt;&lt;td&gt;apt install qemu-user-static &amp;amp;&amp;amp; .&#x2F;vim&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;容器中跑 arm64&lt;&#x2F;td&gt;&lt;td&gt;QEMU + binfmt + OCI&lt;&#x2F;td&gt;&lt;td&gt;podman run --platform=linux&#x2F;arm64 arm64v8&#x2F;alpine&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;交叉编译 arm64&lt;&#x2F;td&gt;&lt;td&gt;Multiarch + gcc&lt;&#x2F;td&gt;&lt;td&gt;apt install gcc-aarch64-linux-gnu &amp;amp;&amp;amp; aarch64-linux-gnu-gcc hello.c&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h1 id=&quot;chang-jian-wen-ti&quot;&gt;常见问题&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;ru-guo-zhi-zuo-he-hui-zen-yang&quot;&gt;如果只做 ① 和 ②，会怎样？&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;dpkg --add-architecture arm64
apt install vim:arm64
# 然后运行：
&amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;vim
# 可能得到：
# cannot execute binary file: Exec format error
# 因为：
# 系统能装包
# 但内核不知道如何执行 arm64 ELF
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;ru-guo-you-qemu-dan-mei-you-binfmt-misc&quot;&gt;如果有 QEMU 但没有 binfmt_misc？&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 你可以：
qemu-aarch64-static &amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;vim
# 但不能直接：
&amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;vim
# 因为：
# 内核不会自动调用 qemu
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;ru-guo-you-binfmt-misc-dan-mei-you-qemu&quot;&gt;如果有 binfmt_misc 但没有 QEMU？&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text &quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;# 那么执行会变成：
# No such file or directory
# 因为：
# 内核要调用 &amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;qemu-aarch64-static
# 结果命令不存在
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;binfmt-misc&quot;&gt;binfmt_misc&lt;&#x2F;h1&gt;
&lt;p&gt;内核机制：自动调用解释器运行异构二进制&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;docker run --privileged --rm tonistiigi&amp;#x2F;binfmt --install all
docker run -it --rm --platform=linux&amp;#x2F;loong64 loongarch64&amp;#x2F;debian uname -a

# qemu-user-static    # 提供 &amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;qemu-*-static 二进制
# binfmt-support      # Debian&amp;#x2F;Ubuntu 专用：管理 binfmt_misc 持久化
# binfmt-support 会在安装时：
# 将预定义的注册规则写入 &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;binfmt-support&amp;#x2F;
# 创建 systemd 服务：systemd-binfmt.service
# 启用服务：systemctl enable systemd-binfmt
# 系统级预装 QEMU + binfmt # Debian&amp;#x2F;Ubuntu # Fedora&amp;#x2F;RHEL 
sudo apt install qemu-user-static binfmt-support 
sudo dnf install qemu-user-static 

# 用 rootful Podman（临时 sudo）
sudo podman run --privileged --rm tonistiigi&amp;#x2F;binfmt --install all
# 普通用户运行容器（rootless 安全！）
podman run -it --rm --platform=linux&amp;#x2F;loong64 loongarch64&amp;#x2F;debian uname -a

## 复杂、会话级有效、重启失效 —— 不如一句 sudo apt install qemu-user-static
# 1. 创建用户命名空间并挂载 binfmt_misc
unshare --user --map-root-user --mount sh -c &amp;#x27;
  mount -t binfmt_misc binfmt_misc &amp;#x2F;proc&amp;#x2F;sys&amp;#x2F;fs&amp;#x2F;binfmt_misc
  podman run --rm -v &amp;#x2F;proc&amp;#x2F;sys&amp;#x2F;fs&amp;#x2F;binfmt_misc:&amp;#x2F;proc&amp;#x2F;sys&amp;#x2F;fs&amp;#x2F;binfmt_misc:rw tonistiigi&amp;#x2F;binfmt --install loong64
&amp;#x27;
# 2. 保持命名空间 alive（后台）
unshare --user --map-root-user --mount --fork sleep infinity &amp;amp;
NS_PID=$!
# 3. 在该命名空间中运行容器
nsenter -U -m -t $NS_PID podman run --platform=linux&amp;#x2F;loong64 uname -a
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>systemd-nspawn lxc podman 容器对比</title>
        <published>2025-11-24T20:56:45+08:00</published>
        <updated>2025-11-24T20:56:45+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/11/systemd-nspawn lxc podman 容器对比/"/>
        <id>https://vercel.juzhong.xyz/2025/11/systemd-nspawn lxc podman 容器对比/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/11/systemd-nspawn lxc podman 容器对比/">&lt;h1 id=&quot;debootstrap-gou-jian-vmmu-lu&quot;&gt;debootstrap 构建vm目录&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1
sudo debootstrap --verbose --include=tmux,apt-transport-https,ca-certificates,dbus bookworm &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;machines&amp;#x2F;debian https:&amp;#x2F;&amp;#x2F;mirrors.ustc.edu.cn&amp;#x2F;debian
sudo machinectl start debian
sudo machinectl shell debian
# sudo systemd-nspawn -D &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;machines&amp;#x2F;debian -u root -- &amp;#x2F;bin&amp;#x2F;bash -c &amp;#x27;systemctl is-active dbus&amp;#x27;
# sudo systemd-nspawn -D &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;machines&amp;#x2F;debian

podman pull ubuntu:24.04
podman export ubuntu:24.04 &amp;gt; ubuntu.tar
mkdir &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;machines&amp;#x2F;ubuntu
tar -xf ubuntu.tar -C &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;machines&amp;#x2F;ubuntu

machinectl start ubuntu
systemd-nspawn -D &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;machines&amp;#x2F;ubuntu
# 单次运行 &amp;#x2F; 调试 &amp;#x2F; 灵活参数控制
# 参数全由用户传递，例如：
# 挂载
# network
# capabilities
# user namespace 等
sudo systemd-nspawn -b -M debian --private-users
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;pei-zhi-machinede-qi-dong-can-shu&quot;&gt;配置machine的启动参数&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;ini&quot; class=&quot;language-ini &quot;&gt;&lt;code class=&quot;language-ini&quot; data-lang=&quot;ini&quot;&gt;cat &amp;lt;&amp;lt;EOF | sudo tee &amp;quot;&amp;#x2F;etc&amp;#x2F;systemd&amp;#x2F;nspawn&amp;#x2F;debian.nspawn&amp;quot; &amp;gt;&amp;#x2F;dev&amp;#x2F;null
# 安全执行环境
[Exec]
# 启用用户命名空间（关键！容器内 root ≠ 宿主 root）
PrivateUsers=yes
PrivateUsersChown=yes
# 降权：禁止提权，限制能力集
NoNewPrivileges=yes
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_CHOWN CAP_DAC_OVERRIDE CAP_SETGID CAP_SETUID
# 隔离内核模块&amp;#x2F;参数
PrivateMounts=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectControlGroups=yes
# 文件系统
[Files]
# 只读绑定宿主关键配置
BindReadOnly=&amp;#x2F;etc&amp;#x2F;resolv.conf
# 可选：绑定项目目录（取消注释并修改路径）
#Bind=&amp;#x2F;home&amp;#x2F;$USER&amp;#x2F;project:&amp;#x2F;mnt&amp;#x2F;project
# 网络（桥接模式）
[Network]
VirtualEthernet=yes
Bridge=$BRIDGE
# 若需MACVLAN（高性能），替换为：
#MACVLAN=$MAIN_IFACE
# 资源控制（cgroup v2）
[ResourceControl]
# CPU：最多 2 核，权重 500
CPUQuota=200%
AllowedCPUs=0 1
# 内存：硬限制 2GB，软限制 1.5GB
MemoryMax=2G
MemoryHigh=1500M
# 进程数上限
TasksMax=500
# IO 权重
IOWeight=500
# 设备安全（仅允许必要设备）
[Device]
# 清空默认允许列表
DeviceAllow=
# 允许终端&amp;#x2F;随机数
DeviceAllow=char-pts rw
DeviceAllow=char-urandom r
DeviceAllow=char-null r
# 禁止访问磁盘&amp;#x2F;USB&amp;#x2F;内核设备
#DeviceAllow=block-* r  # 取消注释可允许磁盘（危险！）
EOF
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;chang-qi-chi-jiu-wan-zheng-os-de-kai-fa-huan-jing-ru-bian-yi-nei-he-bu-shu-fu-wu-zhan-ce-shi-xi-tong-ji-ruan-jian&quot;&gt;长期、持久、完整 OS 的开发环境（如：编译内核、部署服务栈、测试系统级软件）&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;首选 systemd-nspawn&lt;&#x2F;li&gt;
&lt;li&gt;优势：天然持久、systemd 原生、无缝 journal、machinectl 管理方便&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 创建 Ubuntu 开发机
sudo debootstrap jammy &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;machines&amp;#x2F;dev-ubuntu
sudo systemd-nspawn -D &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;machines&amp;#x2F;dev-ubuntu --boot
sudo machinectl enable dev-ubuntu
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;xu-ni-ji-zhong-pei-zhi-wang-luo&quot;&gt;虚拟机中配置网络&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# ip route add  default via 192.168.2.1 dev host0
tee -a  &amp;#x2F;etc&amp;#x2F;resolv.conf&amp;lt;&amp;lt;EOF
nameserver 223.5.5.5
EOF
# 创建 networkd 配置，为 veth 接口（默认名是 host0）启用 DHCP
cat &amp;gt; &amp;#x2F;etc&amp;#x2F;systemd&amp;#x2F;network&amp;#x2F;20-wired.network &amp;lt;&amp;lt;&amp;#x27;EOF&amp;#x27;
[Match]
Name=host0
[Network]
DHCP=yes
# 可选：添加 DNS
# DNS=192.168.1.1
# Domains=lan
EOF
systemctl enable --now systemd-networkd
networkctl status

cat &amp;#x2F;etc&amp;#x2F;subuid
pid=$(machinectl show debian -p Leader --value)
cat &amp;#x2F;proc&amp;#x2F;$pid&amp;#x2F;uid_map

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;shi-yong-isogou-zao-rootfs&quot;&gt;使用iso构造rootfs&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo mount -o loop &amp;#x2F;path&amp;#x2F;to&amp;#x2F;system.iso &amp;#x2F;mnt&amp;#x2F;iso
sudo unsquashfs -f -d &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;machines&amp;#x2F;ubuntu &amp;#x2F;mnt&amp;#x2F;iso&amp;#x2F;casper&amp;#x2F;minimal.squashfs
sudo machinectl start ubuntu
sudo machinectl shell ubuntu
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;xu-yao-gui-an-quan-rootless-docker-jing-xiang-sheng-tai&quot;&gt;需要 GUI + 安全 rootless + Docker 镜像生态&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;首选 Podman（rootless）&lt;&#x2F;li&gt;
&lt;li&gt;优势：一行命令跑 GUI 应用、OCI 镜像丰富、与 Dockerfile 兼容、安全&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;podman run -d \
  --name devbox \
  --hostname devbox \
  --systemd=always \
  -e DISPLAY=$DISPLAY \
  -v &amp;#x2F;tmp&amp;#x2F;.X11-unix:&amp;#x2F;tmp&amp;#x2F;.X11-unix \
  -v ~&amp;#x2F;project:&amp;#x2F;home&amp;#x2F;user&amp;#x2F;project:z \
  -v dev-data:&amp;#x2F;var&amp;#x2F;lib&amp;#x2F;mysql \
  ghcr.io&amp;#x2F;linuxserver&amp;#x2F;code-server:latest

# 通过--rootfs运行：Podman可以直接使用这个解压后的目录来运行容器，这证实了该目录可以作为有效的根文件系统使用：
podman run --rootfs &amp;#x2F;path&amp;#x2F;to&amp;#x2F;lxc&amp;#x2F;rootfs
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;xu-yao-kuai-zhao-mo-ban-chuan-tong-xu-ni-hua-ti-yan&quot;&gt;需要快照、模板、传统虚拟化体验&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;选 LXC（或 LXD）&lt;&#x2F;li&gt;
&lt;li&gt;优势：快照&#x2F;迁移&#x2F;备份成熟；适合运维人员管理多容器&lt;&#x2F;li&gt;
&lt;li&gt;推荐搭配 lxd（LXC 的 daemon + REST API + CLI 增强版）：&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;lxc launch ubuntu:22.04 dev --profile default --profile gui  # 若配置了 GUI profile
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>sing-box tun配置</title>
        <published>2025-11-23T19:57:28+08:00</published>
        <updated>2025-11-23T19:57:28+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/11/sing-box tun配置/"/>
        <id>https://vercel.juzhong.xyz/2025/11/sing-box tun配置/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/11/sing-box tun配置/">&lt;h1 id=&quot;sing-box-pei-zhi-tunde-yuan-li&quot;&gt;sing-box 配置tun的原理&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# Routing Policy DataBase
sudo ip rule add priority 9000 from all to 172.20.0.0&amp;#x2F;30 table 2022  
sudo ip rule add priority 9003 not iif lo lookup 2022
# 9003: not from all iif lo lookup 2022  # 生成的结果中自动添加了from all

ip rule

0:    from all lookup local
9000: from all to 172.20.0.0&amp;#x2F;30 lookup 2022
# 不匹配路由前缀为0（不匹配缺省路由）
9001: from all lookup 2022 suppress_prefixlength 0
# 地址非53端口的所有流量
9002: not from all dport 53 lookup main suppress_prefixlength 0
9002: from all ipproto icmp goto 9010
9002: from all iif tun0 goto 9010
9003: not from all iif lo lookup 2022
9003: from 0.0.0.0 iif lo lookup 2022
9003: from 172.20.0.0&amp;#x2F;30 iif lo lookup 2022
9010: from all nop
32766: from all lookup main
32767: from all lookup default
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;ip route show table 2022
default dev tun0

ip route show table main
default via 11.11.11.1 dev pppoe-wan proto static
11.11.11.1 dev pppoe-wan proto kernel scope link src 11.11.11.5
192.168.11.0&amp;#x2F;24 dev br-lan proto kernel scope link src 192.168.11.1
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;chuang-jian-lu-you-ming-cheng-bing-shi-lu-you-sheng-xiao&quot;&gt;创建路由名称 并使路由生效&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;echo 100 custom &amp;gt;&amp;gt; &amp;#x2F;etc&amp;#x2F;iproute2&amp;#x2F;rt_tables 
ip route add default via 192.168.1.100 dev eth1 table custom
ip rule add to 192.168.1.200 lookup custom
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;fwmark&quot;&gt;fwmark&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;iptables -t mangle -A FORWARD -i eth3 -p tcp --dport 80 -j MARK --set-mark 1  
iptables -t mangle -A FORWARD -i eth3 -p tcp --dport 25 -j MARK --set-mark 2  
iptables -t mangle -A FORWARD -i eth3 -p tcp --dport 110 -j MARK --set-mark 2  
iptables -t mangle -A FORWARD -i eth3 -j MARK --set-mark 3  
ip rule add fwmark 1 table 1  
ip rule add fwmark 2 table 2  
ip rule add fwmark 3 table 3
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;shi-yong-ip-rule-pei-zhi-lu-you-gui-ze&quot;&gt;使用 ip rule 配置路由规则&lt;&#x2F;h1&gt;
&lt;p&gt;内核需要根据规则，来为数据包选择要进行的操作或选择使用的路由表——当数据包能够匹配某些规则，则对该数据包执行该规则所对应的动作，比如查找一个路由表。Linux 的默认规则会让入向和出向的流量都 &quot;lookup&quot; 默认路由表。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tian-jia-lu-you-gui-ze-de-ip-rule-yong-fa-ru-xia&quot;&gt;添加路由规则的 ip rule 用法如下：&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;ip rule add {prefix} {selector} {predicate}&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;ip rule add 的意思很好理解，就是使用其后的参数，添加一个新的规则。prefix 表示该规则的应用范围——是入向流量还是出向流量。selector 表示需要使用的过滤条件。predicate 的意思是谓语，表示 selector 的对象或要执行的动作。&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;prefix: from {addr} | to {addr}&lt;&#x2F;li&gt;
&lt;li&gt;selector: to {addr} | priority &amp;lt;#&amp;gt; | fwmark &lt;fwmark&gt; | iif &lt;name&gt; | oif &lt;name&gt; | tos &lt;value&gt;&lt;&#x2F;li&gt;
&lt;li&gt;predicate: {blackhole | prohibited | unreachable} | lookup &lt;table id&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;prefix 是源地址和&#x2F;或目的地址，可以是单一 IP 地址或一个地址段。from 后接源地址&#x2F;地址范围，to 后接目的地址&#x2F;地址范围。也可以用 all 表示所有地址。这里的 from 和 to 会被用来对数据包进行匹配，能够匹配上的则会被应用该条规则；&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;selector 可以对数据包进行进一步的过滤，同一条规则中可以使用多个 selector。常用的 selector 有下面几种：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;fwmark：数据包的标记值，在命令中填的 10 进制数字会被转成 16 进制存储和使用，如果要使用 16 进制表示，则需要在前面加个 x。需要注意的是，fwmark（FireWall MARK）只能由 iptables 添加；&lt;&#x2F;li&gt;
&lt;li&gt;iif：入向接口名称；&lt;&#x2F;li&gt;
&lt;li&gt;oif：出向接口名称；&lt;&#x2F;li&gt;
&lt;li&gt;priority：本条规则的优先级，数字越小，优先级越高。该值必须是唯一的，即，不允许出现两条优先级相同的路由规则；&lt;&#x2F;li&gt;
&lt;li&gt;tos：Type of Service，服务类型；&lt;&#x2F;li&gt;
&lt;li&gt;ipproto：ip 层协议类型；&lt;&#x2F;li&gt;
&lt;li&gt;sport、dport：源端口及目的端口，可以是特定端口或端口范围&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;predicate 表示当本条规则匹配成功时要执行的动作，包括：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;lookup：查找要使用的路由表；&lt;&#x2F;li&gt;
&lt;li&gt;unreachable：设置该路由不可达，数据包会被丢弃，ICMP 会返回 host unreachable，发送代码会报错 EHOSTUNREACH ；&lt;&#x2F;li&gt;
&lt;li&gt;blackhole（黑洞）：数据包会被无声丢弃（discarded silently），发送代码会报错 EINVAL ；&lt;&#x2F;li&gt;
&lt;li&gt;prohabit（禁止）：数据包会被丢弃并给一个报错。ICMP 会返回 communication administratively prohibited。发送代码会报错 EACCES；&lt;&#x2F;li&gt;
&lt;li&gt;需要注意的是，ip rule 并不能对数据包添加标记，而只能检查 fwmark 值，并根据该值确定如何处理数据包&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;ip-rule-you-xian-ji&quot;&gt;ip rule 优先级&lt;&#x2F;h2&gt;
&lt;p&gt;这里的优先级指的是使用 ip rule 的 priority 选项设置的优先级。这个优先级实际上是最后才会发挥作用的——只有当多条规则的其他部分（from &#x2F; to，过滤规则等）都完全相同时，系统才会根据该值选择真正要使用的规则。&lt;&#x2F;p&gt;
&lt;p&gt;如果用命令设置规则的时候没有指定优先级，则系统会自动为该规则添加一个比【最近使用的规则的优先级高一级】的优先级值。比如最近用的一条路由规则的优先级为 100 ，则新添加的一条规则的优先级值就是 99。&lt;&#x2F;p&gt;
&lt;h1 id=&quot;diao-shi&quot;&gt;调试&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;用 TRACE 调试路由&lt;&#x2F;li&gt;
&lt;li&gt;开启 debug：&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;echo 65535 &amp;gt; &amp;#x2F;proc&amp;#x2F;sys&amp;#x2F;net&amp;#x2F;ipv4&amp;#x2F;rt_trace_max_size
sysctl -w net.core.netdev_max_backlog=5000

rtmon rt filter
# 可以看到 RPDB 的逐条匹配过程。
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>linux wifi网卡不工作</title>
        <published>2025-11-23T18:50:42+08:00</published>
        <updated>2025-11-23T18:50:42+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/11/linux wifi网卡不工作/"/>
        <id>https://vercel.juzhong.xyz/2025/11/linux wifi网卡不工作/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/11/linux wifi网卡不工作/">&lt;h1 id=&quot;xian-xiang&quot;&gt;现象&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;ip link
iw dev
# 这些命令 都看不到对应的无线网卡
# pci设备是可以看到wifi设别的
# lspci -v | grep -i wifi
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;pai-cha-guo-cheng&quot;&gt;排查过程&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt update
sudo apt install firmware-iwlwifi

lspci -v | grep -i wifi
sudo lspci -v -s 00:14.3

rfkill list all
nmcli radio wifi
nmcli radio wifi on

sudo lsmod | grep iwl
sudo dmesg | grep -i iwl

# 查看系统是否至少识别 Wi-Fi 为网络设备
sudo lshw -C network
# 如果无线网卡显示：
# UNCLAIMED
# 驱动没有绑定成功
ls &amp;#x2F;sys&amp;#x2F;class&amp;#x2F;net&amp;#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;zhong-xin-jia-zai-nei-he-mo-kuai-hou-hui-fu-liao&quot;&gt;重新加载内核模块后恢复了？&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 1. 清空当前的 dmesg 缓冲区，排除干扰
sudo dmesg -C
# 2. 卸载驱动模块
sudo modprobe -r iwlwifi
# 3. 重新加载驱动模块 (这一步会触发初始化)
sudo modprobe iwlwifi
# 4. 立即查看刚刚产生的日志 (这次肯定会有内容！)
sudo dmesg
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>systemd-networkd-wait-online阻塞问题解决方案</title>
        <published>2025-11-23T00:18:35+08:00</published>
        <updated>2025-11-23T00:18:35+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/11/systemd-networkd-wait-online阻塞问题解决方案/"/>
        <id>https://vercel.juzhong.xyz/2025/11/systemd-networkd-wait-online阻塞问题解决方案/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/11/systemd-networkd-wait-online阻塞问题解决方案/">&lt;h1 id=&quot;pei-zhi-chao-shi-shi-jian-he-zhi-ding-deng-dai-jie-kou&quot;&gt;配置超时时间 和 指定等待接口&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# sudo systemctl disable systemd-networkd-wait-online.service --now
sudo systemctl edit systemd-networkd-wait-online.service
[Service]
TimeoutStartSec=5
# 删除原来的 ExecStart 行
ExecStart=
# 添加新的 ExecStart 行，使用 --interface 明确指定等待的接口
ExecStart=&amp;#x2F;lib&amp;#x2F;systemd&amp;#x2F;systemd-networkd-wait-online --interface=eth0 --interface=eth1
# 排除名为 vpn0 的接口
# ExecStart=&amp;#x2F;lib&amp;#x2F;systemd&amp;#x2F;systemd-networkd-wait-online --exclude=vpn0

# 全局超时配置
sudo vim &amp;#x2F;etc&amp;#x2F;systemd&amp;#x2F;system.conf
DefaultTimeoutStartSec=10
DefaultTimeoutStopSec=10
ShutdownWatchdogSec=30
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;zhen-duan-wen-ti-gen-yuan&quot;&gt;诊断问题根源&lt;&#x2F;h1&gt;
&lt;p&gt;如果问题是由于网络配置本身的错误导致接口无法上线，仅仅禁用等待服务只会隐藏问题。&lt;&#x2F;p&gt;
&lt;p&gt;检查网络状态： 查看 systemd-networkd 对接口的看法：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;networkctl status
# 查找接口的 State 是否一直处于 configuring 或 degraded 状态。
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>构造edid内核参数 创建虚拟显示器</title>
        <published>2025-11-22T23:30:38+08:00</published>
        <updated>2025-11-22T23:30:38+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/11/构造edid内核参数 创建虚拟显示器/"/>
        <id>https://vercel.juzhong.xyz/2025/11/构造edid内核参数 创建虚拟显示器/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/11/构造edid内核参数 创建虚拟显示器/">&lt;h1 id=&quot;nei-he-ji-xu-ni-xian-shi-qi-tui-jian-wu-xu-ying-jian-yong-jiu-sheng-xiao&quot;&gt;内核级虚拟显示器（推荐！无需硬件，永久生效）&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;选择一个没有物理显示器的接口(逻辑接口)&lt;&#x2F;li&gt;
&lt;li&gt;使用 drm_kms_helper.edid_firmware + 自定义 EDID&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;for p in &amp;#x2F;sys&amp;#x2F;class&amp;#x2F;drm&amp;#x2F;*&amp;#x2F;status; do con=${p%&amp;#x2F;status}; echo -n &amp;quot;${con#*&amp;#x2F;card?-}: &amp;quot;; cat $p; done
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;sheng-cheng-yi-ge-biao-zhun-edid-li-ru-1920x1080&quot;&gt;生成一个标准 EDID（例如 1920x1080）&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 安装 edid-decode（Debian&amp;#x2F;Ubuntu）
sudo apt install edid-decode
# 创建 1920x1080 EDID 文件（标准 60Hz）
cat &amp;gt; custom-edid.bin &amp;lt;&amp;lt;&amp;#x27;EOF&amp;#x27;
00ffffffffffff004c2dd707ffffffffff
141a0104a51e177802ee95a3544c9926
0f5054bfef80714f81c0810081809500
a9c0b300950f023a801871382d40582c
4500dd0c1100001e000000ff004c6170
746f702d303030300a20000000fc0044
656c6c205532343139480a20000000fd
00184c1e5111000a2020202020202020
000000ff004c6170746f702d30303030
0a200088
EOF

# 转为二进制（上述已是 hexdump -C 格式，需 decode）
xxd -r -p &amp;gt; edid.bin &amp;lt;&amp;lt;&amp;#x27;EOF&amp;#x27;
00ffffffffffff004c2dd707ffffffffff141a0104a51e177802ee95a3544c99260f5054bfef80714f81c0810081809500a9c0b300950f023a801871382d40582c4500dd0c1100001e000000ff004c6170746f702d303030300a20000000fc0044656c6c205532343139480a20000000fd00184c1e5111000a2020202020202020000000ff004c6170746f702d303030300a200088
EOF
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;这是一个标准 Dell U2419H 的 EDID（1920x1080@60Hz），你可用&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tomverbeure.github.io&#x2F;video_timings_calculator?horiz_pixels=640&amp;amp;vert_pixels=480&amp;amp;refresh_rate=60&amp;amp;margins=false&amp;amp;interlaced=false&amp;amp;bpc=8&amp;amp;color_fmt=rgb444&amp;amp;video_opt=false&amp;amp;custom_hblank=80&amp;amp;custom_vblank=6&quot;&gt;在线工具&lt;&#x2F;a&gt;生成任意分辨率&lt;&#x2F;p&gt;
&lt;h2 id=&quot;fu-zhi-dao-gu-jian-mu-lu&quot;&gt;复制到固件目录&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo mkdir -p &amp;#x2F;lib&amp;#x2F;firmware&amp;#x2F;edid&amp;#x2F;
sudo cp edid.bin &amp;#x2F;lib&amp;#x2F;firmware&amp;#x2F;edid&amp;#x2F;virtual-edid.bin
# 更新 initramfs（Ubuntu&amp;#x2F;Debian）
sudo update-initramfs -u 
# CentOS&amp;#x2F;RHEL&amp;#x2F;Fedora
sudo dracut --force
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;tian-jia-nei-he-qi-dong-can-shu-yong-jiu-sheng-xiao&quot;&gt;添加内核启动参数（永久生效）&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 编辑 GRUB 配置
sudo nano &amp;#x2F;etc&amp;#x2F;default&amp;#x2F;grub
RUB_CMDLINE_LINUX=&amp;quot;... drm_kms_helper.edid_firmware=edid&amp;#x2F;virtual-edid.bin video=Virtual-1:1920x1080@60&amp;quot;
# 更新 GRUB
sudo update-grub   # Debian&amp;#x2F;Ubuntu
sudo grub2-mkconfig -o &amp;#x2F;boot&amp;#x2F;grub2&amp;#x2F;grub.cfg  # RHEL
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;zhi-jie-shi-yong-dpwu-li-xian-shi-qi-de-edid&quot;&gt;直接使用dp物理显示器的edid&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo cat &amp;#x2F;sys&amp;#x2F;class&amp;#x2F;drm&amp;#x2F;card0-DP-1&amp;#x2F;edid &amp;gt; &amp;#x2F;tmp&amp;#x2F;dp-edid.bin
# 验证内容（应看到显示器型号）
edid-decode &amp;#x2F;tmp&amp;#x2F;dp-edid.bin | grep -E &amp;quot;Manufacturer|Model|Name&amp;quot;
sudo mkdir -p &amp;#x2F;lib&amp;#x2F;firmware&amp;#x2F;edid&amp;#x2F;
# 复制 EDID（命名为 hdmi-edid.bin，清晰表明用途）
sudo cp &amp;#x2F;tmp&amp;#x2F;dp-edid.bin &amp;#x2F;lib&amp;#x2F;firmware&amp;#x2F;edid&amp;#x2F;hdmi-edid.bin
# 更新 initramfs（确保开机加载）
sudo update-initramfs -u   # Debian&amp;#x2F;Ubuntu
sudo dracut --force        # RHEL&amp;#x2F;Fedora

# 编辑 GRUB
sudo nano &amp;#x2F;etc&amp;#x2F;default&amp;#x2F;grub
GRUB_CMDLINE_LINUX=&amp;quot;... drm_kms_helper.edid_firmware=HDMI-A-1:edid&amp;#x2F;hdmi-edid.bin video=HDMI-A-1:1920x1080@60&amp;quot;
# drm.edid_firmware=HDMI-A-1:edid&amp;#x2F;HDMI-A-1-dp-edid.bin,HDMI-A-2:edid&amp;#x2F;HDMI-A-1-dp-edid.bin
# HDMI-A-1：目标连接器名（必须与 &amp;#x2F;sys&amp;#x2F;class&amp;#x2F;drm&amp;#x2F; 下的名称一致）
# edid&amp;#x2F;hdmi-edid.bin：相对于 &amp;#x2F;lib&amp;#x2F;firmware&amp;#x2F; 的路径
# 💡 你有两个 HDMI（HDMI-A-1, HDMI-A-2），选一个未使用的（如 HDMI-A-2）避免冲突
sudo update-grub

dmesg | grep -E &amp;quot;edid|drm_kms_helper|HDMI-A-2&amp;quot;
lsinitramfs &amp;#x2F;boot&amp;#x2F;initrd.img-$(uname -r) | grep hdmi-edid.bin || true
sudo update-initramfs -u -k all
sudo update-initramfs -u -k $(uname -r)

# !!!!! 5.12 以上的内核，参数已经变为了drm.edid_firmware
drm.edid_firmware=HDMI-A-2:edid&amp;#x2F;hdmi-edid.bin video=HDMI-A-2:2560x1440@120e
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;pai-cha-wei-shen-me-fen-bian-lu-da-bu-dao-edidzhong-de-pei-zhi&quot;&gt;排查为什么分辨率达不到edid中的配置&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 安装工具
sudo apt install libdrm-tests
# 列出所有 connector 及 mode
sudo modetest -M i915 | grep -A 20 &amp;quot;HDMI-A-2&amp;quot;

# 你的 EDID 中 DTD 未设 preferred bit → GNOME 可能忽略它。
git clone https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;akatrevorjay&amp;#x2F;edid-generator
cd edid-generator
# 关键：加 --preferred 和 --cvt-rb
.&amp;#x2F;edid-generator.py \
  --name &amp;quot;VIRT-2K&amp;quot; \
  --width 2560 --height 1440 --refresh 120 \
  --timing &amp;quot;2560 2608 2640 2720 1440 1443 1448 1545 +hsync -vsync&amp;quot; \
  --cvt-rb \          # 使用 reduced blanking（更省带宽）
  --preferred \       # 设为 preferred timing！
  --output &amp;#x2F;lib&amp;#x2F;firmware&amp;#x2F;edid&amp;#x2F;hdmi-edid.bin
sudo update-initramfs -u
# --preferred 让 DRM&amp;#x2F;GNOME 优先选用该 mode
# --cvt-rb 降低 pixel clock（从 497.75 → ~399 MHz），提高兼容性
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;fireware-mei-you-bei-da-bao-jin-initrdzhong&quot;&gt;fireware 没有被打包金initrd中&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo tee &amp;#x2F;etc&amp;#x2F;initramfs-tools&amp;#x2F;hooks&amp;#x2F;zzz_edid_inject &amp;lt;&amp;lt;&amp;#x27;EOF&amp;#x27;
#!&amp;#x2F;bin&amp;#x2F;sh
PREREQ=&amp;quot;&amp;quot;
prereqs() { echo &amp;quot;$PREREQ&amp;quot;; }
case &amp;quot;$1&amp;quot; in
    prereqs) prereqs; exit 0 ;;
esac
. &amp;#x2F;usr&amp;#x2F;share&amp;#x2F;initramfs-tools&amp;#x2F;hook-functions

# 创建 firmware 目录（initramfs 中路径是 lib&amp;#x2F;firmware&amp;#x2F;...）
mkdir -p &amp;quot;${DESTDIR}&amp;#x2F;lib&amp;#x2F;firmware&amp;#x2F;edid&amp;quot;
# 复制文件（必须用 copy_file，不是 cp！）
copy_file &amp;#x2F;lib&amp;#x2F;firmware&amp;#x2F;edid&amp;#x2F;hdmi-edid.bin &amp;#x2F;lib&amp;#x2F;firmware&amp;#x2F;edid&amp;#x2F;hdmi-edid.bin
EOF
# 赋予执行权限（必须！）
sudo chmod +x &amp;#x2F;etc&amp;#x2F;initramfs-tools&amp;#x2F;hooks&amp;#x2F;zzz_edid_inject

sudo update-initramfs -c -k $(uname -r)
lsinitramfs &amp;#x2F;boot&amp;#x2F;initrd.img-$(uname -r) | grep -i &amp;#x27;edid&amp;#x2F;hdmi-edid&amp;#x27;

# 手动解压验证
mkdir &amp;#x2F;tmp&amp;#x2F;initrd &amp;amp;&amp;amp; cd &amp;#x2F;tmp&amp;#x2F;initrd
zcat &amp;#x2F;boot&amp;#x2F;initrd.img-$(uname -r) | cpio -id 2&amp;gt;&amp;#x2F;dev&amp;#x2F;null
find . -name &amp;quot;*hdmi-edid*&amp;quot; -type f
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;edid-firmware-he-video-can-shu-han-yi&quot;&gt;edid_firmware 和video 参数含义&lt;&#x2F;h2&gt;
&lt;p&gt;这两个内核参数是独立的，并且用于不同的目的，但都与显示器的配置有关。&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;drm_kms_helper.edid_firmware=...
&lt;ul&gt;
&lt;li&gt;欺骗内核：强制加载一个特定的 EDID 文件来定义显示器的功能（如支持的分辨率、色彩空间等）。&lt;&#x2F;li&gt;
&lt;li&gt;独立于 video 参数。用于模拟硬件报告的功能。&lt;&#x2F;li&gt;
&lt;li&gt;解决显示器 EDID 报告错误、模拟 4K 分辨率或模拟特定显示器功能。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;video=...
&lt;ul&gt;
&lt;li&gt;强制输出：强制激活一个特定的连接器（Connector）并设置其模式（分辨率和刷新率）。&lt;&#x2F;li&gt;
&lt;li&gt;独立于 edid_firmware 参数。用于强制使能输出。&lt;&#x2F;li&gt;
&lt;li&gt;解决无头（headless）系统无法识别显示器、强制启用休眠后未恢复的接口。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;它们是相互独立的。您可以单独使用其中一个，也可以同时使用。&lt;&#x2F;li&gt;
&lt;li&gt;如果您只是想启动一个虚拟显示器： 仅使用 video=HDMI-A-2:1920x1080@60e 通常就足够了。&lt;&#x2F;li&gt;
&lt;li&gt;如果您需要更复杂的显示器功能模拟： 您可能需要同时使用这两个参数。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;can-shu-ming-cheng&quot;&gt;参数名称&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;这里的 HDMI-A-2 必须与您的 Linux 系统在 &#x2F;sys&#x2F;class&#x2F;drm&#x2F;*&#x2F;status 中报告的逻辑接口名称完全一致。&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;逻辑名称 (HDMI-A-1, HDMI-A-2) 不一定对应您的显卡背后的物理插槽编号。它只是 GPU 驱动程序报告的内部通道名称。
民用主板一般不会将所有的逻辑接口都配置物理接口(成本考虑)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;如果目标是模拟一个虚拟显示器（无头模式）： 您应该选择一个 当前没有物理显示器连接 且 状态显示为 disconnected 的接口名称（例如 HDMI-A-2）。这样，内核就会认为您有一个显示器连接在 HDMI-A-2 上，并使用您指定的参数。&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;如果目标是修复一个已连接的显示器的问题： 您应该选择该显示器实际连接的、状态显示为 connected 的那个接口名称（例如 HDMI-A-1）。&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;video=HDMI-A-2:1920x1080@60e&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;video=： 告诉内核加载视频模式。&lt;&#x2F;li&gt;
&lt;li&gt;HDMI-A-2： 目标连接器名称。&lt;&#x2F;li&gt;
&lt;li&gt;1920x1080： 要设置的分辨率。&lt;&#x2F;li&gt;
&lt;li&gt;@60： 要设置的刷新率（60 Hz）。&lt;&#x2F;li&gt;
&lt;li&gt;e (可选)： 重要，表示 强制启用 (enable)。当连接器处于 disconnected 状态时，添加 e 可以强制驱动程序尝试启用它，非常适合构造虚拟显示器。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;drm_kms_helper.edid_firmware=HDMI-A-2:edid&#x2F;1920x1080.bin&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;drm_kms_helper.edid_firmware=： 告诉内核覆盖 EDID 报告。&lt;&#x2F;li&gt;
&lt;li&gt;HDMI-A-2： 目标连接器名称。&lt;&#x2F;li&gt;
&lt;li&gt;edid&#x2F;1920x1080.bin： EDID 文件路径。您需要手动将一个有效的 EDID 二进制文件放置在 &#x2F;lib&#x2F;firmware&#x2F;edid&#x2F; 目录下。例如，您可以从一台工作正常的显示器上获取 EDID，或者使用工具生成一个。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;yi-lai-guan-xi&quot;&gt;依赖关系&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;drm_kms_helper.edid_firmware=HDMI-A-2:edid&#x2F;xxx.bin
&lt;ul&gt;
&lt;li&gt;阶段1：连接器探测, 将指定 EDID,注入到连接器的 edid 文件中，使内核认为“此接口接了显示器”&lt;&#x2F;li&gt;
&lt;li&gt;❌ 不依赖 video= ；即使没 video=，&#x2F;sys&#x2F;class&#x2F;drm&#x2F;card0-HDMI-A-2&#x2F;status 也会变成 connected&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;video=HDMI-A-2:1920x1080@60
&lt;ul&gt;
&lt;li&gt;阶段2：模式设置,强制激活该连接器的特定显示模式,（即使 EDID 中没有此模式）&lt;&#x2F;li&gt;
&lt;li&gt;✅ 依赖连接器 connected（否则无效）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;zi-ding-yi-edid-sheng-cheng&quot;&gt;自定义 EDID 生成&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;fang-fa-yong-cvt-parse-edid-edid-generator&quot;&gt;方法：用 cvt + parse-edid + edid-generator&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;cvt 2540 1440 120
# 输出类似：
# Modeline &amp;quot;2540x1440_120.00&amp;quot;  852.75  2540 2728 2992 3472  1440 1443 1453 1538 -hsync +vsync
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;用工具生成 EDID：
推荐工具：https:&#x2F;&#x2F;github.com&#x2F;akatrevorjay&#x2F;edid-generator&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git clone https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;akatrevorjay&amp;#x2F;edid-generator
cd edid-generator
.&amp;#x2F;edid-generator.py --name &amp;quot;VIRT-MON&amp;quot; --width 2540 --height 1440 --refresh 120 --timing &amp;quot;2540 2728 2992 3472 1440 1443 1453 1538 +hsync +vsync&amp;quot; --output hdmi-edid.bin

# 验证：
edid-decode hdmi-edid.bin | grep -A5 &amp;quot;Detailed&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>apparmor调试 启动虚拟机失败排查</title>
        <published>2025-11-22T19:48:07+08:00</published>
        <updated>2025-11-22T19:48:07+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/11/apparmor调试 启动虚拟机失败排查/"/>
        <id>https://vercel.juzhong.xyz/2025/11/apparmor调试 启动虚拟机失败排查/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/11/apparmor调试 启动虚拟机失败排查/">&lt;h1 id=&quot;virsh-qi-dong-xu-ni-ji-bao-cuo&quot;&gt;virsh 启动虚拟机报错&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo virsh start 107-debian12
error: 启动域 &amp;#x27;107-debian12&amp;#x27; 失败
error: 内部错误：连接监控的过程中进程退出: 2025-11-22T11:42:17.483457Z qemu-system-x86_64: -blockdev {&amp;quot;driver&amp;quot;:&amp;quot;file&amp;quot;,&amp;quot;filename&amp;quot;:&amp;quot;&amp;#x2F;var&amp;#x2F;lib&amp;#x2F;libvirt&amp;#x2F;images&amp;#x2F;107&amp;#x2F;vm-107-disk-1.qcow2&amp;quot;,&amp;quot;node-name&amp;quot;:&amp;quot;libvirt-2-storage&amp;quot;,&amp;quot;auto-read-only&amp;quot;:true,&amp;quot;discard&amp;quot;:&amp;quot;unmap&amp;quot;}: Could not open &amp;#x27;&amp;#x2F;var&amp;#x2F;lib&amp;#x2F;libvirt&amp;#x2F;images&amp;#x2F;107&amp;#x2F;vm-107-disk-1.qcow2&amp;#x27;: Permission denied
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;cha-kan-apparmorde-pei-zhi-he-zhuang-tai&quot;&gt;查看apparmor的配置和状态&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# AppArmor 策略由 内核模块 (apparmor.ko) 强制执行
# apparmor.service 只负责加载&amp;#x2F;卸载 profile
# aa-teardown 或 apparmor_parser -R 才能移除策略
# 手动 systemctl stop apparmor 不 unload 内核模块 → 残留策略继续生效
sudo systemctl enable --now apparmor.service
sudo systemctl reload libvirtd

sudo dmesg | grep -i &amp;quot;apparmor\|denied&amp;quot; | tail -5
sudo journalctl -k --since &amp;quot;10 minutes ago&amp;quot; | grep -i denied

# 临时禁用 AppArmor（仅测试用）卸载所有 profile（立即解除限制）
sudo aa-teardown
# 禁用内核模块（彻底关闭）
sudo systemctl stop apparmor
sudo rmmod apparmor   # 若报 busy，先 aa-teardown

# 手动扩展 libvirt AppArmor 策略（精准修复）
# 编辑全局 libvirt 模板
sudo nano &amp;#x2F;etc&amp;#x2F;apparmor.d&amp;#x2F;abstractions&amp;#x2F;libvirt-qemu
# Allow access to custom image directories
&amp;#x2F;var&amp;#x2F;lib&amp;#x2F;libvirt&amp;#x2F;images&amp;#x2F;107&amp;#x2F;** rwk,
# rwk = 读+写+加锁（主磁盘需要）

# 重载策略
sudo apparmor_parser -r &amp;#x2F;etc&amp;#x2F;apparmor.d&amp;#x2F;abstractions&amp;#x2F;libvirt-*

# 确认 AppArmor 真正关闭（若选方案 2）
sudo aa-status | grep &amp;quot;apparmor module&amp;quot;
# 检查是否还有 DENIED
sudo dmesg -T | grep -i &amp;quot;denied.*qcow2&amp;quot;
# 临时解决方案：禁用特定配置文件
sudo aa-complain &amp;#x2F;etc&amp;#x2F;apparmor.d&amp;#x2F;libvirt-f681fad3-a70e-44c7-b91b-98a111906d5a
sudo aa-disable &amp;#x2F;etc&amp;#x2F;apparmor.d&amp;#x2F;libvirt-f681fad3-a70e-44c7-b91b-98a111906d5a
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>qemu-img 管理虚拟机硬盘</title>
        <published>2025-11-22T11:21:09+08:00</published>
        <updated>2025-11-22T11:21:09+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/11/qemu-img 管理虚拟机硬盘/"/>
        <id>https://vercel.juzhong.xyz/2025/11/qemu-img 管理虚拟机硬盘/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/11/qemu-img 管理虚拟机硬盘/">&lt;h1 id=&quot;xu-ni-ji-kuai-zhao-lian-snapshot-chains&quot;&gt;虚拟机快照链(snapshot chains)&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;虚拟机快照保存了虚拟机在某个指定时间点的状态(包括操作系统和所有的程序),&lt;&#x2F;li&gt;
&lt;li&gt;利用快照,我们可以恢复虚拟机到某个以前的状态,比如测试软件的时候经常需要回滚系统。&lt;&#x2F;li&gt;
&lt;li&gt;快照链就是多个快照组成的关系链,这些快照按照创建时间排列成链,&lt;&#x2F;li&gt;
&lt;li&gt;像下面这样,本文章要解释的就是怎么创建这条链,链中快照的相互关系,缩短链,以及如何利用这条链回滚我们的虚拟机到某个状态&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;txt&quot; class=&quot;language-txt &quot;&gt;&lt;code class=&quot;language-txt&quot; data-lang=&quot;txt&quot;&gt;base-image&amp;lt;--guest1&amp;lt;--snap1&amp;lt;--snap2&amp;lt;--snap3&amp;lt;--snap4&amp;lt;--当前(active)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;如上,base-image是制作好的一个qcow2格式的磁盘镜像文件,它包含有完整的OS以及引导程序,&lt;&#x2F;li&gt;
&lt;li&gt;现在以这个base-image为模板创建多个虚拟机,简单点方法,每创建一个虚拟机我们就把这个镜像完整复制一份,但这种做法效率底下,满足不了生产需要,&lt;&#x2F;li&gt;
&lt;li&gt;这时就用到了qcow2镜像的特性copy-on-write&lt;&#x2F;li&gt;
&lt;li&gt;qcow2(qemu copy-on-write)格式镜像支持快照,具有创建一个base-image,以及在base-image(backing file)基础上创建多个copy-on-write overlays镜像的能力,&lt;&#x2F;li&gt;
&lt;li&gt;解释下backing file和overlay, 我们为base-image创建一个guest1,那么此时base-image就是guest1的backing file,guest1就是base-image的overlay&lt;&#x2F;li&gt;
&lt;li&gt;同理,为guest1虚拟机创建了一个快照snap1,此时guest1就是snap1的backing file,snap1是guest1的overlay,backing files和overlays十分有用,可以快速的创建瘦装备实例,特别是在开发测试过程中可以快速回滚到之前某个状态&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 使用模板镜像centosbase(backing file)创建两个虚拟机(基于centosbase),20G不是必须的参数
qemu-img create -b centosbase.qcow2 -f qcow2 centos1.qcow2 20G
qemu-img create -b centosbase.qcow2 -f qcow2 centos2.qcow2 20G
# 现在创建出来的centos1和centos2都可以用来启动一个虚拟机,因为他们依赖于backing file,所以这两个磁盘只有几百个字节大小,只有新的文件才会被写入此磁盘
# 查看镜像信息,包括虚拟磁盘大小,实际占用空间,backing file
qemu-img info centos1.qcow2
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;nei-zhi-kuai-zhao-jie-shao-internal-snapshots&quot;&gt;内置快照介绍（Internal Snapshots）&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;nei-zhi-ci-pan-kuai-zhao&quot;&gt;内置磁盘快照&lt;&#x2F;h2&gt;
&lt;p&gt;单个qcow2镜像文件存储快照点的磁盘状态,没有新磁盘文件产生,虚拟机运行状态和关闭状态都可以创建,Libvirt 使用 &#x27;qemu-img&#x27; 命令创建关机状态的磁盘快照.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;nei-zhi-xi-tong-huan-yuan-dian&quot;&gt;内置系统还原点&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;使用virsh save&#x2F;restore命令&lt;&#x2F;li&gt;
&lt;li&gt;可以在虚机开机状态下（内存）保存内存状态，设备状态和磁盘状态到一个指定文件中,还原的时候虚机关机，然后restore回去&lt;&#x2F;li&gt;
&lt;li&gt;多用于测试场景中，我们经常需要不断的将vm还原到某个起点，然后重新开始部署和测试。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;#创建快照1(centos1运行时)
virsh snapshot-create-as centos1 centos1_sn1 centos1_sn1-desc
#创建快照2(centos1关闭)
virsh shutdown centos1
virsh snapshot-create-as centos1 centos1_sn2 centos1_sn2-desc
#查看所有快照
virsh snapshot-list centos1
#快照回滚
virsh snapshot-revert --domain centos1 centos1_sn1
virsh snapshot-revert --domain centos1 centos1_sn3
#内置磁盘快照可以随意回滚,比如先回滚到sn1,在回滚到sn3都是OK的
#注意一点是虚拟机开启状态下,不能回滚到State为running的快照点
#快照删除
virsh snapshot-delete centos1 centos1_sn2
或者
virsh snapshot-delete --domain centos1 --snapshotname centos1_sn2
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;wai-zhi-kuai-zhao-jie-shao-external-snapshots&quot;&gt;外置快照介绍（External Snapshots）&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;wai-zhi-ci-pan-kuai-zhao-external-disk-snapshot&quot;&gt;外置磁盘快照（External disk snapshot）&lt;&#x2F;h2&gt;
&lt;p&gt;当一个快照被创建时，创建时当前的状态保存在当前使用的磁盘文件中，即成为一个backing file,此时一个新的overlay被创建出来保存以后写入的数据&lt;&#x2F;p&gt;
&lt;h2 id=&quot;wai-zhi-xi-tong-huan-yuan-dian-external-system-checkpoint&quot;&gt;外置系统还原点（External system checkpoint）&lt;&#x2F;h2&gt;
&lt;p&gt;虚拟机的磁盘状态将被保存到一个文件中，内存和设备的状态将被保存到另外一个新的文件中&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 启动centos2虚拟机,查看当前所使用磁盘
virsh start centos2
virsh domblklist centos2

virsh snapshot-create-as --domain centos2 centos2_sn1 centos2_sn1-desc --disk-only --diskspec vda,snapshot=external,file=&amp;#x2F;data_lij&amp;#x2F;vhosts&amp;#x2F;centos2_sn1.qcow2 --atomic
#查看快照
virsh snapshot-list centos2
#查看centos2当前所使用磁盘
virsh domblklist centos2
#所使用磁盘已经更新到新创建的磁盘
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;wai-zhi-ci-pan-kuai-zhao-de-he-bing&quot;&gt;外置磁盘快照的合并&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;外置快照非常有用，但这里有一个问题就是如何合并快照文件来缩短链的长度，不能直接删除某个快照,因为每个快照都保存有相应的数据&lt;&#x2F;li&gt;
&lt;li&gt;有两种方式实现
&lt;ul&gt;
&lt;li&gt;blockcommit: 从 top 合并数据到 base (即合并overlays至backing files)&lt;&#x2F;li&gt;
&lt;li&gt;blockpull: 将backing file数据合并至overlay中.从 base 到 top&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;blockcommitxiang-xia-he-bing&quot;&gt;blockcommit向下合并&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# blockcommit可以让你将&amp;#x27;top&amp;#x27;镜像(在同一条backing file链中)合并至底层的&amp;#x27;base&amp;#x27;镜像,
# 一旦 blockcommit #执行完成，处于最上面的overlay链将被自动指向到底层的overlay或base, 后用来缩短链长度的时候十分有用.
# A qemu1.3以下版本不支持live blockcommit,
# B qemu2.0以下版本不支持合并&amp;#x27;Active&amp;#x27;层(最顶部的overlay,即当前使用磁盘)至backing_files
# 当前: [base] &amp;lt;- sn1 &amp;lt;- sn2 &amp;lt;- sn3 &amp;lt;- sn4(当前使用磁盘)
# 目标: [base] &amp;lt;- sn1 &amp;lt;--------------- sn4
# 我们需要做的是合并sn2,sn3到sn1中,并删除sn2,sn3快照,下面有两种方式
# (method-a):
virsh blockcommit --domain f17 vda --base &amp;#x2F;export&amp;#x2F;vmimages&amp;#x2F;sn1.qcow2 --top &amp;#x2F;export&amp;#x2F;vmimages&amp;#x2F;sn3.qcow2 --wait --verbose
# 或者 (method-b):
virsh blockcommit --domain centos2 vda --base centos2_sn2.qcow2 --top centos2_sn3.qcow2 --wait --verbose
virsh blockcommit --domain centos2 vda --base centos2_sn1.qcow2 --top centos2_sn2.qcow2 --wait --verbose
# 注: 如果手工执行*qemu-img*命令完成的话, 现在还只能用method-b. 我们还可以让centos2_sn4(active)直接指向centos2
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;blockpullxiang-shang-he-bing&quot;&gt;blockpull向上合并&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# blockpull（qemu中也称作&amp;#x27;block stream&amp;#x27;）可以将backing合并至active，与blockcommit正好相反.
# 在qemu最新版本2.1.2上测试发现,当前只能将backing file合并至正在使用的active中
# centosbase &amp;lt;-- centos2 &amp;lt;-- centos2_sn1 &amp;lt;-- centos2_sn2 &amp;lt;-- centos2_sn3 &amp;lt;-- centos2_sn4(active)
# 在上面快照链中,可以合并sn1&amp;#x2F;sn2&amp;#x2F;sn3到sn4(active),但不能合并sn1&amp;#x2F;sn2到sn3,因为sn3非当前active磁盘
# 我们需要做的是合并sn1,sn2,sn3到sn4(active)中,并删除sn1,sn2,sn3快照,如下表示关系
# 当前: [base(centos2)] &amp;lt;- sn1 &amp;lt;- sn2 &amp;lt;- sn3 &amp;lt;- sn4(当前使用磁盘)
# 目标: [base(centos2)] &amp;lt;---------------------- sn4
virsh blockpull --domain centos_2 --path &amp;#x2F;data_lij&amp;#x2F;vhosts&amp;#x2F;centos2_sn4.qcow2 --base &amp;#x2F;data_lij&amp;#x2F;vhosts&amp;#x2F;centos2.qcow2 --wait --verbose
#清理掉不用的快照
virsh snapshot-delete --domain centos2 centos2_sn1 --metadata
virsh snapshot-delete --domain centos2 centos2_sn2 --metadata
virsh snapshot-delete --domain centos2 centos2_sn3 --metadata
#查看centos2的快照
virsh snapshot-list centos2
#查看centos2当前使用磁盘
virsh domblklist centos2
#查看快照sn4的backing file
qemu-img info centos2_sn4.qcow2
#如果要迁移虚拟机centos2,可能要将所有backing files合并至centos2_sn4(active),然后迁移centos2_sn4(active)至目的位置
#所有的backing files 都合并到centos2_sn4(active)
virsh blockpull --domain centos2 --path &amp;#x2F;data_lij&amp;#x2F;vhosts&amp;#x2F;centos2_sn4.qcow2 --wait --verbose
qemu-img info centos2_sn4.qcow2
#合并之后,centos2_sn4是一个完整的镜像,包括centosbase,sn1&amp;#x2F;2&amp;#x2F;3所有的数据,此时其不再需要backing files
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;qemu-img-wai-zhi-kuai-zhao-he-bing&quot;&gt;qemu-img 外置快照合并&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;qemu-img rebase -u -b centos2_sn1.qcow2 centos2_sn3.qcow2     #让sn3指向sn1
# 现在sn1中包含了之前的sn1&amp;#x2F;sn2中的数据,所以此时不再需要sn2中的数据,直接让sn3指向sn1即可,可以直接删除sn2
# 注意: -u代表&amp;#x27;Unsafe mode&amp;#x27; -- 此模式下仅仅修改了指向到的backing file名字(不复制数据)
qemu-img rebase -b centos2_sn1.qcow2 centos2_sn3.qcow2
#未使用-u模式的rebase将把数据也一并合并过去，即把sn2的数据写入到sn3并修改sn3指向sn1,此为默认模式

# 创建一个全新的、无 backing file 的镜像 (推荐)
sudo qemu-img convert -f qcow2 -O qcow2 \
  &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;libvirt&amp;#x2F;images&amp;#x2F;107&amp;#x2F;vm-107-disk-0.qcow2 \
  &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;libvirt&amp;#x2F;images&amp;#x2F;107&amp;#x2F;vm-107-disk-0-standalone.qcow2

# ❌ 危险！这是把当前层写回 backing file，会污染 base 镜像！
sudo qemu-img commit &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;libvirt&amp;#x2F;images&amp;#x2F;107&amp;#x2F;vm-107-disk-0.qcow2

# 将backing file数据合并到当前镜像
sudo qemu-img rebase -b &amp;quot;&amp;quot; &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;libvirt&amp;#x2F;images&amp;#x2F;107&amp;#x2F;vm-107-disk-0.qcow2

# 安装必要的工具（如果尚未安装）
sudo apt-get install libguestfs-tools  # Ubuntu&amp;#x2F;Debian
# 合并并优化镜像
sudo virt-sparsify --compress &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;libvirt&amp;#x2F;images&amp;#x2F;107&amp;#x2F;vm-107-disk-0.qcow2 &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;libvirt&amp;#x2F;images&amp;#x2F;107&amp;#x2F;vm-107-disk-0-merged.qcow2
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;qi-dong-shi-bai-hou-xiu-fu&quot;&gt;启动失败后修复&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;zai-su-zhu-ji-shang-gua-zai-xin-jing-xiang-geng-xin-fstab-zhong-jian-initramfs&quot;&gt;在宿主机上挂载新镜像，更新 fstab + 重建 initramfs&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 安装必要工具（如未安装）
sudo apt install libguestfs-tools   # Debian&amp;#x2F;Ubuntu
# 或 yum install libguestfs-tools   # RHEL&amp;#x2F;CentOS
# 使用 guestfish 挂载并检查&amp;#x2F;修复
sudo guestfish --rw -a &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;libvirt&amp;#x2F;images&amp;#x2F;107&amp;#x2F;vm-107-disk-0-standalone.qcow2
&amp;gt; run
&amp;gt; list-filesystems
&amp;gt; mount &amp;#x2F;dev&amp;#x2F;sda1 &amp;#x2F;        # 假设 &amp;#x2F; 是 sda1（根据你的分区调整！）
&amp;gt; mount &amp;#x2F;dev&amp;#x2F;sdb1 &amp;#x2F;mnt     # 如果 &amp;#x2F;home 或其他在 sdb1，按需挂
# 查看当前 UUID（关键！）
&amp;gt; sh &amp;quot;blkid&amp;quot;
# ✅ 更新 fstab 中的 UUID 为新值
&amp;gt; sh &amp;quot;sed -i &amp;#x27;s&amp;#x2F;old-xxxx-yyyy-zzzz&amp;#x2F;new-1111-2222-3333&amp;#x2F;g&amp;#x27; &amp;#x2F;etc&amp;#x2F;fstab&amp;quot;
# —— 如果是 Debian&amp;#x2F;Ubuntu：
&amp;gt; sh &amp;quot;chroot &amp;#x2F; update-initramfs -u -k all&amp;quot;
# 退出
&amp;gt; exit
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;lin-shi-rao-guo-jin-yong-yu-zhen-duan-huo-jin-ji-hui-fu-zai-grub-qi-dong-jie-mian-e-edit&quot;&gt;临时绕过（仅用于诊断或紧急恢复） 在 GRUB 启动界面： e(edit)&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;添加启动参数  init=&amp;#x2F;bin&amp;#x2F;bash

mount -o remount,rw &amp;#x2F;
cat &amp;#x2F;etc&amp;#x2F;fstab
lsblk
blkid
mount -a

exec &amp;#x2F;sbin&amp;#x2F;init
systemctl set-default graphical
update-grub
reboot
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;qi-dong-xu-ni-ji-de-jian-qie-ban-gong-xiang&quot;&gt;启动虚拟机的剪切板共享&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt install spice-vdagent
sudo virsh dumpxml debian12 | grep graphics
sudo virsh domdisplay debian12
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>pipewire 音频控制</title>
        <published>2025-11-18T15:32:14+08:00</published>
        <updated>2025-11-18T15:32:14+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/11/pipewire 音频控制/"/>
        <id>https://vercel.juzhong.xyz/2025/11/pipewire 音频控制/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/11/pipewire 音频控制/">&lt;h1 id=&quot;gnomeyin-pin-wen-ti-pai-cha&quot;&gt;gnome音频问题排查&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;systemctl --user --now disable pulseaudio.socket pulseaudio.service
systemctl --user status pipewire pipewire-pulse wireplumber pulseaudio 2&amp;gt;&amp;#x2F;dev&amp;#x2F;null | grep -E &amp;quot;Active:|Loaded:&amp;quot;

# 列出 ALSA 识别的声卡
aplay -l

# 重新加载声卡模块（常见 Intel&amp;#x2F;Realtek）
sudo alsa force-reload

# 或手动加载（根据芯片选）：
sudo modprobe snd_hda_intel      # Intel HDA
sudo modprobe snd_hda_codec_realtek  # Realtek 编解码器常见问题补丁

# 检查内核是否屏蔽了声卡（罕见但致命）
grep -i &amp;quot;blacklist.*snd&amp;quot; &amp;#x2F;etc&amp;#x2F;modprobe.d&amp;#x2F;*
# 若有 → 注释掉相关行并 reboot

# 查看音频服务 sink（输出设备）
pactl info | grep &amp;quot;Default Sink&amp;quot;
pactl list short sinks

# 重置用户音频配置（安全！会重建 ~&amp;#x2F;.config&amp;#x2F;pipewire 等）
systemctl --user stop pipewire{,-pulse} wireplumber
rm -rf ~&amp;#x2F;.config&amp;#x2F;pipewire ~&amp;#x2F;.config&amp;#x2F;pulse
systemctl --user start pipewire{,-pulse} wireplumber

# 禁用“声音效果”干扰（某些主题&amp;#x2F;扩展冲突）
gsettings set org.gnome.desktop.sound event-sounds false
gsettings set org.gnome.desktop.sound input-feedback-sounds false

# PipeWire 日志（高亮关键错误）
journalctl --user-unit=pipewire --user-unit=wireplumber -f
# 或 PulseAudio（若仍在用）
pulseaudio -k; pulseaudio --start --log-level=debug
# 观察终端输出中的 ERROR&amp;#x2F;WARNING

# 播放测试音（设备 0,0 = 第一块声卡第一个设备）
speaker-test -D hw:0,0 -c 2 -t wav
# 若能听到“左…右…” → 硬件正常！问题在上层服务（Pulse&amp;#x2F;PipeWire&amp;#x2F;GNOME）
# 若无声 → 硬件&amp;#x2F;驱动层问题

sudo apt install pavucontrol   # Debian&amp;#x2F;Ubuntu
pavucontrol

sudo apt install linux-firmware  # Ubuntu&amp;#x2F;Debian

# 看 Codec 芯片型号
cat &amp;#x2F;proc&amp;#x2F;asound&amp;#x2F;cards
# 再看具体编解码器：
cat &amp;#x2F;proc&amp;#x2F;asound&amp;#x2F;card*&amp;#x2F;codec#*

# 用 lspci 确认硬件源头
lspci -v | grep -A 10 -i &amp;quot;audio\|multimedia&amp;quot;
# 只有 1 个 Audio device！证明是单物理声卡。

# HDMI 音频其实是 GPU 的一部分：
# HDMI 音频由 i915 显卡驱动 通过 snd_hda_intel 声卡驱动 输出（共享同一控制器）

# 如何「隐藏」不用的 HDMI 设备？（可选） 
sudo nano &amp;#x2F;etc&amp;#x2F;modprobe.d&amp;#x2F;disable-hdmi.conf
# 只启用 card 0 的 device 0（模拟输出），禁用其他 device
options snd_hda_intel index=0 enable=1
options snd_hda_intel index=1 enable=0  # 禁用 HDMI（若被识别为 card 1）
# 但你的 HDMI 和模拟在同一 card，需用 pin 配置 → 见前文 model= 方案

speaker-test -c 2 -D default    # 默认设备双声道测试
# 或指定设备：
speaker-test -c 2 -D hw:0,0      # hw:0,0 是 card 0, device 0
# 临时关闭 PulseAudio 再测（仅调试用）
# 退出 PulseAudio（--kill）
pulseaudio -k
# 立即测试（5秒内操作！否则 PulseAudio 会自动重启）
speaker-test -D hw:0,0 -c 2 -t wav -l 1
# 测完手动重启（或等它自启）
pulseaudio --start
# 播放一个测试音（走 PulseAudio）
echo &amp;quot;test&amp;quot; | festival --tts
# 或用 ALSA 的 plughw（允许混音，不冲突）
speaker-test -D plughw:0,0 -c 2 -t wav -l 1
aplay -D hw:0,3 &amp;#x2F;usr&amp;#x2F;share&amp;#x2F;sounds&amp;#x2F;alsa&amp;#x2F;Front_Left.wav

# HDMI设备参数 
aplay -D hw:0,3 --dump-hw-params
# 强制 ALSA 探测 HDMI 音频（加 probe_mask）
# 创建配置文件
echo &amp;quot;options snd_hda_intel probe_mask=0xfff&amp;quot; | sudo tee &amp;#x2F;etc&amp;#x2F;modprobe.d&amp;#x2F;99-hdmi-audio.conf
# 重启（必须！）
sudo reboot

amixer -c 0 scontents

pactl list sink-inputs short
# 强制把 Chrome 流切回内置声卡
# 先获取 Chrome 的 sink-input index（如上面的 42）
# 再获取目标 sink 名称（如 alsa_output.pci-0000_00_1f.3.analog-stereo）
pactl move-sink-input 42 alsa_output.pci-0000_00_1f.3.analog-stereo
# 0 表示 取消挂起
pactl suspend-sink alsa_output.pci-0000_00_1f.3.analog-stereo 0

lsof &amp;#x2F;dev&amp;#x2F;snd&amp;#x2F;*
fuser -v &amp;#x2F;dev&amp;#x2F;snd&amp;#x2F;*
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>cloudflare 地址和端口范围</title>
        <published>2025-11-14T00:45:38+08:00</published>
        <updated>2025-11-14T00:45:38+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/11/cloudflare 地址和端口范围/"/>
        <id>https://vercel.juzhong.xyz/2025/11/cloudflare 地址和端口范围/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/11/cloudflare 地址和端口范围/">&lt;p&gt;cloudflare常用端口&lt;&#x2F;p&gt;
&lt;h2 id=&quot;http-ports-supported-by-cloudflare&quot;&gt;HTTP ports supported by Cloudflare&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;80 8080 8880 2052 2082 2086 2095&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;https-ports-supported-by-cloudflare&quot;&gt;HTTPS ports supported by Cloudflare&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;443 2053 2083 2087 2096 8443&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;ports-supported-by-cloudflare-but-with-caching-disabled&quot;&gt;Ports supported by Cloudflare, but with caching disabled&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;2052 2053 2082 2083 2086 2087 2095 2096 8880 8443&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;https:&#x2F;&#x2F;developers.cloudflare.com&#x2F;fundamentals&#x2F;reference&#x2F;network-ports&#x2F;&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.cloudflare-cn.com&#x2F;ips&#x2F;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>sing-box 手动配置(deb安装)</title>
        <published>2025-11-12T23:10:15+08:00</published>
        <updated>2025-11-12T23:10:15+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/11/learn/sing-box 手动配置(deb安装)/"/>
        <id>https://vercel.juzhong.xyz/2025/11/learn/sing-box 手动配置(deb安装)/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/11/learn/sing-box 手动配置(deb安装)/">&lt;h1 id=&quot;an-zhuang-sing-box-zhi-jie-an-zhuang-dao-xi-tong-mu-lu&quot;&gt;安装sing-box(直接安装到系统目录)&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo mkdir -p &amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;keyrings &amp;amp;&amp;amp;
   sudo curl -fsSL https:&amp;#x2F;&amp;#x2F;sing-box.app&amp;#x2F;gpg.key -o &amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;keyrings&amp;#x2F;sagernet.asc &amp;amp;&amp;amp;
   sudo chmod a+r &amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;keyrings&amp;#x2F;sagernet.asc &amp;amp;&amp;amp;
   echo &amp;#x27;
Types: deb
URIs: https:&amp;#x2F;&amp;#x2F;deb.sagernet.org&amp;#x2F;
Suites: *
Components: *
Enabled: yes
Signed-By: &amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;keyrings&amp;#x2F;sagernet.asc
&amp;#x27; | sudo tee &amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;sources.list.d&amp;#x2F;sagernet.sources &amp;amp;&amp;amp;
   sudo apt-get update &amp;amp;&amp;amp;
   sudo apt-get install sing-box # or sing-box-beta

# manual install
curl -fsSL https:&amp;#x2F;&amp;#x2F;sing-box.app&amp;#x2F;install.sh | sh
curl -fsSL https:&amp;#x2F;&amp;#x2F;sing-box.app&amp;#x2F;install.sh | sh -s -- --version 1.12.12
sudo mkdir -p &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;sing-box&amp;#x2F; &amp;#x2F;etc&amp;#x2F;sing-box&amp;#x2F;
sudo systemctl start sing-box

# 使用233boy 脚本生成配置时遇到了systemd-unit冲突， 修改了233boy脚本中的unit位置为&amp;#x2F;etc&amp;#x2F;
&amp;#x2F;etc&amp;#x2F;sing-box&amp;#x2F;sh&amp;#x2F;src&amp;#x2F;systemd.sh
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;anytls-reality-pei-zhi&quot;&gt;anytls reality 配置&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;sheng-cheng-reality-keypair&quot;&gt;生成reality keypair&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;sing-box generate reality-keypair | tee ~&amp;#x2F;.tmp&amp;#x2F;anytls-reality-keypair.txt
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;anytls-reality-server-pei-zhi&quot;&gt;anytls-reality server 配置&lt;&#x2F;h2&gt;
&lt;p&gt;修改password private_key short_id&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;json&quot; class=&quot;language-json &quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;cat &amp;lt;&amp;lt;EOF | sudo tee &amp;#x2F;etc&amp;#x2F;sing-box&amp;#x2F;anytls-reality.json 
{
    &amp;quot;inbounds&amp;quot;: [
        {
            &amp;quot;type&amp;quot;: &amp;quot;anytls&amp;quot;,
            &amp;quot;listen&amp;quot;: &amp;quot;::&amp;quot;,
            &amp;quot;listen_port&amp;quot;: 56443,
            &amp;quot;users&amp;quot;: [
                {
                    &amp;quot;name&amp;quot;: &amp;quot;user&amp;quot;,
                    &amp;quot;password&amp;quot;: &amp;quot;123456&amp;quot;
                }
            ],
            &amp;quot;padding_scheme&amp;quot;: [
                &amp;quot;stop=8&amp;quot;,
                &amp;quot;0=30-30&amp;quot;,
                &amp;quot;1=100-400&amp;quot;,
                &amp;quot;2=400-500,c,500-1000,c,500-1000,c,500-1000,c,500-1000&amp;quot;,
                &amp;quot;3=9-9,500-1000&amp;quot;,
                &amp;quot;4=500-1000&amp;quot;,
                &amp;quot;5=500-1000&amp;quot;,
                &amp;quot;6=500-1000&amp;quot;,
                &amp;quot;7=500-1000&amp;quot;
            ],
            &amp;quot;tls&amp;quot;: {
                &amp;quot;enabled&amp;quot;: true,
                &amp;quot;server_name&amp;quot;: &amp;quot;yahoo.com&amp;quot;,
                &amp;quot;reality&amp;quot;: {
                    &amp;quot;enabled&amp;quot;: true,
                    &amp;quot;handshake&amp;quot;: {
                        &amp;quot;server&amp;quot;: &amp;quot;yahoo.com&amp;quot;,
                        &amp;quot;server_port&amp;quot;: 443
                    },
                    &amp;quot;private_key&amp;quot;: &amp;quot;eO3B3EMGXrYfGOe87NkUVusaeUxtLB4vxiqjVXqb9GU&amp;quot;,
                    &amp;quot;short_id&amp;quot;: &amp;quot;0123456789abcdef&amp;quot;
                }
            }
        }
    ]
}
EOF
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;anytls-reality-client-pei-zhi&quot;&gt;anytls-reality client 配置&lt;&#x2F;h2&gt;
&lt;p&gt;修改server password public_key short_id&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;json&quot; class=&quot;language-json &quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;sudo tee &amp;#x2F;etc&amp;#x2F;sing-box&amp;#x2F;client-anytls-reality.json &amp;lt;&amp;lt;EOF
{
    &amp;quot;outbounds&amp;quot;: [
        {
            &amp;quot;type&amp;quot;: &amp;quot;anytls&amp;quot;,
            &amp;quot;tag&amp;quot;: &amp;quot;anytls-out&amp;quot;,
            &amp;quot;server&amp;quot;: &amp;quot;10.32.118.200&amp;quot;,
            &amp;quot;server_port&amp;quot;: 56443,
            &amp;quot;password&amp;quot;: &amp;quot;123456&amp;quot;,
            &amp;quot;idle_session_check_interval&amp;quot;: &amp;quot;30s&amp;quot;,
            &amp;quot;idle_session_timeout&amp;quot;: &amp;quot;30s&amp;quot;,
            &amp;quot;min_idle_session&amp;quot;: 5,
            &amp;quot;tls&amp;quot;: {
                &amp;quot;enabled&amp;quot;: true,
                &amp;quot;disable_sni&amp;quot;: false,
                &amp;quot;server_name&amp;quot;: &amp;quot;yahoo.com&amp;quot;,
                &amp;quot;insecure&amp;quot;: false,
                &amp;quot;utls&amp;quot;: {
                    &amp;quot;enabled&amp;quot;: true,
                    &amp;quot;fingerprint&amp;quot;: &amp;quot;chrome&amp;quot;
                },
                &amp;quot;reality&amp;quot;: {
                    &amp;quot;enabled&amp;quot;: true,
                    &amp;quot;public_key&amp;quot;: &amp;quot;u4v3a_-uhIXPE2RoGaNy9_W5EK5UYV_hVN4Vpei75lM&amp;quot;,
                    &amp;quot;short_id&amp;quot;: &amp;quot;0123456789abcdef&amp;quot;
                }
            }
        }
    ]
}
EOF
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;vless-reality-pei-zhi&quot;&gt;vless-reality 配置&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;sing-box generate uuid
&amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;sing-box generate reality-keypair | tee ~&amp;#x2F;.tmp&amp;#x2F;vless-reality-keypair.txt
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;vless-reality-server-pei-zhi&quot;&gt;vless-reality server 配置&lt;&#x2F;h2&gt;
&lt;p&gt;修改password private_key short_id&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;json&quot; class=&quot;language-json &quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;cat &amp;lt;&amp;lt;EOF | sudo tee &amp;#x2F;etc&amp;#x2F;sing-box&amp;#x2F;vless-reality.json 
{
    &amp;quot;inbounds&amp;quot;: [
    {
      &amp;quot;tag&amp;quot;: &amp;quot;VLESS-REALITY-33584.json&amp;quot;,
      &amp;quot;type&amp;quot;: &amp;quot;vless&amp;quot;,
      &amp;quot;listen&amp;quot;: &amp;quot;::&amp;quot;,
      &amp;quot;listen_port&amp;quot;: 33584,
      &amp;quot;users&amp;quot;: [
        {
          &amp;quot;flow&amp;quot;: &amp;quot;xtls-rprx-vision&amp;quot;,
          &amp;quot;uuid&amp;quot;: &amp;quot;xxxxxxxx-cbef-4811-a3f0-d10733e669cd&amp;quot;
        }
      ],
      &amp;quot;tls&amp;quot;: {
        &amp;quot;enabled&amp;quot;: true,
        &amp;quot;server_name&amp;quot;: &amp;quot;aws.amazon.com&amp;quot;,
        &amp;quot;reality&amp;quot;: {
          &amp;quot;enabled&amp;quot;: true,
          &amp;quot;handshake&amp;quot;: {
            &amp;quot;server&amp;quot;: &amp;quot;aws.amazon.com&amp;quot;,
            &amp;quot;server_port&amp;quot;: 443
          },
          &amp;quot;private_key&amp;quot;: &amp;quot;xxxxxxxx_GoOG9l7xvyT_zJuh4wyHyacXGdUWiuhJGg&amp;quot;,
          &amp;quot;short_id&amp;quot;: [
            &amp;quot;&amp;quot;
          ]
        }
      }
    }
  ]
}
EOF
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;vless-reality-client-duan-ji-chu-pei-zhi&quot;&gt;vless reality client 端基础配置&lt;&#x2F;h2&gt;
&lt;p&gt;修改uuid public_key&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;json&quot; class=&quot;language-json &quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;sudo tee &amp;#x2F;etc&amp;#x2F;sing-box&amp;#x2F;client-vless-reality.json &amp;lt;&amp;lt;EOF
{
    &amp;quot;outbounds&amp;quot;: [
        {
            &amp;quot;type&amp;quot;: &amp;quot;vless&amp;quot;,
            &amp;quot;tag&amp;quot;: &amp;quot;vless-out&amp;quot;,
            &amp;quot;server&amp;quot;: &amp;quot;10.50.228.53&amp;quot;,
            &amp;quot;server_port&amp;quot;: 13584,
            &amp;quot;uuid&amp;quot;: &amp;quot;211d952d-cbef-4811-a3f0-xxxxxxxxxxxx&amp;quot;,
            &amp;quot;flow&amp;quot;: &amp;quot;xtls-rprx-vision&amp;quot;,
            &amp;quot;network&amp;quot;: &amp;quot;tcp&amp;quot;,
            &amp;quot;tls&amp;quot;: {
                &amp;quot;enabled&amp;quot;: true,
                &amp;quot;disable_sni&amp;quot;: false,
                &amp;quot;server_name&amp;quot;: &amp;quot;aws.amazon.com&amp;quot;,
                &amp;quot;utls&amp;quot;: {
                &amp;quot;enabled&amp;quot;: true,
                &amp;quot;fingerprint&amp;quot;: &amp;quot;chrome&amp;quot;
                },
                &amp;quot;reality&amp;quot;: {
                &amp;quot;enabled&amp;quot;: true,
                &amp;quot;public_key&amp;quot;: &amp;quot;xxxxxx-3J5ReO_EpOBSix7PYhFOzaor0r8xQtEUdjS8&amp;quot;,
                &amp;quot;short_id&amp;quot;: &amp;quot;&amp;quot;
                }
            }
        }
    ]
}
EOF
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;vless-ws-tls-pei-zhi&quot;&gt;vless-ws-tls 配置&lt;&#x2F;h1&gt;
&lt;h1 id=&quot;anytls-ws-tls-pei-zhi&quot;&gt;anytls-ws-tls 配置&lt;&#x2F;h1&gt;
&lt;h1 id=&quot;xhttp-pei-zhi&quot;&gt;xhttp 配置&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;xhttp-fu-wu-duan-pei-zhi&quot;&gt;xhttp 服务端配置&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;json&quot; class=&quot;language-json &quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;sudo tee &amp;#x2F;etc&amp;#x2F;sing-box&amp;#x2F;client-xhttp-tls.json &amp;lt;&amp;lt;EOF
{
  &amp;quot;inbounds&amp;quot;: [
    {
      &amp;quot;tag&amp;quot;: &amp;quot;VLESS-HTTPUpgrade-TLS-box2.peter.com.json&amp;quot;,
      &amp;quot;type&amp;quot;: &amp;quot;vless&amp;quot;,
      &amp;quot;listen&amp;quot;: &amp;quot;0.0.0.0&amp;quot;,
      &amp;quot;listen_port&amp;quot;: 443,
      &amp;quot;users&amp;quot;: [
        {
          &amp;quot;uuid&amp;quot;: &amp;quot;a1b9a65d-e65a-409c-92e3-c038dd808642&amp;quot;
        }
      ],
      &amp;quot;transport&amp;quot;: {
        &amp;quot;type&amp;quot;: &amp;quot;httpupgrade&amp;quot;,
        &amp;quot;path&amp;quot;: &amp;quot;&amp;#x2F;xxxxxxxx-e65a-409c-92e3-c038dd808642&amp;quot;,
        &amp;quot;headers&amp;quot;: {
          &amp;quot;host&amp;quot;: &amp;quot;box2.peter.com&amp;quot;
        }
      },
      &amp;quot;tls&amp;quot;: {
        &amp;quot;enabled&amp;quot;: true,
        &amp;quot;server_name&amp;quot;: &amp;quot;box2.peter.com&amp;quot;,
        &amp;quot;alpn&amp;quot;: [&amp;quot;h2&amp;quot;]
      }
    }
  ]
}

EOF
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;xhttp-ke-hu-duan-pei-zhi&quot;&gt;xhttp 客户端配置&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;json&quot; class=&quot;language-json &quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;sudo tee &amp;#x2F;etc&amp;#x2F;sing-box&amp;#x2F;client-xhttp-tls.json &amp;lt;&amp;lt;EOF
{
  &amp;quot;outbounds&amp;quot;: [
    {
      &amp;quot;server&amp;quot;: &amp;quot;www.visa.com&amp;quot;,
      &amp;quot;server_port&amp;quot;: 443,
      &amp;quot;uuid&amp;quot;: &amp;quot;xxxxxxxx-e65a-409c-92e3-c038dd808642&amp;quot;,
      &amp;quot;packet_encoding&amp;quot;: &amp;quot;xudp&amp;quot;,
      &amp;quot;type&amp;quot;: &amp;quot;vless&amp;quot;,
      &amp;quot;tag&amp;quot;: &amp;quot;proxy&amp;quot;,
      &amp;quot;tls&amp;quot;: {
        &amp;quot;enabled&amp;quot;: true,
        &amp;quot;server_name&amp;quot;: &amp;quot;box2.peter.com&amp;quot;,
        &amp;quot;insecure&amp;quot;: false
      },
      &amp;quot;transport&amp;quot;: {
        &amp;quot;type&amp;quot;: &amp;quot;httpupgrade&amp;quot;,
        &amp;quot;host&amp;quot;: &amp;quot;box2.peter.com&amp;quot;,
        &amp;quot;path&amp;quot;: &amp;quot;&amp;#x2F;xxxxxxxx-e65a-409c-92e3-c038dd808642&amp;quot;
      }
    }
  ]
}
EOF
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;hysteria2-pei-zhi&quot;&gt;hysteria2 配置&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;hysteria2-server-pei-zhi&quot;&gt;hysteria2 server 配置&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;json&quot; class=&quot;language-json &quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;{
  &amp;quot;inbounds&amp;quot;: [
    {
      &amp;quot;tag&amp;quot;: &amp;quot;Hysteria2-55003.json&amp;quot;,
      &amp;quot;type&amp;quot;: &amp;quot;hysteria2&amp;quot;,
      &amp;quot;listen&amp;quot;: &amp;quot;::&amp;quot;,
      &amp;quot;listen_port&amp;quot;: 55003,
      &amp;quot;users&amp;quot;: [
        {
          &amp;quot;password&amp;quot;: &amp;quot;xxxxxxxx-c295-4b16-a518-b721343e7d1c&amp;quot;
        }
      ],
      &amp;quot;tls&amp;quot;: {
        &amp;quot;enabled&amp;quot;: true,
        &amp;quot;alpn&amp;quot;: [
          &amp;quot;h3&amp;quot;
        ],
        &amp;quot;key_path&amp;quot;: &amp;quot;&amp;#x2F;etc&amp;#x2F;sing-box&amp;#x2F;bin&amp;#x2F;tls.key&amp;quot;,
        &amp;quot;certificate_path&amp;quot;: &amp;quot;&amp;#x2F;etc&amp;#x2F;sing-box&amp;#x2F;bin&amp;#x2F;tls.cer&amp;quot;
      }
    }
  ]
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;hysteria2-client-pei-zhi&quot;&gt;hysteria2 client 配置&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;json&quot; class=&quot;language-json &quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;{
  &amp;quot;outbounds&amp;quot;: [
    {
      &amp;quot;type&amp;quot;: &amp;quot;hysteria2&amp;quot;,
      &amp;quot;server&amp;quot;: &amp;quot;10.50.228.53&amp;quot;,
      &amp;quot;server_port&amp;quot;: 55003,
      &amp;quot;up_mbps&amp;quot;: 100,
      &amp;quot;down_mbps&amp;quot;: 100,
      &amp;quot;password&amp;quot;: &amp;quot;xxxxxxxx-c295-4b16-a518-b721343e7d1c&amp;quot;,
      &amp;quot;tls&amp;quot;: {
        &amp;quot;enabled&amp;quot;: true,
        &amp;quot;insecure&amp;quot;:true
      }
    }

  ]
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;grpc-pei-zhi&quot;&gt;grpc 配置&lt;&#x2F;h1&gt;
&lt;h1 id=&quot;client-ji-chu-pei-zhi&quot;&gt;client 基础配置&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;json&quot; class=&quot;language-json &quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;sudo tee &amp;#x2F;etc&amp;#x2F;sing-box&amp;#x2F;client-config.json &amp;lt;&amp;lt;EOF
{
  &amp;quot;log&amp;quot;: {
    &amp;quot;disabled&amp;quot;: false,
    &amp;quot;level&amp;quot;: &amp;quot;debug&amp;quot;,
    &amp;quot;output&amp;quot;: &amp;quot;&amp;quot;,
    &amp;quot;timestamp&amp;quot;: true
  },
  &amp;quot;experimental&amp;quot;: {
    &amp;quot;clash_api&amp;quot;: {
      &amp;quot;external_controller&amp;quot;: &amp;quot;127.0.0.1:10807&amp;quot;,
      &amp;quot;external_ui&amp;quot;: &amp;quot;ui&amp;quot;,
      &amp;quot;external_ui_download_url&amp;quot;: &amp;quot;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;MetaCubeX&amp;#x2F;metacubexd&amp;#x2F;archive&amp;#x2F;gh-pages.zip&amp;quot;,
      &amp;quot;external_ui_download_detour&amp;quot;: &amp;quot;vless-out&amp;quot;,
      &amp;quot;default_mode&amp;quot;: &amp;quot;rule&amp;quot;,
      &amp;quot;access_control_allow_origin&amp;quot;: [ &amp;quot;*&amp;quot; ],
      &amp;quot;access_control_allow_private_network&amp;quot;: false
    },
    &amp;quot;cache_file&amp;quot;: {
      &amp;quot;enabled&amp;quot;: true,
      &amp;quot;path&amp;quot;: &amp;quot;cache.db&amp;quot;,
      &amp;quot;cache_id&amp;quot;: &amp;quot;&amp;quot;,
      &amp;quot;store_fakeip&amp;quot;: true,
      &amp;quot;store_rdrc&amp;quot;: true,
      &amp;quot;rdrc_timeout&amp;quot;: &amp;quot;7d&amp;quot;
    }
  },
  &amp;quot;inbounds&amp;quot;: [
    {
      &amp;quot;address&amp;quot;: [&amp;quot;172.18.0.1&amp;#x2F;30&amp;quot;, &amp;quot;fdfe:dcba:9876::1&amp;#x2F;126&amp;quot;],
      &amp;quot;route_address&amp;quot;: [&amp;quot;0.0.0.0&amp;#x2F;1&amp;quot;, &amp;quot;128.0.0.0&amp;#x2F;1&amp;quot;, &amp;quot;::&amp;#x2F;1&amp;quot;, &amp;quot;8000::&amp;#x2F;1&amp;quot;],
      &amp;quot;route_exclude_address&amp;quot;: [
        &amp;quot;192.168.0.0&amp;#x2F;16&amp;quot;,
        &amp;quot;10.0.0.0&amp;#x2F;8&amp;quot;,
        &amp;quot;172.16.0.0&amp;#x2F;12&amp;quot;,
        &amp;quot;fc00::&amp;#x2F;7&amp;quot;
      ],
      &amp;quot;auto_route&amp;quot;: true,
      &amp;quot;strict_route&amp;quot;: true,
      &amp;quot;type&amp;quot;: &amp;quot;tun&amp;quot;
    },
    {
      &amp;quot;type&amp;quot;: &amp;quot;mixed&amp;quot;,
      &amp;quot;tag&amp;quot;: &amp;quot;mixed-in&amp;quot;,
      &amp;quot;listen&amp;quot;: &amp;quot;127.0.0.1&amp;quot;,
      &amp;quot;listen_port&amp;quot;: 10806,
      &amp;quot;tcp_fast_open&amp;quot;: false,
      &amp;quot;tcp_multi_path&amp;quot;: false,
      &amp;quot;udp_fragment&amp;quot;: false
    }
  ],
  &amp;quot;outbounds&amp;quot;: [
    {
      &amp;quot;type&amp;quot;: &amp;quot;selector&amp;quot;,
      &amp;quot;tag&amp;quot;: &amp;quot;🚀 Select&amp;quot;,
      &amp;quot;interrupt_exist_connections&amp;quot;: true,
      &amp;quot;outbounds&amp;quot;: [
        &amp;quot;vless-out&amp;quot;,
        &amp;quot;🎈 Auto&amp;quot;
      ]
    },
    {
      &amp;quot;type&amp;quot;: &amp;quot;urltest&amp;quot;,
      &amp;quot;tag&amp;quot;: &amp;quot;🎈 Auto&amp;quot;,
      &amp;quot;url&amp;quot;: &amp;quot;https:&amp;#x2F;&amp;#x2F;www.gstatic.com&amp;#x2F;generate_204&amp;quot;,
      &amp;quot;interval&amp;quot;: &amp;quot;3m&amp;quot;,
      &amp;quot;tolerance&amp;quot;: 150,
      &amp;quot;interrupt_exist_connections&amp;quot;: true,
      &amp;quot;outbounds&amp;quot;: [
        &amp;quot;vless-out&amp;quot;
      ]
    },
    {
      &amp;quot;type&amp;quot;: &amp;quot;direct&amp;quot;,
      &amp;quot;tag&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
    },
    {
      &amp;quot;type&amp;quot;: &amp;quot;selector&amp;quot;,
      &amp;quot;tag&amp;quot;: &amp;quot;🐟 Fallback&amp;quot;,
      &amp;quot;interrupt_exist_connections&amp;quot;: true,
      &amp;quot;outbounds&amp;quot;: [
        &amp;quot;🚀 Select&amp;quot;,
        &amp;quot;🎯 Direct&amp;quot;
      ]
    },
    {
      &amp;quot;type&amp;quot;: &amp;quot;selector&amp;quot;,
      &amp;quot;tag&amp;quot;: &amp;quot;GLOBAL&amp;quot;,
      &amp;quot;interrupt_exist_connections&amp;quot;: true,
      &amp;quot;outbounds&amp;quot;: [
        &amp;quot;🚀 Select&amp;quot;,
        &amp;quot;🎈 Auto&amp;quot;,
        &amp;quot;🎯 Direct&amp;quot;,
        &amp;quot;🐟 Fallback&amp;quot;
      ]
    },
  ],
  &amp;quot;route&amp;quot;: {
    &amp;quot;rules&amp;quot;: [
      {
        &amp;quot;action&amp;quot;: &amp;quot;hijack-dns&amp;quot;,
        &amp;quot;protocol&amp;quot;: &amp;quot;dns&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;clash_mode&amp;quot;: &amp;quot;direct&amp;quot;,
        &amp;quot;outbound&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;clash_mode&amp;quot;: &amp;quot;global&amp;quot;,
        &amp;quot;outbound&amp;quot;: &amp;quot;GLOBAL&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;network&amp;quot;: &amp;quot;icmp&amp;quot;,
        &amp;quot;outbound&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;reject&amp;quot;,
        &amp;quot;protocol&amp;quot;: &amp;quot;quic&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;reject&amp;quot;,
        &amp;quot;rule_set&amp;quot;: [
          &amp;quot;Category-Ads&amp;quot;
        ]
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;rule_set&amp;quot;: [
          &amp;quot;GeoSite-Private&amp;quot;
        ],
        &amp;quot;outbound&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;rule_set&amp;quot;: [
          &amp;quot;GeoSite-CN&amp;quot;
        ],
        &amp;quot;outbound&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;rule_set&amp;quot;: [
          &amp;quot;GeoIP-Private&amp;quot;
        ],
        &amp;quot;outbound&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;rule_set&amp;quot;: [
          &amp;quot;GeoIP-CN&amp;quot;
        ],
        &amp;quot;outbound&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;rule_set&amp;quot;: [
          &amp;quot;GeoLocation-!CN&amp;quot;
        ],
        &amp;quot;outbound&amp;quot;: &amp;quot;🚀 Select&amp;quot;
      }
    ],
    &amp;quot;rule_set&amp;quot;: [
      {
        &amp;quot;tag&amp;quot;: &amp;quot;Category-Ads&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;remote&amp;quot;,
        &amp;quot;url&amp;quot;: &amp;quot;https:&amp;#x2F;&amp;#x2F;testingcf.jsdelivr.net&amp;#x2F;gh&amp;#x2F;MetaCubeX&amp;#x2F;meta-rules-dat@sing&amp;#x2F;geo&amp;#x2F;geosite&amp;#x2F;category-ads-all.srs&amp;quot;,
        &amp;quot;format&amp;quot;: &amp;quot;binary&amp;quot;,
        &amp;quot;download_detour&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;tag&amp;quot;: &amp;quot;GeoIP-Private&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;remote&amp;quot;,
        &amp;quot;url&amp;quot;: &amp;quot;https:&amp;#x2F;&amp;#x2F;testingcf.jsdelivr.net&amp;#x2F;gh&amp;#x2F;MetaCubeX&amp;#x2F;meta-rules-dat@sing&amp;#x2F;geo&amp;#x2F;geoip&amp;#x2F;private.srs&amp;quot;,
        &amp;quot;format&amp;quot;: &amp;quot;binary&amp;quot;,
        &amp;quot;download_detour&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;tag&amp;quot;: &amp;quot;GeoSite-Private&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;remote&amp;quot;,
        &amp;quot;url&amp;quot;: &amp;quot;https:&amp;#x2F;&amp;#x2F;testingcf.jsdelivr.net&amp;#x2F;gh&amp;#x2F;MetaCubeX&amp;#x2F;meta-rules-dat@sing&amp;#x2F;geo&amp;#x2F;geosite&amp;#x2F;private.srs&amp;quot;,
        &amp;quot;format&amp;quot;: &amp;quot;binary&amp;quot;,
        &amp;quot;download_detour&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;tag&amp;quot;: &amp;quot;GeoIP-CN&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;remote&amp;quot;,
        &amp;quot;url&amp;quot;: &amp;quot;https:&amp;#x2F;&amp;#x2F;testingcf.jsdelivr.net&amp;#x2F;gh&amp;#x2F;MetaCubeX&amp;#x2F;meta-rules-dat@sing&amp;#x2F;geo&amp;#x2F;geoip&amp;#x2F;cn.srs&amp;quot;,
        &amp;quot;format&amp;quot;: &amp;quot;binary&amp;quot;,
        &amp;quot;download_detour&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;tag&amp;quot;: &amp;quot;GeoSite-CN&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;remote&amp;quot;,
        &amp;quot;url&amp;quot;: &amp;quot;https:&amp;#x2F;&amp;#x2F;testingcf.jsdelivr.net&amp;#x2F;gh&amp;#x2F;MetaCubeX&amp;#x2F;meta-rules-dat@sing&amp;#x2F;geo&amp;#x2F;geosite&amp;#x2F;cn.srs&amp;quot;,
        &amp;quot;format&amp;quot;: &amp;quot;binary&amp;quot;,
        &amp;quot;download_detour&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;tag&amp;quot;: &amp;quot;GeoLocation-!CN&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;remote&amp;quot;,
        &amp;quot;url&amp;quot;: &amp;quot;https:&amp;#x2F;&amp;#x2F;testingcf.jsdelivr.net&amp;#x2F;gh&amp;#x2F;MetaCubeX&amp;#x2F;meta-rules-dat@sing&amp;#x2F;geo&amp;#x2F;geosite&amp;#x2F;geolocation-!cn.srs&amp;quot;,
        &amp;quot;format&amp;quot;: &amp;quot;binary&amp;quot;,
        &amp;quot;download_detour&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      }
    ],
    &amp;quot;auto_detect_interface&amp;quot;: true,
    &amp;quot;final&amp;quot;: &amp;quot;🐟 Fallback&amp;quot;,
    &amp;quot;default_domain_resolver&amp;quot;: {
      &amp;quot;server&amp;quot;: &amp;quot;Local-DNS&amp;quot;
    }
  },
  &amp;quot;dns&amp;quot;: {
    &amp;quot;servers&amp;quot;: [
      {
        &amp;quot;tag&amp;quot;: &amp;quot;Local-DNS&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;https&amp;quot;,
        &amp;quot;domain_resolver&amp;quot;: &amp;quot;Local-DNS-Resolver&amp;quot;,
        &amp;quot;server_port&amp;quot;: 443,
        &amp;quot;server&amp;quot;: &amp;quot;223.5.5.5&amp;quot;,
        &amp;quot;path&amp;quot;: &amp;quot;&amp;#x2F;dns-query&amp;quot;
      },
      {
        &amp;quot;tag&amp;quot;: &amp;quot;Local-DNS-Resolver&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;udp&amp;quot;,
        &amp;quot;server_port&amp;quot;: 53,
        &amp;quot;server&amp;quot;: &amp;quot;223.5.5.5&amp;quot;
      },
      {
        &amp;quot;tag&amp;quot;: &amp;quot;Remote-DNS&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;tls&amp;quot;,
        &amp;quot;detour&amp;quot;: &amp;quot;🚀 Select&amp;quot;,
        &amp;quot;domain_resolver&amp;quot;: &amp;quot;Remote-DNS-Resolver&amp;quot;,
        &amp;quot;server_port&amp;quot;: 853,
        &amp;quot;server&amp;quot;: &amp;quot;8.8.8.8&amp;quot;
      },
      {
        &amp;quot;tag&amp;quot;: &amp;quot;Remote-DNS-Resolver&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;udp&amp;quot;,
        &amp;quot;detour&amp;quot;: &amp;quot;🚀 Select&amp;quot;,
        &amp;quot;server_port&amp;quot;: 53,
        &amp;quot;server&amp;quot;: &amp;quot;8.8.8.8&amp;quot;
      }
    ],
    &amp;quot;rules&amp;quot;: [
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;clash_mode&amp;quot;: &amp;quot;direct&amp;quot;,
        &amp;quot;server&amp;quot;: &amp;quot;Local-DNS&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;clash_mode&amp;quot;: &amp;quot;global&amp;quot;,
        &amp;quot;server&amp;quot;: &amp;quot;Remote-DNS&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;rule_set&amp;quot;: [
          &amp;quot;GeoSite-CN&amp;quot;
        ],
        &amp;quot;server&amp;quot;: &amp;quot;Local-DNS&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;rule_set&amp;quot;: [
          &amp;quot;GeoLocation-!CN&amp;quot;
        ],
        &amp;quot;server&amp;quot;: &amp;quot;Remote-DNS&amp;quot;
      }
    ],
    &amp;quot;disable_cache&amp;quot;: false,
    &amp;quot;disable_expire&amp;quot;: false,
    &amp;quot;independent_cache&amp;quot;: false,
    &amp;quot;final&amp;quot;: &amp;quot;Remote-DNS&amp;quot;
  }
}
EOF
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;andriod-ban-ben-shi-yong&quot;&gt;andriod 版本使用&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;sing-box -C &amp;#x2F;etc&amp;#x2F;sing-box&amp;#x2F; merge ~&amp;#x2F;.tmp&amp;#x2F;sing-box.merge.conf
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>sunshine moonlight 配置linux第二屏幕</title>
        <published>2025-11-10T21:14:35+08:00</published>
        <updated>2025-11-10T21:14:35+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/11/sunshine moonlight 配置linux第二屏幕/"/>
        <id>https://vercel.juzhong.xyz/2025/11/sunshine moonlight 配置linux第二屏幕/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/11/sunshine moonlight 配置linux第二屏幕/">&lt;p&gt;安装sunshine和moonlight&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 服务端安装sunshine(需要扩展屏幕主机)
# https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;LizardByte&amp;#x2F;Sunshine&amp;#x2F;releases&amp;#x2F;tag&amp;#x2F;v2025.924.154138
sudo apt install .&amp;#x2F;sunshine-ubuntu-24.04-amd64.deb

# 客户端安装moonlight(作为第二屏幕的主机)
sudo flatpak install com.moonlight_stream.Moonlight
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;xu-ni-xian-shi-qi&quot;&gt;虚拟显示器？&lt;&#x2F;h1&gt;
&lt;p&gt;使用 Wayland + vkms + Weston headless&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;modinfo vkms | grep filename
sudo modprobe vkms
ls &amp;#x2F;sys&amp;#x2F;class&amp;#x2F;drm | grep card

# &amp;#x2F;etc&amp;#x2F;modprobe.d&amp;#x2F;vkms.conf
# 示例：创建两个 vkms 虚拟显示器
options vkms nodes=2

sudo apt install libdrm-tests
modetest -M vkms | grep -i connect
sudo apt install wlroots-utils
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;vainfo --display drm --device &amp;#x2F;dev&amp;#x2F;dri&amp;#x2F;renderD128
pactl info
sudo apt install -y x11-xserver-utils weston
# 主要是 modetest 检查 DRM 输出，Wayland 原生可以使用 wlr-randr 或 Weston 的虚拟输出测试
weston --backend=headless-backend.so --socket=wayland-headless-0
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt install edid-decode read-edid
sudo get-edid &amp;gt; &amp;#x2F;lib&amp;#x2F;firmware&amp;#x2F;edid&amp;#x2F;1080p.bin

sudo tee &amp;#x2F;etc&amp;#x2F;modprobe.d&amp;#x2F;vkms.conf &amp;lt;&amp;lt;&amp;#x27;EOF&amp;#x27;
options vkms enable_cursor=1 enable_overlay=1 edid_firmware=edid&amp;#x2F;1080p.bin
EOF

sudo modprobe -r vkms
sudo modprobe vkms

cat &amp;#x2F;sys&amp;#x2F;class&amp;#x2F;drm&amp;#x2F;card0-Virtual-1&amp;#x2F;edid | edid-decode

sudo cat &amp;#x2F;sys&amp;#x2F;kernel&amp;#x2F;debug&amp;#x2F;dri&amp;#x2F;0&amp;#x2F;state
modetest -M vkms -s 63@38:1920x1080

sudo udevadm trigger --subsystem-match=drm --action=change
sudo apt install drm-info
drm_info &amp;#x2F;dev&amp;#x2F;dri&amp;#x2F;card0
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;debian13-zhong-mei-you-vkms&quot;&gt;debian13 中没有vkms?&lt;&#x2F;h1&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;特性&lt;&#x2F;th&gt;&lt;th&gt;vkms&lt;&#x2F;th&gt;&lt;th&gt;virtio-gpu&lt;&#x2F;th&gt;&lt;th&gt;qxl&lt;&#x2F;th&gt;&lt;th&gt;dummy X11&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;驱动位置&lt;&#x2F;td&gt;&lt;td&gt;内核 DRM&lt;&#x2F;td&gt;&lt;td&gt;内核 DRM&lt;&#x2F;td&gt;&lt;td&gt;内核 DRM&lt;&#x2F;td&gt;&lt;td&gt;用户态 X11&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;显示输出&lt;&#x2F;td&gt;&lt;td&gt;✅ DRM 原生&lt;&#x2F;td&gt;&lt;td&gt;✅ DRM 原生&lt;&#x2F;td&gt;&lt;td&gt;✅ DRM 原生&lt;&#x2F;td&gt;&lt;td&gt;❌ 无 DRM 节点&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;硬件依赖&lt;&#x2F;td&gt;&lt;td&gt;无（纯虚拟）&lt;&#x2F;td&gt;&lt;td&gt;需虚拟化环境&lt;&#x2F;td&gt;&lt;td&gt;需 QEMU&#x2F;SPICE&lt;&#x2F;td&gt;&lt;td&gt;无&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;性能&lt;&#x2F;td&gt;&lt;td&gt;软件模拟，较慢&lt;&#x2F;td&gt;&lt;td&gt;中等&lt;&#x2F;td&gt;&lt;td&gt;中等&lt;&#x2F;td&gt;&lt;td&gt;慢&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Sunshine 兼容&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;⚠️ 需 Xwayland&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;GNOME 可识别&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;pei-zhi-kms&quot;&gt;配置KMS&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;在电脑上安装 Sunshine，平板上安装 Moonlight，确保能搜索到并能正常控制电脑；&lt;&#x2F;li&gt;
&lt;li&gt;用下面的命令枚举所有设备接口的连接情况，选择一个未连接（disconnected）的 HDMI 接口（如 HDMI-A-1），记下它：&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;for p in &amp;#x2F;sys&amp;#x2F;class&amp;#x2F;drm&amp;#x2F;*&amp;#x2F;status; do con=${p%&amp;#x2F;status}; echo -n &amp;quot;${con#*&amp;#x2F;card?-}: &amp;quot;; cat $p; done 
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;在 &#x2F;usr&#x2F;lib&#x2F;firmware&#x2F; 下创建一个新的 edid 目录（如果没有），并将你的 edid 文件放在那里。例如 &#x2F;usr&#x2F;lib&#x2F;firmware&#x2F;edid&#x2F;samsung-q800t-hdmi2.1；&lt;&#x2F;li&gt;
&lt;li&gt;编辑内核参数，添加以下内容。其中 HDMI-A-1 是你选择的接口，edid&#x2F;samsung-q800t-hdmi2.1 是你的 EDID 文件。注意不要漏了最后的 :e：&lt;&#x2F;li&gt;
&lt;li&gt;drm.edid_firmware=HDMI-A-1:edid&#x2F;samsung-q800t-hdmi2.1 video=HDMI-A-1:e&lt;&#x2F;li&gt;
&lt;li&gt;重启电脑。如果一切正常，你的电脑会认为有一个新的 HDMI 显示器连接上了，而实际上它是一个虚拟显示器；&lt;&#x2F;li&gt;
&lt;li&gt;在命令行中运行 sunshine，查看其输出的 KMS Monitor List，找到你的 HDMI 接口对应的编号，停止 Sunshine；&lt;&#x2F;li&gt;
&lt;li&gt;在正常启动的 Sunshine 的设置中填入上一步的编号，应用设置，确定其投屏的来源是你的虚拟显示器。&lt;&#x2F;li&gt;
&lt;li&gt;这样就完成了，你可以在 KDE 设置中像普通显示器那样配置该虚拟显示器的分辨率和空间位置，甚至可以在不用时禁用该显示器。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre&gt;&lt;code&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>linux 中的seat管理</title>
        <published>2025-11-06T21:53:55+08:00</published>
        <updated>2025-11-06T21:53:55+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/11/linux 中的seat管理/"/>
        <id>https://vercel.juzhong.xyz/2025/11/linux 中的seat管理/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/11/linux 中的seat管理/">&lt;h1 id=&quot;seatyi-ban-kong-zhi-na-xie-she-bei&quot;&gt;seat一般控制哪些设备&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;哪些设备属于一个 seat、由谁配置&#x2F;控制，是掌握 Linux 图形会话、多用户、多终端安全模型的关键&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Seat 管理的设备主要包括：GPU（DRM&#x2F;KMS）、输入设备（键盘&#x2F;鼠标&#x2F;触摸屏等）、声音设备（可选）和串口&#x2F;智能卡读卡器（高级场景）&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;这些设备的归属由 udev 规则标记，并由 systemd-logind 在运行时动态分配给活跃的图形会话（session）&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;图形设备	&#x2F;dev&#x2F;dri&#x2F;card0, &#x2F;dev&#x2F;dri&#x2F;renderD128	GPU，用于显示输出和硬件加速&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;输入设备	&#x2F;dev&#x2F;input&#x2F;event*	键盘、鼠标、触摸板、触控屏、Tablet 等&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;TTY 控制台	&#x2F;dev&#x2F;tty0, &#x2F;dev&#x2F;tty1 ...	虚拟终端（VT），seat 通常绑定到一个 VT&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;音频设备（可选）	&#x2F;dev&#x2F;snd&#x2F;*	某些系统将声卡绑定到 seat（非强制）&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;其他外设（可选）	&#x2F;dev&#x2F;ttyS0, &#x2F;dev&#x2F;usb&#x2F;hiddev*	如串口、智能卡读卡器（企业&#x2F;嵌入式场景）&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;⚠️ 注意：网络设备、存储设备（如 &#x2F;dev&#x2F;sda）不属于 seat，它们是全局共享的。&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;如果未设置 ID_SEAT，设备默认属于 seat0（主 seat）&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&#x2F;etc&#x2F;udev&#x2F;rules.d&#x2F;99-seat1.rules&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;将特定 USB 键鼠绑定到 seat1&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;SUBSYSTEM==&quot;input&quot;, ATTRS{idVendor}==&quot;abcd&quot;, ATTRS{idProduct}==&quot;1234&quot;, ENV{ID_SEAT}=&quot;seat1&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;将特定 GPU 绑定到 seat1&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;SUBSYSTEM==&quot;drm&quot;, KERNEL==&quot;card1&quot;, ENV{ID_SEAT}=&quot;seat1&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 列出所有 seats
loginctl list-seats
# 查看 seat0 的详细信息（含设备）
loginctl show-seat seat0 -p ActiveSession -p Devices

# 查看某个输入设备是否属于 seat0
udevadm info &amp;#x2F;dev&amp;#x2F;input&amp;#x2F;event4 | grep ID_SEAT
# 查看是否有 uaccess 标签
udevadm info &amp;#x2F;dev&amp;#x2F;dri&amp;#x2F;card0 | grep TAGS
# 输出应包含: :uaccess:

# 使用 loginctl 工具将一个设备永久地分配给一个特定的 Seat
loginctl attach [SEAT_ID] [DEVICE_SYSFS_PATH]
    [SEAT_ID]: 你想分配到的 Seat 名称，例如 seat1。
    [DEVICE_SYSFS_PATH]: 设备的 SysFS 路径，例如 &amp;#x2F;sys&amp;#x2F;devices&amp;#x2F;pci0000:00&amp;#x2F;...&amp;#x2F;drm&amp;#x2F;card1。
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;duo-seatkong-zhi-guan-li&quot;&gt;多seat控制管理&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;假设你有一台机器，接了两套显示器+键鼠：
&lt;ul&gt;
&lt;li&gt;Seat0：主板 HDMI + 内置键盘 → 用户 A 登录 GNOME&lt;&#x2F;li&gt;
&lt;li&gt;Seat1：PCIe 独立显卡 + USB 键鼠 → 用户 B 登录 Sway&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;你需要：
&lt;ul&gt;
&lt;li&gt;创建 udev 规则，将独显和 USB 设备标记为 ID_SEAT=seat1&lt;&#x2F;li&gt;
&lt;li&gt;启动两个图形会话（分别绑定到不同 TTY）&lt;&#x2F;li&gt;
&lt;li&gt;systemd-logind 自动为每个 session 授权对应设备&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;此时：
&lt;ul&gt;
&lt;li&gt;用户 A 无法看到用户 B 的屏幕内容；&lt;&#x2F;li&gt;
&lt;li&gt;用户 B 的键盘不会影响用户 A；&lt;&#x2F;li&gt;
&lt;li&gt;GPU 资源完全隔离。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>漏洞挖掘方法</title>
        <published>2025-11-05T15:49:12+08:00</published>
        <updated>2025-11-05T15:49:12+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/11/漏洞挖掘方法/"/>
        <id>https://vercel.juzhong.xyz/2025/11/漏洞挖掘方法/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/11/漏洞挖掘方法/">&lt;h1 id=&quot;lou-dong-wa-jue&quot;&gt;漏洞挖掘&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;软件成分分析
&lt;ul&gt;
&lt;li&gt;识别分析某一个软件中所使用的组件与第三方库的来源、版本、许可证信息的技术&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;已知漏洞(漏洞扫描)&lt;&#x2F;li&gt;
&lt;li&gt;静态分析&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>浏览器指纹</title>
        <published>2025-11-05T14:52:40+08:00</published>
        <updated>2025-11-05T14:52:40+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/11/浏览器指纹/"/>
        <id>https://vercel.juzhong.xyz/2025/11/浏览器指纹/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/11/浏览器指纹/">&lt;h1 id=&quot;liu-lan-qi-zhi-wen&quot;&gt;浏览器指纹&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;操作系统&lt;&#x2F;li&gt;
&lt;li&gt;cpu架构&lt;&#x2F;li&gt;
&lt;li&gt;系统支持的字体遍历&lt;&#x2F;li&gt;
&lt;li&gt;窗口大小、显示器大小&lt;&#x2F;li&gt;
&lt;li&gt;禁用 Canvas 图像提取&lt;&#x2F;li&gt;
&lt;li&gt;集成 NoScript 以及第一方域名隔离&lt;&#x2F;li&gt;
&lt;li&gt;利用字体、功能、行为特征等等（无论是否使用 JavaScript）&lt;&#x2F;li&gt;
&lt;li&gt;tls 指纹&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>gcc 参数</title>
        <published>2025-11-05T11:48:23+08:00</published>
        <updated>2025-11-05T11:48:23+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/11/gcc 参数/"/>
        <id>https://vercel.juzhong.xyz/2025/11/gcc 参数/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/11/gcc 参数/">&lt;h1 id=&quot;g-lian-jie-shi-start-grouphe-end-groupde-zuo-yong&quot;&gt;g++链接时，--start-group和--end-group的作用&lt;&#x2F;h1&gt;
&lt;p&gt;在使用g++进行链接时，库之间的符号依赖可能导致链接失败&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;例如，当库A依赖库B中的符号，而库B又需要库A中的符号时，传统的链接顺序无法满足这种循环依赖&lt;&#x2F;li&gt;
&lt;li&gt;此时，&lt;code&gt;--start-group&lt;&#x2F;code&gt;和&lt;code&gt;--end-group&lt;&#x2F;code&gt;选项就显得尤为重要&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;作用&lt;&#x2F;strong&gt;：它们告诉链接器在指定的组内反复扫描目标文件和库，直到不再有新的符号被解析为止，从而解决复杂的依赖问题&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;正确用法&lt;&#x2F;strong&gt;：将相关的目标文件或库放置在&lt;code&gt;--start-group&lt;&#x2F;code&gt;和&lt;code&gt;--end-group&lt;&#x2F;code&gt;之间&lt;&#x2F;li&gt;
&lt;li&gt;例如： &lt;code&gt;bash g++ -o myapp --start-group libA.a libB.a --end-group &lt;&#x2F;code&gt; 此命令确保&lt;code&gt;libA.a&lt;&#x2F;code&gt;和&lt;code&gt;libB.a&lt;&#x2F;code&gt;之间的依赖关系被正确解析，即使存在循环依赖。&lt;&#x2F;li&gt;
&lt;li&gt;忘记添加&lt;code&gt;--end-group&lt;&#x2F;code&gt;，链接器可能报错或行为异常；滥用该选项可能导致链接时间增加&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>vocabulary 常用专业术语</title>
        <published>2025-11-05T11:41:45+08:00</published>
        <updated>2025-11-05T11:41:45+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/11/vocabulary 常用专业术语/"/>
        <id>https://vercel.juzhong.xyz/2025/11/vocabulary 常用专业术语/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/11/vocabulary 常用专业术语/">&lt;h1 id=&quot;tls&quot;&gt;tls&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;KDF(Key derivation function) 密钥派生函数
&lt;ul&gt;
&lt;li&gt;可用于将密钥扩展到更长的密钥或获得所需格式的密钥&lt;&#x2F;li&gt;
&lt;li&gt;非秘密参数被称为盐&lt;&#x2F;li&gt;
&lt;li&gt;相比其他加密哈希算法，KDF 具有一个独特属性——计算速度很慢，而且从设计上就使其计算速度难以提升，所以 KDF 也被称作「慢哈希算法」&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;AEAD(Authenticated_Encrypted_with_associated_data)
&lt;ul&gt;
&lt;li&gt;chacha20poly1305&lt;&#x2F;li&gt;
&lt;li&gt;aes-gcm aes-ccm&lt;&#x2F;li&gt;
&lt;li&gt;在TLS1.3中，当使用如ChaCha20-Poly1305这样的AEAD加密套件时,已不再需要独立的 HMAC 运算&lt;&#x2F;li&gt;
&lt;li&gt;TLS 1.3在设计上移除了&quot;MAC-then-Encrypt&quot;的组合方式，这种组合曾被曝出存在 BEAST、Lucky 13 等安全漏洞&lt;&#x2F;li&gt;
&lt;li&gt;注意 AEAD 密码套件中的 HASH：
&lt;ul&gt;
&lt;li&gt;以TLS_CHACHA20_POLY1305_SHA256为例，其中的 SHA256不是用来对消息记录做HMAC认证的&lt;&#x2F;li&gt;
&lt;li&gt;这个SHA256是用于TLS握手过程中的密钥派生函数,特别是HKDF-Extract和HKDF-Expand，用来从握手产生的秘密信息中派生出会话密钥、nonce 等加密参数&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;HKDF（HMAC_based_key_derivation_function）&lt;&#x2F;li&gt;
&lt;li&gt;ECDHE(Ephemeral Elliptic Curve Diffie-Hellman ephemeral)
&lt;ul&gt;
&lt;li&gt;curve25519 x25519 ed25519&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;ai&quot;&gt;AI&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;RAG Retrieval-Augmented Generation&lt;&#x2F;li&gt;
&lt;li&gt;LoRA Low-Rank Adaptation&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>从pve切换到libvirt 问题排查</title>
        <published>2025-11-02T00:30:58+08:00</published>
        <updated>2025-11-02T00:30:58+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/11/从pve切换到libvirt 问题排查/"/>
        <id>https://vercel.juzhong.xyz/2025/11/从pve切换到libvirt 问题排查/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/11/从pve切换到libvirt 问题排查/">&lt;h1 id=&quot;qian-yi-xu-ni-ji-wen-ti-ji-lu&quot;&gt;迁移虚拟机问题记录&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 因为apparmor的限制 libvirt 访问&amp;#x2F;var&amp;#x2F;lib&amp;#x2F;vz&amp;#x2F;images目录会遇到权限问题, 所有将虚拟机文件迁移到libvirt目录中
# 可能会遇到pve中的模板文件移动失败: 修改attr后再执行
sudo chattr -i &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;vz&amp;#x2F;images&amp;#x2F;100&amp;#x2F;base-100-disk-0.qcow2
sudo lsattr &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;vz&amp;#x2F;images&amp;#x2F;100&amp;#x2F;base-100-disk-0.qcow2
sudo mv &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;vz&amp;#x2F;images&amp;#x2F;* &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;libvirt&amp;#x2F;images&amp;#x2F;

sudo chown libvirt-qemu:libvirt-qemu &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;libvirt&amp;#x2F;images&amp;#x2F;100&amp;#x2F;
sudo chmod 755 &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;libvirt&amp;#x2F;images&amp;#x2F;100

# 直接使用宿主机中的vmbr0网桥, 虚拟机无网络, 需要开启宿主机转发功能
sudo iptables -P FORWARD ACCEPT
sudo sysctl -w net.ipv4.ip_forward=1
sudo sysctl net | grep ip_forward

sudo apt netfilter-persistent
sudo netfilter-persistent save
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>rustc-wrapper(linker)解决cargo并行链接OOM问题</title>
        <published>2025-10-31T09:52:15+08:00</published>
        <updated>2025-10-31T09:52:15+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/10/rustc-wrapper(linker)解决cargo并行链接OOM问题/"/>
        <id>https://vercel.juzhong.xyz/2025/10/rustc-wrapper(linker)解决cargo并行链接OOM问题/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/10/rustc-wrapper(linker)解决cargo并行链接OOM问题/">&lt;h1 id=&quot;bao-zhuan-linkerde-fang-shi&quot;&gt;包转linker的方式&lt;&#x2F;h1&gt;
&lt;p&gt;ld_wrapper.sh
并没有验证通过ORZ?&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;#!&amp;#x2F;bin&amp;#x2F;bash
# 通用链接器包装器 - ld_generic_wrapper.sh

PRESSURE_THRESHOLD=&amp;quot;0.10&amp;quot;          # 内存压力阈值（10%）
MAX_WAIT_TIME=600                  # 最大等待时间（秒）
MIN_WAIT_TIME=5                    # 最小等待时间（秒） 
MAX_RETRIES=100                    # 最大重试次数
PRESSURE_FILE=&amp;quot;&amp;#x2F;sys&amp;#x2F;fs&amp;#x2F;cgroup&amp;#x2F;user.slice&amp;#x2F;user-$(id -u).slice&amp;#x2F;memory.pressure&amp;quot;
REAL_LD=&amp;quot;&amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;ld&amp;quot;              # 真实链接器路径，可根据需要修改
LOG_FILE=&amp;quot;&amp;#x2F;tmp&amp;#x2F;linker_wrapper.log&amp;quot; # 日志文件路径

# 检测真实链接器
detect_real_linker() {
    local wrapper_name=$(basename &amp;quot;$0&amp;quot;)
    case &amp;quot;$wrapper_name&amp;quot; in
        *ld*)
            REAL_LD=&amp;quot;&amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;ld&amp;quot;
            ;;
        *lld*)
            REAL_LD=&amp;quot;&amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;lld&amp;quot;
            ;;
        *gold*)
            REAL_LD=&amp;quot;&amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;gold&amp;quot;
            ;;
        *)
            REAL_LD=&amp;quot;&amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;ld&amp;quot;
            ;;
    esac
    
    # 检查链接器是否存在
    if [[ ! -x &amp;quot;$REAL_LD&amp;quot; ]]; then
        # 尝试在PATH中查找
        REAL_LD=$(which &amp;quot;${wrapper_name#wrapper_}&amp;quot;) || REAL_LD=&amp;quot;&amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;ld&amp;quot;
    fi
}

# 日志函数
log_message() {
    echo &amp;quot;$(date &amp;#x27;+%Y-%m-%d %H:%M:%S&amp;#x27;) - $1&amp;quot; &amp;gt;&amp;gt; &amp;quot;$LOG_FILE&amp;quot;
}

# 其余函数与之前相同...
get_some_avg10() {
    local pressure_file=$1
    if [[ -f &amp;quot;$pressure_file&amp;quot; ]]; then
        local line=$(grep &amp;quot;^some&amp;quot; &amp;quot;$pressure_file&amp;quot;)
        if [[ $line =~ avg10=([0-9.]+) ]]; then
            echo &amp;quot;${BASH_REMATCH[1]}&amp;quot;
            return 0
        fi
    fi
    echo &amp;quot;0.00&amp;quot;
}

wait_for_low_memory_pressure() {
    local retry_count=0
    local current_pressure
    
    while [[ $retry_count -lt $MAX_RETRIES ]]; do
        current_pressure=$(get_some_avg10 &amp;quot;$PRESSURE_FILE&amp;quot;)
        
        # 使用bc进行浮点数比较
        if command -v bc &amp;gt;&amp;#x2F;dev&amp;#x2F;null 2&amp;gt;&amp;amp;1; then
            # 如果有bc，进行精确比较
            if (( $(echo &amp;quot;$current_pressure &amp;lt; $PRESSURE_THRESHOLD&amp;quot; | bc -l) )); then
                log_message &amp;quot;内存压力正常 ($current_pressure &amp;lt; $PRESSURE_THRESHOLD)，开始执行链接&amp;quot;
                return 0
            fi
        else
            # 如果没有bc，使用bash内置的数值比较（假设压力值小于10）
            if (( $(echo &amp;quot;${current_pressure} &amp;lt; ${PRESSURE_THRESHOLD}&amp;quot; | tr -d &amp;#x27;.&amp;#x27; | head -c3) &amp;lt; $(echo &amp;quot;${PRESSURE_THRESHOLD}&amp;quot; | tr -d &amp;#x27;.&amp;#x27; | head -c3) )); then
                log_message &amp;quot;内存压力正常 ($current_pressure &amp;lt; $PRESSURE_THRESHOLD)，开始执行链接&amp;quot;
                return 0
            fi
        fi
        
        # 计算随机等待时间
        local wait_time=$(( MIN_WAIT_TIME + RANDOM % (MAX_WAIT_TIME - MIN_WAIT_TIME + 1) ))
        
        log_message &amp;quot;内存压力过高: $current_pressure (阈值: $PRESSURE_THRESHOLD), 等待 ${wait_time}秒后重试 (尝试: $((retry_count + 1))&amp;#x2F;$MAX_RETRIES)&amp;quot;
        
        # 等待
        sleep $wait_time
        
        ((retry_count++))
    done
    
    log_message &amp;quot;错误: 达到最大重试次数 ($MAX_RETRIES)，内存压力仍过高: $current_pressure&amp;quot;
    return 1
}

main() {
    log_message &amp;quot;链接器包装器被调用，参数: $*&amp;quot;

    detect_real_linker
    log_message &amp;quot;$(date) - 链接器包装器调用: $REAL_LD, 参数: $*&amp;quot; &amp;gt;&amp;gt; &amp;quot;$LOG_FILE&amp;quot;
    
    if ! wait_for_low_memory_pressure; then
        log_message &amp;quot;错误: 内存压力持续过高&amp;quot; &amp;gt;&amp;amp;2
        return 1
    fi
    
    log_message &amp;quot;执行真实链接器: $REAL_LD $*&amp;quot;
    exec &amp;quot;$REAL_LD&amp;quot; &amp;quot;$@&amp;quot;
}

main &amp;quot;$@&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;修改cargo编译使用的链接器&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 临时生效： 使脚本可执行
chmod +x &amp;#x2F;path&amp;#x2F;to&amp;#x2F;ld_wrapper.sh

# 配置RUSTFLAGS环境变量
export RUSTFLAGS=&amp;quot;-C link-arg=-fuse-ld=&amp;#x2F;path&amp;#x2F;to&amp;#x2F;ld_wrapper.sh&amp;quot;
cargo build
# 或者配置
export CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=$(realpath &amp;#x2F;path&amp;#x2F;to&amp;#x2F;wrap-ld.sh)

# 创建符号链接
ln -s &amp;#x2F;path&amp;#x2F;to&amp;#x2F;ld_generic_wrapper.sh &amp;#x2F;path&amp;#x2F;to&amp;#x2F;wrapper_ld
ln -s &amp;#x2F;path&amp;#x2F;to&amp;#x2F;ld_generic_wrapper.sh &amp;#x2F;path&amp;#x2F;to&amp;#x2F;wrapper_lld
ln -s &amp;#x2F;path&amp;#x2F;to&amp;#x2F;ld_generic_wrapper.sh &amp;#x2F;path&amp;#x2F;to&amp;#x2F;wrapper_gold

# 在cargo配置中使用
[target.x86_64-unknown-linux-gnu]
linker = &amp;quot;&amp;#x2F;path&amp;#x2F;to&amp;#x2F;wrapper_ld&amp;quot;

# 实时查看日志
tail -f &amp;#x2F;tmp&amp;#x2F;ld_wrapper.log

# 监控内存压力变化
watch -n 1 &amp;#x27;cat &amp;#x2F;sys&amp;#x2F;fs&amp;#x2F;cgroup&amp;#x2F;user.slice&amp;#x2F;user-$(id -u).slice&amp;#x2F;memory.pressure&amp;#x27;

# 检查链接进程
ps aux | grep ld_wrapper
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;bao-zhuang-rustcjin-xing-bian-yi&quot;&gt;包装rustc进行编译&lt;&#x2F;h1&gt;
&lt;p&gt;使用rustc-wrapper.sh&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;#!&amp;#x2F;bin&amp;#x2F;bash
RUSTC_BIN=&amp;quot;$1&amp;quot;
shift

PRESSURE_THRESHOLD=&amp;quot;0.10&amp;quot;
MAX_WAIT_TIME=60
MIN_WAIT_TIME=5
MAX_RETRIES=60
PRESSURE_FILE=&amp;quot;&amp;#x2F;sys&amp;#x2F;fs&amp;#x2F;cgroup&amp;#x2F;user.slice&amp;#x2F;user-$(id -u).slice&amp;#x2F;memory.pressure&amp;quot;

get_some_avg10() {
    if [[ -f &amp;quot;$PRESSURE_FILE&amp;quot; ]]; then
        local line=$(grep &amp;quot;^some&amp;quot; &amp;quot;$PRESSURE_FILE&amp;quot;)
        if [[ $line =~ avg10=([0-9.]+) ]]; then
            echo &amp;quot;${BASH_REMATCH[1]}&amp;quot;
            return 0
        fi
    fi
    # 默认返回 0.00，表示没有压力
    echo &amp;quot;0.00&amp;quot;
}

# 检查是否为链接阶段：包含 --crate-type=bin 或 cdylib，且不包含 --print（避免干扰 Cargo 查询）
if [[ &amp;quot;$*&amp;quot; == *&amp;quot;--crate-type bin&amp;quot;* || &amp;quot;$*&amp;quot; == *&amp;quot;--crate-type cdylib&amp;quot;* ]] &amp;amp;&amp;amp; [[ &amp;quot;$*&amp;quot; != *&amp;quot;--print&amp;quot;* ]]; then
    echo &amp;#x27;****************Linker stage ...****************&amp;#x27;
    retry_count=0
    while [[ $retry_count -lt 100 ]]; do
        current_pressure=$(get_some_avg10 &amp;quot;$PRESSURE_FILE&amp;quot;)
        # 使用bc进行浮点数比较
        if command -v bc &amp;gt;&amp;#x2F;dev&amp;#x2F;null 2&amp;gt;&amp;amp;1; then
            if (( $(echo &amp;quot;$current_pressure &amp;lt; $PRESSURE_THRESHOLD&amp;quot; | bc -l) )); then
                echo &amp;quot;****************内存压力正常 ($current_pressure &amp;lt; $PRESSURE_THRESHOLD)，开始执行 rustc****************&amp;quot;
		break
            fi
        else
                echo &amp;quot;****************必须安装bc工具计算浮点运算****************&amp;quot;
		exit 1
        fi

        # 计算随机等待时间
        wait_time=$(( MIN_WAIT_TIME + RANDOM % (MAX_WAIT_TIME - MIN_WAIT_TIME + 1) ))
        echo &amp;quot;****************内存压力过高: $current_pressure (阈值: $PRESSURE_THRESHOLD), 等待 ${wait_time}秒后重试 (尝试: $((retry_count + 1))&amp;#x2F;$MAX_RETRIES)****************&amp;quot;
        sleep $wait_time
        ((retry_count++))
    done
fi

exec &amp;quot;$RUSTC_BIN&amp;quot; &amp;quot;$@&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>wait-online when any-interface ready</title>
        <published>2025-10-30T20:54:56+08:00</published>
        <updated>2025-10-30T20:54:56+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/10/wait-online when any-interface ready/"/>
        <id>https://vercel.juzhong.xyz/2025/10/wait-online when any-interface ready/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/10/wait-online when any-interface ready/">&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo tee &amp;#x2F;etc&amp;#x2F;systemd&amp;#x2F;system&amp;#x2F;systemd-networkd-wait-online.service.d&amp;#x2F;wait-for-only-one-interface.conf &amp;lt;&amp;lt;EOF
[Service]
ExecStart=
ExecStart=&amp;#x2F;usr&amp;#x2F;lib&amp;#x2F;systemd&amp;#x2F;systemd-networkd-wait-online --any
EOF

sudo systemctl daemon-reload
sudo systemctl cat systemd-networkd-wait-online.service
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>libvirt 虚拟机内存管理</title>
        <published>2025-10-29T10:51:16+08:00</published>
        <updated>2025-10-29T10:51:16+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/10/libvirt 虚拟机内存管理/"/>
        <id>https://vercel.juzhong.xyz/2025/10/libvirt 虚拟机内存管理/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/10/libvirt 虚拟机内存管理/">&lt;h1 id=&quot;libvirt-windowsxu-ni-ji-nei-cun-zhan-yong-guo-gao&quot;&gt;libvirt windows虚拟机内存占用过高&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;xu-ni-ji-nei-cun-ce-lue&quot;&gt;虚拟机内存策略&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;QEMU 在虚拟机启动时，一次性分配固定的内存。
这部分内存被 预留并映射到宿主机进程（qemu-system-x86_64）。
从宿主机的角度看，这些内存都是“被占用的”。
即使 Windows 内部只使用很少，也不会被宿主机回收。&lt;&#x2F;li&gt;
&lt;li&gt;💡 换句话说：
没有 balloon 驱动 = 没有动态回收机制。
QEMU 不知道 Windows 里面的内存使用情况，它只能把所有内存都“留给”虚拟机进程。&lt;&#x2F;li&gt;
&lt;li&gt;Windows 内存管理的特性加剧了现象
Windows 客户机即便空闲，也会：
启动缓存与系统文件预取；
启动 SuperFetch &#x2F; SysMain；
各种服务预分配内存池；
内核会尽量“占用”空闲内存以提高 I&#x2F;O 性能（File Cache）。
因此在任务管理器中看似“使用很多内存”，其实很多是 可释放缓存（Standby Memory）。
但宿主机（Linux + libvirt）看不到“哪些是可回收的”，于是整块都算“已用内存”。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;ballooning-ru-he-jie-jue-zhe-ge-wen-ti&quot;&gt;Ballooning 如何解决这个问题？&lt;&#x2F;h2&gt;
&lt;p&gt;Ballooning 的作用是 建立 Guest 与 Host 之间的内存使用反馈通道：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Guest 内 balloon 驱动 作为一个“伪设备”，可以向 Windows 内存管理器 申请分配内存（就像一个普通程序申请内存一样）；&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Windows 会从其空闲内存池中分配给 balloon 驱动；&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;但 balloon 驱动 不会真正使用这些内存，只是“持有”它；&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;由于这部分内存被 balloon 占用，QEMU 就知道：Guest 实际可用内存减少了，可以将对应物理页从宿主机释放；&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;宿主机内存压力大时，libvirt 可通过 virsh setmem 命令 增大 balloon 大小，从而“回收”虚拟机内存。&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Linux 虚拟机也一样：没有 balloon 驱动（如 virtio_balloon 模块未加载），同样会高占内存；&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;现代替代方案：virtio-mem（动态内存插拔）比 balloon 更灵活，但 Windows 支持有限，balloon 仍是主流；&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;内存共享（KSM）不能替代 balloon：KSM 只能合并完全相同的内存页（如多个 Win10 虚拟机的系统 DLL），对私有数据无效。&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;libvirt-qemu-zhi-chi-windows-xu-ni-ji-de-nei-cun-ballooning-dong-tai-nei-cun-guan-li&quot;&gt;libvirt&#x2F;QEMU 支持 Windows 虚拟机的内存 ballooning（动态内存管理）&lt;&#x2F;h2&gt;
&lt;p&gt;需要在 宿主机与客户机两边都正确配置&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;windows 虚拟机上安装 virtio-win-xxx.iso 中的ballooning(其他的可以不安装，容易引起问题)&lt;&#x2F;li&gt;
&lt;li&gt;配置虚拟机配置&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;xml&quot; class=&quot;language-xml &quot;&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&amp;lt;memballoon model=&amp;#x27;virtio&amp;#x27;&amp;gt;
  &amp;lt;stats period=&amp;#x27;10&amp;#x27;&amp;#x2F;&amp;gt;
&amp;lt;&amp;#x2F;memballoon&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>gnome-remote-desktop headless 模式</title>
        <published>2025-10-28T20:10:27+08:00</published>
        <updated>2025-10-28T20:10:27+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/10/gnome-remote-desktop headless 模式/"/>
        <id>https://vercel.juzhong.xyz/2025/10/gnome-remote-desktop headless 模式/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/10/gnome-remote-desktop headless 模式/">&lt;h1 id=&quot;quan-liu-cheng-pei-zhi&quot;&gt;全流程配置&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt install -y gnome-remote-desktop winpr-utils


# 为 RDP 服务生成自签名 TLS 证书：
mkdir -p ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop
winpr-makecert -silent -rdp -path ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop rdp-tls
# 使用 RDP 配置 GNOME 远程桌面：
grdctl --headless rdp set-tls-key ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;rdp-tls.key
grdctl --headless rdp set-tls-cert ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;rdp-tls.crt
grdctl --headless rdp enable
grdctl --headless rdp disable-view-only
grdctl --headless rdp set-credentials peter Strong@pssword
# 如果keyring密钥环也没有TPM模块， 认证信息会保存在文件中
cat ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;credentials.ini
# 为单用户服务启用无头服务器：
# systemctl --user enable --now gnome-remote-desktop-headless.service
&amp;#x2F;usr&amp;#x2F;libexec&amp;#x2F;gnome-remote-desktop-daemon --headless --

# 以 root 用户身份为单个用户永久启动无头 GNOME 会话：
# sudo systemctl enable --now gnome-headless-session@peter.service
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 客户端连接
xfreerdp &amp;#x2F;v:192.168.7.99:3389 &amp;#x2F;u:peter &amp;#x2F;p:Strong@password +clipboard &amp;#x2F;dynamic-resolution &amp;#x2F;sound:sys:pulse &amp;#x2F;microphone:sys:pulse &amp;#x2F;cert-ignore +sec-rdp
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;配置gnome-headless-session&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;ini&quot; class=&quot;language-ini &quot;&gt;&lt;code class=&quot;language-ini&quot; data-lang=&quot;ini&quot;&gt;sudo tee &amp;#x2F;etc&amp;#x2F;systemd&amp;#x2F;system&amp;#x2F;gnome-headless-session@.service &amp;lt;&amp;lt;EOF
[Unit]
# %i is the instance name (e.g., &amp;#x27;peter&amp;#x27; in gnome-headless-session@peter.service)
Description=GNOME Headless Desktop Session for User %i
Documentation=https:&amp;#x2F;&amp;#x2F;wiki.gnome.org&amp;#x2F;Projects&amp;#x2F;Mutter&amp;#x2F;RemoteDesktop
After=systemd-user-sessions.service
After=network.target remote-fs.target
# After=graphical.target
Wants=graphical.target
# 依赖于用户会话的挂载点和 D-Bus
# Requires=user@%i.service
# BindsTo=user@%i.service
# 确保在用户退出时停止
KillMode=mixed
# 在停止时发送 SIGTERM，等待 9 秒后发送 SIGKILL
TimeoutStopSec=9

[Service]
# Type=simple 适用于 ExecStart 是主进程的情况。
Type=simple
User=%i
Group=%i
PAMName=login
Environment=XDG_SESSION_TYPE=wayland
Environment=XDG_RUNTIME_DIR=&amp;#x2F;run&amp;#x2F;user&amp;#x2F;%U
Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=&amp;#x2F;run&amp;#x2F;user&amp;#x2F;%U&amp;#x2F;bus
# Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=%E&amp;#x2F;bus
ExecStartPre=&amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY XDG_SESSION_TYPE XDG_CURRENT_DESKTOP
ExecStartPre=-&amp;#x2F;bin&amp;#x2F;sh -c &amp;#x27;XDG_RUNTIME_DIR=&amp;#x2F;run&amp;#x2F;user&amp;#x2F;$(id -u %i) &amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;loginctl enable-linger %i&amp;#x27;
ExecStart=&amp;#x2F;usr&amp;#x2F;libexec&amp;#x2F;gnome-remote-desktop-daemon --headless
Restart=on-failure
RestartSec=9

[Install]
WantedBy=multi-user.target
EOF
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;使能 grd headless模式&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo systemctl enable --now gnome-headless-session@peter.service
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>gist使用</title>
        <published>2025-10-26T10:42:58+08:00</published>
        <updated>2025-10-26T10:42:58+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/10/gist使用/"/>
        <id>https://vercel.juzhong.xyz/2025/10/gist使用/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/10/gist使用/">&lt;pre data-lang=&quot;txt&quot; class=&quot;language-txt &quot;&gt;&lt;code class=&quot;language-txt&quot; data-lang=&quot;txt&quot;&gt;https:&amp;#x2F;&amp;#x2F;gist.githubusercontent.com&amp;#x2F;peter&amp;#x2F;0d54d265365eea6cc485eff0e27a6095&amp;#x2F;raw&amp;#x2F;306d43e59dda68c9bbda73568bc35938afec147b&amp;#x2F;file.txt
https:&amp;#x2F;&amp;#x2F;gist.githubusercontent.com&amp;#x2F;peter&amp;#x2F;4ebf871274bd089d8c4b8af375628f36&amp;#x2F;raw&amp;#x2F;b8f2bb5646f257fca28b1203c8ecd8e26ccffc3c&amp;#x2F;box.txt
https:&amp;#x2F;&amp;#x2F;gist.githubusercontent.com&amp;#x2F;peter&amp;#x2F;1fec0a47ca8e5288046d3a6eb2203b80&amp;#x2F;raw&amp;#x2F;caf1ae6e96feb5459c8bc662d853198e4660bc2f&amp;#x2F;ray.txt

https:&amp;#x2F;&amp;#x2F;gist.githubusercontent.com&amp;#x2F;peter&amp;#x2F;1fec0a47ca8e5288046d3a6eb2203b80&amp;#x2F;raw&amp;#x2F;3ed0e0085da9f8cf8194eec13f5db440fbbf471f&amp;#x2F;ray.txt#upgradeCDN
https:&amp;#x2F;&amp;#x2F;gist.githubusercontent.com&amp;#x2F;peter&amp;#x2F;4ebf871274bd089d8c4b8af375628f36&amp;#x2F;raw&amp;#x2F;1215bf211050906ef59bda09bcf798656105fd67&amp;#x2F;box.txt#fixSNI

https:&amp;#x2F;&amp;#x2F;gist.githubusercontent.com&amp;#x2F;peter&amp;#x2F;84d2840ea060606c25b8c37faace7c68&amp;#x2F;raw&amp;#x2F;9224a25c124dc9636165ee8bf07ad3a76e97c134&amp;#x2F;box-systemd-nspawn.txt
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>openvpn 配置</title>
        <published>2025-10-26T10:30:40+08:00</published>
        <updated>2025-10-26T10:30:40+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/10/openvpn 配置/"/>
        <id>https://vercel.juzhong.xyz/2025/10/openvpn 配置/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/10/openvpn 配置/">&lt;h1 id=&quot;an-zhuang-he-pei-zhi&quot;&gt;安装和配置&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;apt install openvpn
# 覆盖默认配置， 探测192.168.2.1可达
sudo tee &amp;#x2F;etc&amp;#x2F;systemd&amp;#x2F;system&amp;#x2F;openvpn-client@work.service &amp;lt;&amp;lt;EOF
[Unit]
Description=OpenVPN tunnel for %I after IP 192.168.2.1 to be reachable
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
PrivateTmp=true
WorkingDirectory=&amp;#x2F;etc&amp;#x2F;openvpn&amp;#x2F;client
ExecStartPre=&amp;#x2F;bin&amp;#x2F;bash -c &amp;#x27;until ping -c 1 -W 5 192.168.2.1; do sleep 1; done
ExecStart=&amp;#x2F;usr&amp;#x2F;sbin&amp;#x2F;openvpn --suppress-timestamps --nobind --config %i.conf
CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SETPCAP CAP_SYS_CHROOT CAP_DAC_OVERRIDE
LimitNPROC=10
DeviceAllow=&amp;#x2F;dev&amp;#x2F;null rw
DeviceAllow=&amp;#x2F;dev&amp;#x2F;net&amp;#x2F;tun rw
ProtectSystem=true
ProtectHome=true
KillMode=process
[Install]
WantedBy=multi-user.target
EOF

cat &amp;lt;&amp;lt;EOF | sudo tee &amp;#x2F;etc&amp;#x2F;openvpn&amp;#x2F;client&amp;#x2F;work.conf
client
dev tun
proto tcp
remote &amp;lt;ip&amp;gt; &amp;lt;port&amp;gt;
resolv-retry infinite
nobind
persist-key
persist-tun
comp-lzo no

auth-user-pass
# openvpn3 客户端支持账户认证, openvpn2 好像支持环境变量热证
# &amp;lt;auth-user-pass&amp;gt;
# VPN_USERNAME_HERE
# VPN_PASSWORD_HERE
# &amp;lt;&amp;#x2F;auth-user-pass&amp;gt;
remote-cert-tls server

data-ciphers AES-256-GCM:AES-256-CBC
data-ciphers-fallback AES-256-CBC
verb 3
&amp;lt;ca&amp;gt;
-----BEGIN CERTIFICATE-----
XXX base 64
-----END CERTIFICATE-----
&amp;lt;&amp;#x2F;ca&amp;gt;
EOF
sudo systemctl start openvpn-client@work.service
# 可以手动调节metric 防止影响局域网路由
sudo ip route change default via 10.8.0.1 dev tun0 metric 300
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;fu-wu-duan-pei-zhi&quot;&gt;服务端配置&lt;&#x2F;h1&gt;
&lt;p&gt;可以参考ldap账户认证&lt;&#x2F;p&gt;
&lt;h1 id=&quot;pei-zhi-lu-you&quot;&gt;配置路由&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;ip route
# 192.168.5.0&amp;#x2F;24 dev eno1 proto kernel scope link src 192.168.5.23 metric 100 
# 192.168.4.0&amp;#x2F;22 via 10.8.0.9 dev tun0 
# 192.168.4.0&amp;#x2F;22 via 10.8.0.9 dev tun0 metric 10
ip route get 192.168.5.244
# 192.168.5.244 dev eno1 src 192.168.5.23 uid 1000
#     cache

# 为什么经过dev tun0 的路由地址metric优先级(10)更高, 但是路由却走了直连的路由？？？
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;yuan-yin&quot;&gt;原因&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Metric 只在“相同目标前缀”的多条路由之间比较时才生效。
&lt;ul&gt;
&lt;li&gt;例如：两条都是 192.168.5.0&#x2F;24，一个 metric 10，一个 metric 100 → 选 metric 10。&lt;&#x2F;li&gt;
&lt;li&gt;但你的 metric 10 路由是 192.168.4.0&#x2F;22，和 192.168.5.0&#x2F;24 不是相同前缀！&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;前缀长度优先于 metric
&lt;ul&gt;
&lt;li&gt;目标地址 192.168.5.244 属于 192.168.5.0&#x2F;24 网段。&lt;&#x2F;li&gt;
&lt;li&gt;Linux 路由查找时会做 最长前缀匹配（Longest Prefix Match），而：&lt;&#x2F;li&gt;
&lt;li&gt;192.168.5.0&#x2F;24 是 &#x2F;24 前缀&lt;&#x2F;li&gt;
&lt;li&gt;192.168.4.0&#x2F;22 虽然也包含 192.168.5.244（因为 &#x2F;22 覆盖 192.168.4.0 ~ 192.168.7.255），但它是 更短的前缀（&#x2F;22 &amp;lt; &#x2F;24）&lt;&#x2F;li&gt;
&lt;li&gt;✅ 所以系统 优先选择更具体的 &#x2F;24 路由&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;ru-guo-ni-zhen-de-xiang-rang-192-168-5-244-zou-tun0-zen-me-ban&quot;&gt;如果你真的想让 192.168.5.244 走 tun0 怎么办？&lt;&#x2F;h2&gt;
&lt;p&gt;这是个非常规需求（因为 192.168.5.244 和你本机在同一个局域网），但技术上可以做到：&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tian-jia-geng-ju-ti-de-32-lu-you-tui-jian&quot;&gt;添加更具体的 &#x2F;32 路由（推荐）&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo ip route add 192.168.5.244 via 10.8.0.9 dev tun0 metric 5
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;shi-yong-ce-lue-lu-you-gao-ji&quot;&gt;使用策略路由（高级）&lt;&#x2F;h3&gt;
&lt;p&gt;通过 ip rule + 自定义路由表，对特定用户&#x2F;进程&#x2F;防火墙标记的流量使用不同路由。&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo ip rule add to 192.168.5.244&amp;#x2F;24 lookup 100
sudo ip route add default via 10.8.0.9 dev tun0 table 100
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>gnome-remote-desktop 配置</title>
        <published>2025-10-25T21:43:52+08:00</published>
        <updated>2025-10-25T21:43:52+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/10/gnome-remote-desktop 配置/"/>
        <id>https://vercel.juzhong.xyz/2025/10/gnome-remote-desktop 配置/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/10/gnome-remote-desktop 配置/">&lt;h1 id=&quot;ming-ling-xing-cha-kan-pei-zhi&quot;&gt;命令行查看配置&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;gsettings list-recursively | grep remote-desktop
systemctl --user stop gnome-remote-desktop

# 但是我尝试了多种方法最后生成的都是openssh格式的私钥key？？？！！！
# 生成新的密钥（确保是PEM格式）
openssl genrsa -out ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;rdp-tls.key 2048
# 使用 openssl 明确生成 PEM 格式 
openssl genpkey -algorithm RSA -out ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;rdp-tls.key -pkeyopt rsa_keygen_bits:2048
# 生成证书
openssl req -new -x509 -key ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;rdp-tls.key -out ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;rdp-tls.crt -days 3650 -subj &amp;quot;&amp;#x2F;C=CN&amp;#x2F;ST=State&amp;#x2F;L=City&amp;#x2F;O=Organization&amp;#x2F;CN=$(hostname)&amp;quot;

# 设置密钥和证书（如果证书已经设置过，可以不用再设置，但为了确保，可以重新设置一次）
grdctl set-tls-key ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;rdp-tls.key
grdctl set-tls-cert ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;rdp-tls.crt
grdctl status
grdctl --help
systemctl --user start gnome-remote-desktop

# 如果反复遇到 RDP 证书问题，最省时省力的方式是关闭 RDP，启用 VNC：
gsettings set org.gnome.desktop.remote-desktop.rdp enabled false
gsettings set org.gnome.desktop.remote-desktop.vnc enabled true
echo -n &amp;#x27;yourpassword&amp;#x27; | gsettings set org.gnome.desktop.remote-desktop.vnc password &amp;quot;$(base64 -w 0)&amp;quot;
systemctl --user restart gnome-remote-desktop


# 禁用屏幕自动锁定
gsettings set org.gnome.desktop.screensaver lock-enabled false
# 设置屏幕空白时间为从不
gsettings set org.gnome.desktop.session idle-delay 0
gsettings set org.gnome.desktop.screensaver idle-activation-enabled false
# 禁用自动挂起
gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-ac-type &amp;#x27;nothing&amp;#x27;
gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-battery-type &amp;#x27;nothing&amp;#x27;

# GNOME 45+ 的 gnome-remote-desktop 在 RDP 模式下不会主动防止系统挂起。 因此你还需要告诉 logind 保持唤醒状态：
# 这可以防止合盖（或外接显示器断开）时触发挂起。
sudo sed -i &amp;#x27;s&amp;#x2F;^#\?HandleLidSwitch=.*&amp;#x2F;HandleLidSwitch=ignore&amp;#x2F;&amp;#x27; &amp;#x2F;etc&amp;#x2F;systemd&amp;#x2F;logind.conf
sudo sed -i &amp;#x27;s&amp;#x2F;^#\?HandleLidSwitchDocked=.*&amp;#x2F;HandleLidSwitchDocked=ignore&amp;#x2F;&amp;#x27; &amp;#x2F;etc&amp;#x2F;systemd&amp;#x2F;logind.conf
sudo systemctl restart systemd-logind
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;qi-ta-zi-liao-de-bu-chong&quot;&gt;其他资料的补充&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 以目标用户身份设置 GNOME 配置（关键！） # 切换到你的桌面用户（例如 peter）
sudo -u peter dbus-run-session -- bash
# dbus-run-session 确保 D-Bus 会话可用，否则 gsettings 可能失效。 

# 禁用自动锁屏
gsettings set org.gnome.desktop.screensaver lock-enabled false

# 禁用屏幕休眠（设为 0 表示永不）
gsettings set org.gnome.desktop.session idle-delay 0

# 禁用显示器自动关闭（设为 0 表示永不）
gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-ac-type &amp;#x27;nothing&amp;#x27;
gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-battery-type &amp;#x27;nothing&amp;#x27;

# 禁用屏幕变黑（DPMS）
gsettings set org.gnome.desktop.session idle-delay 0
gsettings set org.gnome.settings-daemon.plugins.power idle-dim false

sudo tee &amp;#x2F;etc&amp;#x2F;systemd&amp;#x2F;logind.conf.d&amp;#x2F;90-disable-suspend.conf &amp;lt;&amp;lt;EOF
[Login]
HandleLidSwitch=ignore
HandleLidSwitchExternalPower=ignore
HandleLidSwitchDocked=ignore
IdleAction=ignore
IdleActionSec=0
EOF
sudo systemctl restart systemd-logind

# GNOME 会检测是否有“活跃会话”。如果你使用的是 GNOME 内置远程桌面（gnome-remote-desktop），它默认应被视为活跃。但为保险起见： 允许远程会话阻止空闲
gsettings set org.gnome.mutter idle-monitor false

# 系统级别的阻止系统挂起: 遇到过问题 sleep.target 会刷大量warning日志
sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target
# 程序运行时临时阻止系统挂起
systemd-inhibit --what=idle:sleep:shutdown --who=&amp;quot;Reason&amp;quot; --why=&amp;quot;Explanation&amp;quot; &amp;#x2F;path&amp;#x2F;to&amp;#x2F;command 
systemd-inhibit --what=idle:sleep:shutdown --who=&amp;quot;Keep up&amp;quot; --why=&amp;quot;Preventing sleep&amp;quot; &amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;htop
systemd-inhibit --list
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;sshdeng-lu-hou-de-quan-liu-cheng-pei-zhi&quot;&gt;ssh登录后的全流程配置&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;USERNAME=peter
UID=$(id -u $USERNAME)
export XDG_RUNTIME_DIR=&amp;#x2F;run&amp;#x2F;user&amp;#x2F;$UID
export DBUS_SESSION_BUS_ADDRESS=unix:path=$XDG_RUNTIME_DIR&amp;#x2F;bus

# 安装（Ubuntu&amp;#x2F;Debian）
sudo apt update
sudo apt install -y gnome-remote-desktop winpr-utils

# 生成证书并配置
sudo -u $USERNAME -- sh -c &amp;#x27;mkdir -p ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop &amp;amp;&amp;amp; \
  winpr-makecert -silent -rdp -path ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop rdp-tls&amp;#x27;

sudo -u $USERNAME -- bash -c &amp;#x27;
  grdctl rdp set-tls-key ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;rdp-tls.key
  grdctl rdp set-tls-cert ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;gnome-remote-desktop&amp;#x2F;rdp-tls.crt
  grdctl rdp set-credentials &amp;#x27;&amp;quot;&amp;#x27;&amp;quot;$USERNAME&amp;quot;&amp;#x27;&amp;quot;&amp;#x27; &amp;#x27;&amp;quot;&amp;#x27;&amp;quot;&amp;#x27;StrongP@ssw0rd&amp;#x27;&amp;quot;&amp;#x27;&amp;quot;&amp;#x27;
  grdctl rdp enable
  grdctl rdp disable-view-only
  systemctl --user enable --now gnome-remote-desktop.service
&amp;#x27;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;xiu-fu-mi-yao-huan-jie-suo-shi-bai&quot;&gt;修复密钥环解锁失败&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;GNOME Remote Desktop（以及 grdctl）会把 RDP&#x2F;VNC 凭据、TLS 证书路径 等信息加密保存到 GNOME Keyring 中。&lt;&#x2F;li&gt;
&lt;li&gt;Keyring 是由 gnome-keyring-daemon 管理的一个加密存储，默认有一个叫 “login” 的 keyring 文件：&lt;&#x2F;li&gt;
&lt;li&gt;位于：~&#x2F;.local&#x2F;share&#x2F;keyrings&#x2F;login.keyring&lt;&#x2F;li&gt;
&lt;li&gt;加密口令：最初创建用户时的密码&lt;&#x2F;li&gt;
&lt;li&gt;平常在 GUI 登录时由 gnome-keyring-daemon 自动解锁。&lt;&#x2F;li&gt;
&lt;li&gt;但当你通过 SSH &#x2F; 无图形登录时，这个 daemon 没有运行，也无法自动解锁。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;shan-chu-zhong-jian-login-mi-yao-huan-zui-zhi-jie&quot;&gt;删除&#x2F;重建 login 密钥环（最直接）&lt;&#x2F;h3&gt;
&lt;p&gt;如果你不在意旧的保存内容，可以直接删除密钥环并重新生成：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;mv ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;keyrings&amp;#x2F;login.keyring ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;keyrings.bak
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;tong-bu-mi-ma-ru-guo-ni-zhi-dao-jiu-mi-ma&quot;&gt;同步密码（如果你知道旧密码）&lt;&#x2F;h3&gt;
&lt;p&gt;如果你确定旧密码是 “OldPass”，新密码是 “NewPass”，
可以用 GNOME Keyring 工具同步（需要临时图形环境）：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;seahorse
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;然后右键 “登录” → “更改密码”，输入旧密码 + 新密码同步。
之后 CLI 方式的 grdctl 输入新密码就能正确验证。&lt;&#x2F;p&gt;
&lt;h3 id=&quot;shou-dong-qi-dong-gnome-keyring-daemon-ssh-huan-jing&quot;&gt;手动启动 gnome-keyring-daemon（SSH 环境）&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;eval $(gnome-keyring-daemon --start --components=secrets,pkcs11,ssh,gpg)
export GNOME_KEYRING_CONTROL
export GNOME_KEYRING_PID
export SSH_AUTH_SOCK
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;wan-quan-tiao-guo-keyring-lin-shi-ce-shi-yong&quot;&gt;完全跳过 keyring（临时、测试用）&lt;&#x2F;h3&gt;
&lt;p&gt;GNOME Remote Desktop 没有官方参数能跳过 keyring保存，但可以用一种“hack”方式：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 仅限测试环境！！
export GNOME_KEYRING_CONTROL=&amp;#x2F;tmp&amp;#x2F;fake-keyring
mkdir -p $GNOME_KEYRING_CONTROL
grdctl rdp set-credentials &amp;lt;user&amp;gt; &amp;lt;password&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;这会创建一个临时未加密 keyring 存储（适合容器或测试机），
重启后失效，但能避免“解锁密钥环”弹窗。&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>常用软件列表</title>
        <published>2025-10-24T10:32:13+08:00</published>
        <updated>2025-10-24T10:32:13+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/10/常用软件列表/"/>
        <id>https://vercel.juzhong.xyz/2025/10/常用软件列表/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/10/常用软件列表/">&lt;h1 id=&quot;ruan-jian-lie-biao&quot;&gt;软件列表&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;mkcert&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;openssl&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;openvpn
easyrsa
self-service-password&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;gpg&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;cargo install xremap --features gnome&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;nginx&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;pingora:
pingap&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;ddns-go&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;dns-sd(dns service discovery) mDNS&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;vlc&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;ffmpeg&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;qbttorrent&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;excalidraw.com&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;penpot.app&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;video&quot;&gt;video&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;apt install shotcut      # 视频处理&lt;&#x2F;li&gt;
&lt;li&gt;sudo apt install kooha   # 录屏工具&lt;&#x2F;li&gt;
&lt;li&gt;vlc                      # 视频播放， rtsp流媒体&lt;&#x2F;li&gt;
&lt;li&gt;obs&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;kai-fa&quot;&gt;开发&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;aws s3&lt;&#x2F;li&gt;
&lt;li&gt;minio rustfs&lt;&#x2F;li&gt;
&lt;li&gt;bind9 hickory-dns&lt;&#x2F;li&gt;
&lt;li&gt;hyper axum tokio tonic tower clap serde tokio-smoltcp rustls zola tracing&lt;&#x2F;li&gt;
&lt;li&gt;podman llvm clang rust-analyzer&lt;&#x2F;li&gt;
&lt;li&gt;asan afl++ syzkaller&lt;&#x2F;li&gt;
&lt;li&gt;cloudflared&#x2F;worker&lt;&#x2F;li&gt;
&lt;li&gt;vscode&#x2F;chrome 插件&lt;&#x2F;li&gt;
&lt;li&gt;qemu&lt;&#x2F;li&gt;
&lt;li&gt;mimalloc&lt;&#x2F;li&gt;
&lt;li&gt;systemfd --no-pid -s http::5000 -- cargo watch -x run&lt;&#x2F;li&gt;
&lt;li&gt;shoes sing-box xray&lt;&#x2F;li&gt;
&lt;li&gt;dbus&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;learn&quot;&gt;learn&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;架构设计 https:&#x2F;&#x2F;github.com&#x2F;Admol&#x2F;SystemDesign.git&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;ai-helper&quot;&gt;AI helper&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;ollma RAGflow&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;zi-dian&quot;&gt;字典&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;golddict dialect pot-desktop&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;xiang-mu-guan-li&quot;&gt;项目管理&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;jira&lt;&#x2F;li&gt;
&lt;li&gt;NocoBase&lt;&#x2F;li&gt;
&lt;li&gt;Plane&lt;&#x2F;li&gt;
&lt;li&gt;Planka&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>apt download下载离线安装包</title>
        <published>2025-10-23T13:29:40+08:00</published>
        <updated>2025-10-23T13:29:40+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/10/apt download下载离线安装包/"/>
        <id>https://vercel.juzhong.xyz/2025/10/apt download下载离线安装包/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/10/apt download下载离线安装包/">&lt;h1 id=&quot;fang-an-yi-yum-apt-xia-zai-chi-xian-bao-tui-jian-xin-shou&quot;&gt;方案一：yum &#x2F; apt 下载离线包（推荐新手）&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;centos-rhel-xia-zai-rpm-bao&quot;&gt;CentOS &#x2F; RHEL（下载 rpm 包）&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 首先安装 yum-plugin-downloadonly 插件
yum install yum-plugin-downloadonly -y
# 使用下面命令下载指定的包及其依赖项
yum install --downloadonly 软件包名
# 例如：下载nginx
yum install --downloadonly nginx
# 默认下载路径
ll &amp;#x2F;var&amp;#x2F;cache&amp;#x2F;yum&amp;#x2F;x86_64&amp;#x2F;7&amp;#x2F;base&amp;#x2F;packages
ll &amp;#x2F;var&amp;#x2F;cache&amp;#x2F;yum&amp;#x2F;x86_64&amp;#x2F;7&amp;#x2F;epel&amp;#x2F;packages
# 指定下载路径（推荐）
yum install --downloadonly --downloaddir=&amp;#x2F;data&amp;#x2F;pkgs&amp;#x2F;nginx&amp;#x2F; nginx
# 参数解释
--downloadonly                          # 只下载包不安装
--downloaddir=&amp;#x2F;your&amp;#x2F;custom&amp;#x2F;path&amp;#x2F;        # 指定下载路径
# 查看下载后的包
ls &amp;#x2F;data&amp;#x2F;pkgs&amp;#x2F;nginx&amp;#x2F;
# centos-indexhtml-7-9.el7.centos.noarch.rpm
# gperftools-libs-2.6.1-1.el7.x86_64.rpm
# nginx-1.20.1-10.el7.x86_64.rpm
# nginx-filesystem-1.20.1-10.el7.noarch.rpm
# openssl11-libs-1.1.1k-7.el7.x86_64.rpm
# 打包传输到内网
cd &amp;#x2F;data&amp;#x2F;pkgs&amp;#x2F;
tar -czf nginx-offline.tar.gz nginx&amp;#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;nei-wang-ji-qi-an-zhuang&quot;&gt;========== 内网机器安装 ==========&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 解压后进入目录
tar -xzf nginx-offline.tar.gz
cd nginx&amp;#x2F;
# 方法1：使用rpm命令
rpm -ivh *.rpm
# 方法2：使用yum localinstall（推荐，自动处理依赖）
yum localinstall -y *.rpm
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;ubuntu-debian-xia-zai-deb-bao&quot;&gt;Ubuntu &#x2F; Debian（下载 deb 包）&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 下载deb包
apt --download-only install 软件包名
# 例如：下载nginx
apt --download-only install nginx
# 默认下载路径
ll &amp;#x2F;var&amp;#x2F;cache&amp;#x2F;apt&amp;#x2F;archives&amp;#x2F;
# 指定下载路径
mkdir -p &amp;#x2F;data&amp;#x2F;pkgs&amp;#x2F;nginx
apt -o dir::cache::archives=&amp;quot;&amp;#x2F;data&amp;#x2F;pkgs&amp;#x2F;nginx&amp;quot; install --download-only nginx
# 参数解释
--download-only                                    # 只下载包不安装
-o dir::cache::archives=&amp;quot;&amp;#x2F;your&amp;#x2F;custom&amp;#x2F;path&amp;quot;       # 指定下载路径
# 打包传输
cd &amp;#x2F;data&amp;#x2F;pkgs&amp;#x2F;
tar -czf nginx-offline.tar.gz nginx&amp;#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;nei-wang-ji-qi-an-zhuang-1&quot;&gt;========== 内网机器安装 ==========&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;tar -xzf nginx-offline.tar.gz
cd nginx&amp;#x2F;
# 安装所有deb包
dpkg -i *.deb
# 如果遇到依赖问题，执行
apt install -f
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;opensuse-suse-xia-zai-rpm-bao&quot;&gt;openSUSE &#x2F; SUSE（下载 rpm 包）&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 下载包及依赖
zypper install --download-only 软件包名
# 例如：下载nginx
zypper install --download-only nginx
# 默认下载路径
ll &amp;#x2F;var&amp;#x2F;cache&amp;#x2F;zypp&amp;#x2F;packages&amp;#x2F;
# 指定下载目录
zypper --pkg-cache-dir=&amp;#x2F;data&amp;#x2F;pkgs&amp;#x2F;nginx install --download-only nginx
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;nei-wang-ji-qi-an-zhuang-2&quot;&gt;========== 内网机器安装 ==========&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;cd &amp;#x2F;data&amp;#x2F;pkgs&amp;#x2F;nginx&amp;#x2F;
rpm -ivh *.rpm
# 或
zypper install --no-refresh *.rpm
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;alpine-linux-xia-zai-apk-bao&quot;&gt;Alpine Linux（下载 apk 包）&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 下载包到指定目录
apk fetch --recursive --output &amp;#x2F;data&amp;#x2F;pkgs&amp;#x2F;nginx&amp;#x2F; nginx
# 参数解释
--recursive    # 下载所有依赖
--output       # 指定输出目录
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;nei-wang-ji-qi-an-zhuang-3&quot;&gt;========== 内网机器安装 ==========&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;cd &amp;#x2F;data&amp;#x2F;pkgs&amp;#x2F;nginx&amp;#x2F;
apk add --allow-untrusted *.apk
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;fang-an-er-tong-bu-wan-zheng-cang-ku-gua-he-da-gui-mo-nei-wang-huan-jing&quot;&gt;方案二：同步完整仓库（适合大规模内网环境）&lt;&#x2F;h1&gt;
&lt;p&gt;如果内网机器很多，每次都手动下载包太麻烦。可以搭建本地 yum&#x2F;apt 仓库。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;centos-shi-yong-reposync-tong-bu-cang-ku&quot;&gt;CentOS 使用 reposync 同步仓库&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 安装同步工具
yum install yum-utils createrepo -y
# 同步base仓库（根据需要选择仓库）
reposync -r base -p &amp;#x2F;data&amp;#x2F;local-repo&amp;#x2F;
# 同步epel仓库
reposync -r epel -p &amp;#x2F;data&amp;#x2F;local-repo&amp;#x2F;
# 创建仓库元数据
createrepo &amp;#x2F;data&amp;#x2F;local-repo&amp;#x2F;base&amp;#x2F;
createrepo &amp;#x2F;data&amp;#x2F;local-repo&amp;#x2F;epel&amp;#x2F;
# 打包传输到内网
cd &amp;#x2F;data&amp;#x2F;
tar -czf local-repo.tar.gz local-repo&amp;#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;nei-wang-ji-qi-pei-zhi-ben-di-cang-ku&quot;&gt;========== 内网机器配置本地仓库 ==========&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 解压仓库文件
tar -xzf local-repo.tar.gz -C &amp;#x2F;data&amp;#x2F;
# 配置yum源
cat &amp;gt; &amp;#x2F;etc&amp;#x2F;yum.repos.d&amp;#x2F;local.repo &amp;lt;&amp;lt;EOF
[local-base]
name=Local Base Repository
baseurl=file:&amp;#x2F;&amp;#x2F;&amp;#x2F;data&amp;#x2F;local-repo&amp;#x2F;base
enabled=1
gpgcheck=0

[local-epel]
name=Local EPEL Repository
baseurl=file:&amp;#x2F;&amp;#x2F;&amp;#x2F;data&amp;#x2F;local-repo&amp;#x2F;epel
enabled=1
gpgcheck=0
EOF

# 清理缓存并测试
yum clean all
yum makecache
yum repolist
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;ubuntu-shi-yong-apt-mirror-tong-bu-cang-ku&quot;&gt;Ubuntu 使用 apt-mirror 同步仓库&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 安装同步工具
apt install apt-mirror -y

# 编辑配置文件
vim &amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;mirror.list
# 修改内容如下：
set base_path    &amp;#x2F;data&amp;#x2F;apt-mirror
deb http:&amp;#x2F;&amp;#x2F;mirrors.aliyun.com&amp;#x2F;ubuntu focal main restricted universe multiverse
deb http:&amp;#x2F;&amp;#x2F;mirrors.aliyun.com&amp;#x2F;ubuntu focal-updates main restricted universe multiverse

# 开始同步（注意：完整同步需要很大空间，100GB+）
apt-mirror

# 打包核心部分传输到内网
cd &amp;#x2F;data&amp;#x2F;apt-mirror&amp;#x2F;mirror&amp;#x2F;mirrors.aliyun.com&amp;#x2F;
tar -czf ubuntu-repo.tar.gz ubuntu&amp;#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;nei-wang-ji-qi-pei-zhi-ben-di-yuan&quot;&gt;========== 内网机器配置本地源 ==========&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 配置本地源
cat &amp;gt; &amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;sources.list &amp;lt;&amp;lt;EOF
deb [trusted=yes] file:&amp;#x2F;&amp;#x2F;&amp;#x2F;data&amp;#x2F;ubuntu-repo focal main restricted universe multiverse
deb [trusted=yes] file:&amp;#x2F;&amp;#x2F;&amp;#x2F;data&amp;#x2F;ubuntu-repo focal-updates main restricted universe multiverse
EOF

# 更新并测试
apt update
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;fang-an-san-rong-qi-jing-xiang-chi-xian-dao-ru-gua-he-rong-qi-hua-ying-yong&quot;&gt;方案三：容器镜像离线导入（适合容器化应用）&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;lian-wang-ji-qi-cao-zuo&quot;&gt;========== 联网机器操作 ==========&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 拉取镜像
docker pull nginx:latest
docker pull mysql:8.0

# 导出镜像为tar文件
docker save nginx:latest -o nginx-latest.tar
docker save mysql:8.0 -o mysql-8.0.tar

# 或批量导出
docker save $(docker images -q) -o all-images.tar
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;nei-wang-ji-qi-cao-zuo&quot;&gt;========== 内网机器操作 ==========&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 导入镜像
docker load -i nginx-latest.tar
docker load -i mysql-8.0.tar

# 查看导入的镜像
docker images

# 使用镜像
docker run -d -p 80:80 nginx:latest
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;chang-jian-wen-ti-pai-cha&quot;&gt;常见问题排查&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;wen-ti-1-yi-lai-bao-ban-ben-chong-tu&quot;&gt;问题1：依赖包版本冲突&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;症状：安装时提示依赖版本不匹配&lt;&#x2F;li&gt;
&lt;li&gt;解决：强制安装或降级&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;rpm -ivh --force --nodeps xxx.rpm  # 不推荐，可能导致系统问题
# 更好的办法：在联网机器上模拟内网环境再下载
yum --installroot=&amp;#x2F;data&amp;#x2F;test-env install nginx
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;wen-ti-2-nei-wang-ji-qi-xi-tong-ban-ben-he-lian-wang-ji-qi-bu-yi-zhi&quot;&gt;问题2：内网机器系统版本和联网机器不一致&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;症状：下载的包在内网无法安装&lt;&#x2F;li&gt;
&lt;li&gt;解决：确保两边系统版本一致&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;cat &amp;#x2F;etc&amp;#x2F;os-release  # 查看系统版本
# 或者使用Docker容器模拟相同环境下载
docker run -it --rm -v &amp;#x2F;data&amp;#x2F;pkgs:&amp;#x2F;pkgs centos:7 bash
yum install --downloadonly --downloaddir=&amp;#x2F;pkgs&amp;#x2F;nginx nginx
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;wen-ti-3-xia-zai-de-bao-bu-quan-an-zhuang-shi-huan-shi-ti-shi-que-yi-lai&quot;&gt;问题3：下载的包不全，安装时还是提示缺依赖&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;原因：可能是内网机器已安装的包版本和下载的依赖不匹配&lt;&#x2F;li&gt;
&lt;li&gt;解决：使用 yumdownloader 下载所有依赖&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;yum install yum-utils -y
yumdownloader --resolve --destdir=&amp;#x2F;data&amp;#x2F;pkgs&amp;#x2F;nginx nginx

# 参数解释
--resolve    # 解析并下载所有依赖
--destdir    # 指定下载目录
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;shi-yong-ji-qiao-zong-jie&quot;&gt;实用技巧总结&lt;&#x2F;h1&gt;
&lt;ol&gt;
&lt;li&gt;模拟内网环境下载&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;ul&gt;
&lt;li&gt;在联网机器上创建和内网相同的干净环境&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;docker run -it --rm -v &amp;#x2F;data:&amp;#x2F;data centos:7 bash
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;在容器内下载，确保依赖准确&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;批量下载多个软件&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;ul&gt;
&lt;li&gt;创建软件列表&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;cat &amp;gt; software-list.txt &amp;lt;&amp;lt;EOF
nginx
mysql-server
git
vim
EOF
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;批量下载&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;while read pkg; do
  yum install --downloadonly --downloaddir=&amp;#x2F;data&amp;#x2F;pkgs&amp;#x2F;$pkg $pkg
done &amp;lt; software-list.txt
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;检查下载是否完整&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;ul&gt;
&lt;li&gt;列出所有rpm包及依赖关系&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;rpm -qpR &amp;#x2F;data&amp;#x2F;pkgs&amp;#x2F;nginx&amp;#x2F;*.rpm
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;mp.weixin.qq.com&#x2F;s&#x2F;bmTND8Se398a1XdB4J5YYA?poc_token=HIi8-WijPaouTTo4Dbrcz5nkTRaeCJf5j-M5tgnw&quot;&gt;转载地址&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>linux bios刷新工具fwupd</title>
        <published>2025-10-22T23:39:05+08:00</published>
        <updated>2025-10-22T23:39:05+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/10/linux bios刷新工具fwupd/"/>
        <id>https://vercel.juzhong.xyz/2025/10/linux bios刷新工具fwupd/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/10/linux bios刷新工具fwupd/">&lt;h1 id=&quot;linux-gu-jian-shua-xin-gong-ju&quot;&gt;Linux 固件刷新工具&lt;&#x2F;h1&gt;
&lt;p&gt;fwupd： 这是一个 Linux 上的通用固件更新守护进程。如果您的电脑硬件制造商支持 fwupd，您可以在 Debian 系统上安装并使用它来检查和安装固件更新。&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt update
sudo apt install fwupd
sudo fwupdmgr refresh
sudo fwupdmgr get-updates
sudo fwupdmgr update
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>免U盘安装debian系统</title>
        <published>2025-10-22T22:33:33+08:00</published>
        <updated>2025-10-22T22:33:33+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/10/免U盘安装debian系统/"/>
        <id>https://vercel.juzhong.xyz/2025/10/免U盘安装debian系统/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/10/免U盘安装debian系统/">&lt;h1 id=&quot;shi-yong-debootstrap-gou-jian-yi-ge-yuan-sheng-debian-xi-tong-bing-yin-dao-qi-dong-tui-jian&quot;&gt;使用 debootstrap 构建一个原生 Debian 系统并引导启动（推荐）&lt;&#x2F;h1&gt;
&lt;p&gt;这是最干净、最安全、完全不需要U盘的方法。
你会在 Ubuntu 里“手工安装”一个 Debian，然后让 grub 启动它。&lt;&#x2F;p&gt;
&lt;p&gt;如果没有空闲分区， 缩小 Ubuntu 的根分区，腾出 20GB 以上空间，创建一个 ext4 分区。&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;lsblk
sudo apt update
sudo apt install debootstrap grub2 systemd-container
# debootstrap 安装 Debian（例如 Debian 13 Trixie）
sudo debootstrap trixie &amp;#x2F;mnt&amp;#x2F;debian http:&amp;#x2F;&amp;#x2F;deb.debian.org&amp;#x2F;debian
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;这一步会自动在 &#x2F;mnt&#x2F;debian 下生成一个完整的 Debian 根文件系统。&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 挂载关键目录并进入 Debian 环境
mount &amp;#x2F;dev&amp;#x2F;nvme0n1p3&amp;#x2F; &amp;#x2F;mnt&amp;#x2F;debian&amp;#x2F;
mount --bind &amp;#x2F;dev &amp;#x2F;mnt&amp;#x2F;debian&amp;#x2F;dev
mount --bind &amp;#x2F;dev&amp;#x2F;pts &amp;#x2F;mnt&amp;#x2F;debian&amp;#x2F;dev&amp;#x2F;pts
mount --bind &amp;#x2F;proc &amp;#x2F;mnt&amp;#x2F;debian&amp;#x2F;proc
mount --bind &amp;#x2F;sys &amp;#x2F;mnt&amp;#x2F;debian&amp;#x2F;sys
mount --bind &amp;#x2F;run &amp;#x2F;mnt&amp;#x2F;debian&amp;#x2F;run
mount &amp;#x2F;dev&amp;#x2F;nvme0n1p1 &amp;#x2F;mnt&amp;#x2F;debian&amp;#x2F;boot&amp;#x2F;efi   # 替换为你的 ESP 分区

sudo chroot &amp;#x2F;mnt&amp;#x2F;debian

# 在 chroot 中配置系统（此时你“已经在 Debian 中”）
# 设置主机名
echo debian &amp;gt; &amp;#x2F;etc&amp;#x2F;hostname
# 配置 apt 源
cat &amp;gt; &amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;sources.list.d&amp;#x2F;debian.sources &amp;lt;&amp;lt;EOF
Types: deb
URIs: http:&amp;#x2F;&amp;#x2F;mirrors.ustc.edu.cn&amp;#x2F;debian
Suites: trixie trixie-updates
Components: main contrib non-free non-free-firmware
Signed-By: &amp;#x2F;usr&amp;#x2F;share&amp;#x2F;keyrings&amp;#x2F;debian-archive-keyring.gpg

Types: deb
URIs: http:&amp;#x2F;&amp;#x2F;mirrors.ustc.edu.cn&amp;#x2F;debian-security
Suites: trixie-security
Components: main contrib non-free non-free-firmware
Signed-By: &amp;#x2F;usr&amp;#x2F;share&amp;#x2F;keyrings&amp;#x2F;debian-archive-keyring.gpg
EOF
apt update
apt install -y linux-image-amd64 locales sudo vim network-manager
apt install -y grub-efi-amd64-bin grub-efi-amd64-signed grub-efi-amd64
apt install -y systemd vim wget curl tmux openssh-server iproute2 net-tools ifupdown systemd-resolved
apt install -y firmware-linux firmware-realtek firmware-iwlwifi
apt install -y iw wpasupplicant wireless-tools
apt install firmware-sof-signed # firmware-intel-sound
apt install -y tasksel
tasksel install standard --new-install
# 这会安装约 300MB 的常用包，包括完整网络支持、man 手册、日志工具等。
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;pei-zhi-wang-luo-he-efiqi-dong-xiang&quot;&gt;配置网络和efi启动项&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;mkdir -p &amp;#x2F;etc&amp;#x2F;wpa_supplicant
# 可选： 使用 wpa_passphrase 工具生成加密的配置，而不是明文密码
# wpa_passphrase YOUR_SSID YOUR_PASSWORD &amp;gt; &amp;#x2F;etc&amp;#x2F;wpa_supplicant&amp;#x2F;wpa_supplicant.conf
cat&amp;lt;&amp;lt;EOF &amp;gt; &amp;#x2F;etc&amp;#x2F;wpa_supplicant&amp;#x2F;wpa_supplicant-wlp0s20f3.conf
ctrl_interface=&amp;#x2F;run&amp;#x2F;wpa_supplicant
update_config=1
network={
    ssid=&amp;quot;wifi ssid&amp;quot;
    psk=&amp;quot;wifi passwd&amp;quot;
}
EOF
cat &amp;gt;&amp;#x2F;etc&amp;#x2F;systemd&amp;#x2F;network&amp;#x2F;20-wifi.network &amp;lt;&amp;lt;&amp;#x27;EOF&amp;#x27;
[Match]
Name=wlp0s20f3
[Network]
DHCP=yes
EOF
chmod 600 &amp;#x2F;etc&amp;#x2F;wpa_supplicant&amp;#x2F;wpa_supplicant-wlp0s20f3.conf
systemctl enable systemd-networkd
systemctl enable systemd-resolved
systemctl enable wpa_supplicant@wlp0s20f3

# 这会在 wpa_supplicant 连接 Wi-Fi 成功后自动获取 IP

# 使用更现代的 iwd（更简单）
apt install -y iwd
systemctl enable iwd
# 连接 Wi-Fi（交互式）：
iwctl
# [iwd]# device list
# [iwd]# station wlp2s0 scan
# [iwd]# station wlp2s0 get-networks
# [iwd]# station wlp2s0 connect 你的WiFi名称
# [iwd]# exit
# 一旦连上，systemd-networkd 会自动分配 IP 并联网。
# iwd 会自动保存密码，下次开机自动连接。

adduser peter
adduser peter sudo
blkid  # 查看新分区 UUID
cat&amp;lt;&amp;lt;EOF &amp;gt;&amp;gt; &amp;#x2F;etc&amp;#x2F;fstab
UUID=你的新分区UUID &amp;#x2F; ext4 defaults 0 1
EOF
# 安装 grub 到磁盘并更新菜单
# grub-install &amp;#x2F;dev&amp;#x2F;nvme0n1
grub-install --target=x86_64-efi --efi-directory=&amp;#x2F;boot&amp;#x2F;efi --bootloader-id=DEBIAN --force

update-grub
# 它会检测到你的 Ubuntu + Debian 双系统。
# 重启后你会在 GRUB 菜单里看到 “Debian GNU&amp;#x2F;Linux”。
sudo reboot

sudo efibootmgr --create --disk &amp;#x2F;dev&amp;#x2F;nvme0n1 --part 1 --label &amp;quot;Debian&amp;quot; --loader &amp;#x27;\EFI\debian\grubx64.efi&amp;#x27;
# &amp;#x2F;dev&amp;#x2F;nvme0n1 和 --part 1 要替换为你的实际 EFI 分区所在磁盘与分区号。
# 可用 lsblk -f 或 findmnt &amp;#x2F;boot&amp;#x2F;efi 查看。
# 如果你的路径是 &amp;#x2F;boot&amp;#x2F;efi&amp;#x2F;EFI&amp;#x2F;debian&amp;#x2F;grubx64.efi，那 loader 路径就对了。
sudo efibootmgr --bootnum 0001 --bootorder 0001,0000,0002
sudo efibootmgr -v
# 重启后使用F12 可以选择efi的条目
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;deng-lu-debianzhong-an-zhuang&quot;&gt;登录debian中安装&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# apt install locales
# dpkg-reconfigure locales
sudo vim &amp;#x2F;etc&amp;#x2F;locale.gen
# 在文件中找到包含 zh_CN.UTF-8 的那一行，并取消注释（即删除行首的 # 符号）。
#zh_CN.GBK GBK
zh_CN.UTF-8 UTF-8   &amp;lt;-- 确保这一行没有 #
#zh_HK.UTF-8 UTF-8

# 设置系统默认 locale（可选）：
sudo update-locale LANG=zh_CN.UTF-8
# 或者保留英文界面但支持中文显示：
sudo update-locale LANG=en_US.UTF-8 LANGUAGE=zh_CN:en
# 安装简体中文语言支持包
sudo apt-get install language-pack-zh-hans
# sudo localedef -i zh_CN -f UTF-8 zh_CN.UTF-8
# 较完整，适合新硬件，推荐主流使用：
sudo apt install task-gnome-desktop -y
sudo apt install -y network-manager-gnome

sudo systemctl disable wpa_supplicant@wlp0s20f3
sudo systemctl enable NetworkManager
sudo systemctl start NetworkManager
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;shi-yong-systemd-nspawn-qi-dong-wan-zheng-debian-rong-qi-xi-tong&quot;&gt;使用 systemd-nspawn 启动完整 Debian 容器系统&lt;&#x2F;h1&gt;
&lt;p&gt;如果你暂时不想重启，可以直接在 Ubuntu 下运行“原生 Debian 系统容器”：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo debootstrap trixie &amp;#x2F;srv&amp;#x2F;debian http:&amp;#x2F;&amp;#x2F;deb.debian.org&amp;#x2F;debian
sudo systemd-nspawn -D &amp;#x2F;srv&amp;#x2F;debian
# 这会直接进入一个 Debian 容器（有独立的 &amp;#x2F;etc、&amp;#x2F;usr、apt、systemd），
# 就像一个轻量虚拟机，非常适合测试迁移。
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;shi-yong-grub-yin-dao-iso-jing-xiang-zhi-jie-an-zhuang-debian-wu-upan-an-zhuang&quot;&gt;使用 grub 引导 ISO 镜像直接安装 Debian（无U盘安装）&lt;&#x2F;h1&gt;
&lt;p&gt;可以让 grub 直接从 Debian ISO 启动：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;wget https:&amp;#x2F;&amp;#x2F;cdimage.debian.org&amp;#x2F;debian-cd&amp;#x2F;current&amp;#x2F;amd64&amp;#x2F;iso-cd&amp;#x2F;debian-13.0.0-amd64-netinst.iso -O &amp;#x2F;boot&amp;#x2F;debian.iso
cat &amp;lt;&amp;lt;EOF | sudo tee -a &amp;#x2F;etc&amp;#x2F;grub.d&amp;#x2F;40_custom
menuentry &amp;quot;Install Debian 13 (from ISO)&amp;quot; {
    set isofile=&amp;quot;&amp;#x2F;boot&amp;#x2F;debian.iso&amp;quot;
    loopback loop (hd0,3)$isofile
    linux (loop)&amp;#x2F;install.amd&amp;#x2F;vmlinuz boot=install iso-scan&amp;#x2F;filename=$isofile
    initrd (loop)&amp;#x2F;install.amd&amp;#x2F;initrd.gz
}
EOF
sudo update-grub
# 重启，选择 “Install Debian 13 (from ISO)”
# 安装时选择 保留 &amp;#x2F;home 分区，即可实现无U盘切换系统。
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;EOF&lt;&#x2F;p&gt;
&lt;h1 id=&quot;wang-luo-qi-dong-pxe-huo-ipxe-gao-ji&quot;&gt;网络启动（PXE）或 iPXE（高级）&lt;&#x2F;h1&gt;
&lt;p&gt;若你的笔记本支持 PXE 网络启动，可通过局域网加载 Debian 安装器。
需另一台电脑作为 TFTP&#x2F;DHCP 服务器，配置复杂，一般用户不推荐。&lt;&#x2F;p&gt;
&lt;h1 id=&quot;chuang-jian-xu-ni-ci-pan-zuo-wei-lin-shi-live-huan-jing-ji-bu-tui-jian&quot;&gt;创建虚拟磁盘作为临时“Live 环境”（极不推荐）&lt;&#x2F;h1&gt;
&lt;p&gt;理论上可用 kexec 加载新内核 + initrd 实现“内存中切换”，但操作复杂、风险极高，且仍需处理分区缩小问题。&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>linux电源管理</title>
        <published>2025-10-18T15:08:53+08:00</published>
        <updated>2025-10-18T15:08:53+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/10/linux电源管理/"/>
        <id>https://vercel.juzhong.xyz/2025/10/linux电源管理/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/10/linux电源管理/">&lt;h1 id=&quot;cha-kan-suspendxiu-mian-pei-zhi-mo-shi&quot;&gt;查看suspend休眠配置模式&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;cat &amp;#x2F;sys&amp;#x2F;power&amp;#x2F;mem_sleep
echo deep | sudo tee &amp;#x2F;sys&amp;#x2F;power&amp;#x2F;mem_sleep
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;pei-zhi-hibernatexiu-mian&quot;&gt;配置hibernate休眠&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;cat &amp;#x2F;etc&amp;#x2F;fstab
swapon --show
sudo swapoff -a
sudo dd if=&amp;#x2F;dev&amp;#x2F;zero of=&amp;#x2F;swapfile bs=1G count=17
sudo swapon &amp;#x2F;swapfile

# 获取swap文件的offset
sudo filefrag -v &amp;#x2F;swapfile | awk &amp;#x27;{if($1==&amp;quot;0:&amp;quot;) print $4}&amp;#x27;
# 查看根分区 UUID
findmnt -no UUID -T &amp;#x2F;

sudo vim &amp;#x2F;etc&amp;#x2F;default&amp;#x2F;grub
# GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash mem_sleep_default=deep resume=UUID=&amp;lt;磁盘分区UUID&amp;gt; resume_offset=&amp;lt;swap文件偏移量&amp;gt;&amp;quot;
sudo update-grub
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;pei-zhi-dian-yuan-guan-li&quot;&gt;配置电源管理&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;cat &amp;lt;&amp;lt;EOF &amp;gt; &amp;#x2F;etc&amp;#x2F;systemd&amp;#x2F;sleep.conf.d&amp;#x2F;enable-sleep.conf
AllowSuspend=yes
AllowHibernation=yes
HibernateMode=platform shutdown
HibernateState=disk
AllowSuspendThenHibernate=yes
AllowHybridSleep=yes
SuspendState=mem standby freeze
EOF

sudo mkdir &amp;#x2F;etc&amp;#x2F;systemd&amp;#x2F;logind.conf.d
cat &amp;lt;&amp;lt;EOF | sudo tee &amp;#x2F;etc&amp;#x2F;systemd&amp;#x2F;logind.conf.d&amp;#x2F;override.conf
[Login]
HandlePowerKey=suspend-then-hibernate
HandleRebootKey=reboot
HandleRebootKeyLongPress=poweroff
HandleSuspendKey=suspend
HandleSuspendKeyLongPress=hibernate
IdleAction=suspend-then-hibernate
IdleActionSec=30min
EOF

systemd-analyze cat-config systemd&amp;#x2F;sleep.conf
systemd-analyze cat-config systemd&amp;#x2F;logind.conf
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>rdp等连接linuxGUI的工具使用</title>
        <published>2025-10-17T11:25:34+08:00</published>
        <updated>2025-10-17T11:25:34+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/10/software/rdp等连接linuxGUI的工具使用/"/>
        <id>https://vercel.juzhong.xyz/2025/10/software/rdp等连接linuxGUI的工具使用/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/10/software/rdp等连接linuxGUI的工具使用/">&lt;h1 id=&quot;chang-yong-gong-ju&quot;&gt;常用工具&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;xrdp： 主要适配x11 xorg后端&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt install xrdp
sudo apt install xfce4
echo xfce4-session &amp;gt; ~&amp;#x2F;.xsession
sudo systemctl restart xrdp
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;gnome remote desktop： gnome桌面环境自带， 支持wayland&lt;&#x2F;li&gt;
&lt;li&gt;FreeRDP3： freerdp-shadow 组件据说支持 Wayland,这可能是未来 XRDP 自身支持 Wayland 的技术基础&lt;&#x2F;li&gt;
&lt;li&gt;Sunshine + Moonlight: Sunshine（服务端） + Moonlight（客户端）组合提供高性能的远程游戏串流，对 Wayland 支持较好&lt;&#x2F;li&gt;
&lt;li&gt;RustDesk: ustDesk 是另一个值得关注的跨平台远程桌面替代品&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;yuan-cheng-jian-pan-shu-biao&quot;&gt;远程键盘鼠标&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;x2x：这是一款经典的、专为Unix&#x2F;Linux系统设计的工具
它可以通过网络将一台电脑的键盘和鼠标共享给另一台，从而实现跨机器的屏幕扩展，让你的鼠标可以从一台电脑的屏幕边缘“移动”到另一台电脑的屏幕上。&lt;&#x2F;li&gt;
&lt;li&gt;Barrier：它是知名软件Synergy的开源分支，同样可以实现跨计算机共享一套键鼠
功能与x2x类似，配置界面可能更为友好一些。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;vkms&quot;&gt;vkms&lt;&#x2F;h1&gt;
&lt;p&gt;sudo modprobe vkms
步骤 1：安装 linux-image-amd64-unsigned（含 vkms）&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# Debian 13 默认内核无 vkms，需 unsigned 版
sudo apt update
sudo apt install linux-image-amd64-unsigned linux-headers-amd64-unsigned
sudo reboot
# 重启后选新内核（GRUB → Advanced options）
步骤 2：启用 vkms 虚拟屏（注入 EDID）
# 加载 vkms
sudo modprobe vkms
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 生成 EDID（1920x1080）
sudo apt install edid-generator -y
edid-generator --name &amp;quot;Sunshine_Virtual&amp;quot; --width 1920 --height 1080 &amp;gt; &amp;#x2F;tmp&amp;#x2F;vkms.edid
# 注入 EDID（假设 vkms 创建 card1）
sudo sh -c &amp;#x27;cat &amp;#x2F;tmp&amp;#x2F;vkms.edid &amp;gt; &amp;#x2F;sys&amp;#x2F;kernel&amp;#x2F;debug&amp;#x2F;dri&amp;#x2F;1&amp;#x2F;virtual_edid&amp;#x27;
echo &amp;quot;edid&amp;quot; | sudo tee &amp;#x2F;sys&amp;#x2F;class&amp;#x2F;drm&amp;#x2F;card1-VIRTUAL-1&amp;#x2F;status
# 通知 GNOME 启用
# 安装 wlroots-tools（用于唤醒输出）
sudo apt install wlroots-tools
# 强制启用（即使 GNOME 暂未发现）
wlr-randr --output VIRTUAL-1 --on --mode 1920x1080@60
# 触发 GNOME 重扫描
busctl --user call org.gnome.Mutter.DisplayConfig &amp;#x2F;org&amp;#x2F;gnome&amp;#x2F;Mutter&amp;#x2F;DisplayConfig \
  org.gnome.Mutter.DisplayConfig ApplyMonitorsConfig 2 su a(ua{sv}) 2 1 1 0 0 &amp;quot;&amp;quot;
# 图形界面启用（按 Alt 键！）
# 打开 Settings → Displays
# 按住 Alt 键
# 点击 ⋮ → Display arrangement
# 启用新出现的 &amp;quot;Unknown Display&amp;quot;
# Apply
# wlr-randr 显示 VIRTUAL-1 enabled
# Sunshine 可选为第二屏
# Apps 可拖入
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 查看是否生效
ls &amp;#x2F;sys&amp;#x2F;class&amp;#x2F;drm&amp;#x2F;          # 应出现 card1-VIRTUAL-1 等
cat &amp;#x2F;sys&amp;#x2F;kernel&amp;#x2F;debug&amp;#x2F;dri&amp;#x2F;1&amp;#x2F;name  # 显示 &amp;quot;vkms&amp;quot;

# pipewire
pw-cli ls Node
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;cha-kan-xian-shi-qi&quot;&gt;查看显示器&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt install read-edid hwinfo
sudo hwinfo --monitor
cat &amp;#x2F;sys&amp;#x2F;class&amp;#x2F;drm&amp;#x2F;card0*&amp;#x2F;edid | parse-edid
sudo apt install lshw
sudo lshw -C display
sudo apt install edid-decode
edid-decode &amp;#x2F;sys&amp;#x2F;class&amp;#x2F;drm&amp;#x2F;card1-DP-1&amp;#x2F;edid
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>问题排查记录表</title>
        <published>2025-10-13T11:54:42+08:00</published>
        <updated>2025-10-13T11:54:42+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/10/问题排查记录表/"/>
        <id>https://vercel.juzhong.xyz/2025/10/问题排查记录表/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/10/问题排查记录表/">&lt;h1 id=&quot;vm-ubuntu24-04-xu-ni-ji-guan-ji-jie-mian-qia-zhu&quot;&gt;vm ubuntu24.04 虚拟机关机界面卡住&lt;&#x2F;h1&gt;
&lt;p&gt;通过添加启动内核的参数， 在virt-view界面直接看到关机流程被阻塞在ntopng.service上&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo vim &amp;#x2F;etc&amp;#x2F;default&amp;#x2F;grub
# GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet splash&amp;quot;
# GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;&amp;quot;
# loglevel=7 会显示全部内核消息。
GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;loglevel=7&amp;quot;
sudo update-grub

sudo systemctl edit ntopng.service
# TimeoutStopSec=3s
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;base64fan-xu-lie-hua-wen-jian-nei-rong-shi-bai&quot;&gt;base64反序列化文件内容失败&lt;&#x2F;h1&gt;
&lt;ol&gt;
&lt;li&gt;使用serde_json 序列化一个对象， 并base64编码后打印出来&lt;&#x2F;li&gt;
&lt;li&gt;复制打印的base64字符串， 并保存到文件 &#x2F;tmp&#x2F;file&lt;&#x2F;li&gt;
&lt;li&gt;程序中读取&#x2F;tmp&#x2F;file内容，base64解码并使用serde_json反序列化， 会报错&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;yuan-yin&quot;&gt;原因&lt;&#x2F;h2&gt;
&lt;p&gt;通过排查发现，手动复制到文件&#x2F;tmp&#x2F;file的内容结尾多了一个换行符\n&lt;&#x2F;p&gt;
&lt;h2 id=&quot;jie-jue&quot;&gt;解决&lt;&#x2F;h2&gt;
&lt;p&gt;删除结尾的\n字符即可&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;truncate -s -1 &amp;#x2F;tmp&amp;#x2F;file
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>serde_json bigfix反序列化文件内容失败</title>
        <published>2025-10-10T17:45:35+08:00</published>
        <updated>2025-10-10T17:45:35+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/10/serde_json bigfix反序列化文件内容失败/"/>
        <id>https://vercel.juzhong.xyz/2025/10/serde_json bigfix反序列化文件内容失败/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/10/serde_json bigfix反序列化文件内容失败/">&lt;h1 id=&quot;xian-xiang&quot;&gt;现象&lt;&#x2F;h1&gt;
&lt;ol&gt;
&lt;li&gt;使用serde_json 序列化一个对象， 并base64编码后打印出来&lt;&#x2F;li&gt;
&lt;li&gt;复制打印的base64字符串， 并保存到文件 &#x2F;tmp&#x2F;file&lt;&#x2F;li&gt;
&lt;li&gt;程序中读取&#x2F;tmp&#x2F;file内容，base64解码并使用serde_json反序列化， 会报错&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h1 id=&quot;yuan-yin&quot;&gt;原因&lt;&#x2F;h1&gt;
&lt;p&gt;通过排查发现，手动复制到文件&#x2F;tmp&#x2F;file的内容结尾多了一个换行符\n&lt;&#x2F;p&gt;
&lt;h1 id=&quot;jie-jue&quot;&gt;解决&lt;&#x2F;h1&gt;
&lt;p&gt;删除结尾的\n字符即可&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;truncate -s -1 &amp;#x2F;tmp&amp;#x2F;file
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>cockpit管理qemu虚拟机</title>
        <published>2025-10-09T20:04:52+08:00</published>
        <updated>2025-10-09T20:04:52+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/10/cockpit管理qemu虚拟机/"/>
        <id>https://vercel.juzhong.xyz/2025/10/cockpit管理qemu虚拟机/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/10/cockpit管理qemu虚拟机/">&lt;h1 id=&quot;gao-xiao-deng-lu-xu-ni-ji-gui&quot;&gt;高效登录虚拟机GUI&lt;&#x2F;h1&gt;
&lt;p&gt;使用virt-viewer客户端spice协议登录&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;apt install virt-viewer
virt-viewer --reconnect win11
virt-viewer --wait win11
virsh domdisplay win11
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;lian-jie-ju-yu-wang-de-xu-ni-ji&quot;&gt;连接局域网的虚拟机&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;#1. 如果远程宿主机也在跑 libvirtd 并允许远程连接，你还可以直接用：
# 这样 virt-viewer 会先通过 libvirt 查询到 SPICE 端口，然后自动帮你连上去（不用手动写端口）。
# 通常推荐这种方式，安全性更好（走 SSH）
virt-viewer -c qemu+ssh:&amp;#x2F;&amp;#x2F;user@&amp;lt;宿主机IP&amp;gt;&amp;#x2F;system &amp;lt;VM名称或UUID&amp;gt;
virt-viewer -c qemu+ssh:&amp;#x2F;&amp;#x2F;peter@192.168.7.99&amp;#x2F;system win11

#2. 开放spice监听外部地址
# 修改listen=&amp;#x27;0.0.0.0&amp;#x27; 表示允许外部访问（默认可能是 127.0.0.1，那就只能本机连）。
# port 可以固定（如 5901）或自动分配
sudo virsh list
sudo virsh dominfo win11
sudo grep -C 0 --group-separator=&amp;quot;======&amp;quot; listen &amp;#x2F;etc&amp;#x2F;libvirt&amp;#x2F;qemu&amp;#x2F;win11.xml
sudo sed -i&amp;#x27;&amp;#x27; &amp;#x27;s&amp;#x2F;127.0.0.1&amp;#x2F;0.0.0.0&amp;#x2F;&amp;#x27; &amp;#x2F;etc&amp;#x2F;libvirt&amp;#x2F;qemu&amp;#x2F;win11.xml
# 一般需要配置密码，否则太不安全
## &amp;lt;graphics type=&amp;#x27;spice&amp;#x27; port=&amp;#x27;5901&amp;#x27; listen=&amp;#x27;0.0.0.0&amp;#x27;&amp;gt;
##   &amp;lt;passwd&amp;gt;123&amp;lt;&amp;#x2F;passwd&amp;gt;
## &amp;lt;&amp;#x2F;graphics&amp;gt;
virt-viewer --spice-uri spice:&amp;#x2F;&amp;#x2F;192.168.7.99:5901 --spice-password 123

cat &amp;lt;&amp;lt;EOF &amp;gt; win11.vv
[virt-viewer]
type=spice
host=192.168.7.99
port=5901
password=123
delete-this-file=1
fullscreen=0
EOF
remote-viewer vm.vv
# 或者直接双击执行

# 可能的问题
# 音频&amp;#x2F;USB 不工作 SPICE 的辅助通道（如 5902）可能被防火墙阻断，需开放连续端口范围
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;qi-dong-wen-ti-pai-cha&quot;&gt;启动问题排查&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;从debian12 升级到debian13系统后， cockpit的web页面登录失败&lt;&#x2F;li&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo systemctl status cockpit.service
# 2月 03 14:00:57 xiao99 cockpit-tls[2028483]: cockpit-tls: gnutls_handshake failed: A TLS fatal alert has been received.
# 2月 03 14:01:06 xiao99 cockpit-tls[2028483]: cockpit-tls: gnutls_handshake failed: A TLS fatal alert has been received.

# 另外网页会自动刷行页面，后续的cockpit.socket 会崩溃，出现另一个报错信息, 这个应该不是根因
# Dependency failed for cockpit.service - Cockpit Web Service.

gnutls-cli --insecure -p 9090 localhost
# Processed 0 CA certificate(s).
# Resolving &amp;#x27;localhost:9090&amp;#x27;...
# Connecting to &amp;#x27;127.0.0.1:9090&amp;#x27;...
# *** Fatal error: Error in the pull function.

echo -e &amp;quot;GET &amp;#x2F; HTTP&amp;#x2F;1.0\r\n\r\n&amp;quot; | socat - OPENSSL:127.0.0.1:9090,verify=0
# 2026&amp;#x2F;02&amp;#x2F;03 14:18:00 socat[2106042] W refusing to set empty SNI host name
# 2026&amp;#x2F;02&amp;#x2F;03 14:18:00 socat[2106042] W SSL_connect(): Connection reset by peer
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;zheng-shu-wen-ti-jie-jue&quot;&gt;证书问题解决&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo systemd-run \
  --unit=cockpit-cert-debug \
  --pty \
  -p RuntimeDirectory=cockpit&amp;#x2F;tls \
  -p WorkingDirectory=&amp;#x2F; \
  &amp;#x2F;usr&amp;#x2F;lib&amp;#x2F;cockpit&amp;#x2F;cockpit-certificate-ensure --for-cockpit-tls
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo systemctl reset-failed cockpit-debug.service
sudo systemd-run \
  --unit=cockpit-debug \
  --pty \
  -p WorkingDirectory=&amp;#x2F;run \
  -p RuntimeDirectory=cockpit&amp;#x2F;tls \
  -p DynamicUser=yes \
  -p User=cockpit-systemd-service \
  -p Group=cockpit-wsinstance-socket \
  -p NoNewPrivileges=yes \
  -p ProtectSystem=strict \
  -p PrivateDevices=yes \
  -p ProtectKernelTunables=yes \
  -p MemoryDenyWriteExecute=yes \
  -p PrivateIPC=yes \
  -p PrivateNetwork=yes \
  &amp;#x2F;usr&amp;#x2F;lib&amp;#x2F;cockpit&amp;#x2F;cockpit-tls

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo systemctl enable --now \
  cockpit.socket \
  cockpit-wsinstance-http.socket \
  cockpit-wsinstance-https-factory.socket
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>rust关于生命周期: Mutex Fn</title>
        <published>2025-10-09T16:23:32+08:00</published>
        <updated>2025-10-09T16:23:32+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/10/rust关于生命周期: Mutex Fn/"/>
        <id>https://vercel.juzhong.xyz/2025/10/rust关于生命周期: Mutex Fn/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/10/rust关于生命周期: Mutex Fn/">&lt;h1 id=&quot;yu-dao-de-wen-ti&quot;&gt;遇到的问题&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;let mut b = SslConnector::builder(SslMethod::tls_client()).map_err(|e|e.to_string())?;
b.set_verify(SslVerifyMode::NONE);
if let Some(file) = &amp;amp;config.sshkeylogfile {
    let file = OpenOptions::new()
        .create(true)
        .append(true)
        .open(file)
        .map_err(|e|e.to_string())?;
    let file = Mutex::new(file);

    &amp;#x2F;&amp;#x2F; 重点这里： 
    &amp;#x2F;&amp;#x2F; 1. 即需要move将file的生命周期延长
    &amp;#x2F;&amp;#x2F; 2. 又需要file.lock().unwrap() 这样使用捕获的变量， 这样才能多次调用
    &amp;#x2F;&amp;#x2F; 可以理解为 struct Fn { file: TFile }, Fn 结构通过move保存了值类型file， 同时使用Mutex保证了内部可变性？？？
    b.set_keylog_callback(move |_ssl, str| {
        &amp;#x2F;&amp;#x2F; let file = file; &amp;#x2F;&amp;#x2F; 这样调用一次就消耗了file,不能多次调用这个回调
        let mut file = file.lock().unwrap();
        let _ = file.write_all(str.as_bytes());
        let _ = file.write_all(b&amp;quot;\n&amp;quot;);
    });
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>linux 录屏并视频剪辑进行标注</title>
        <published>2025-10-09T14:14:57+08:00</published>
        <updated>2025-10-09T14:14:57+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/10/linux 录屏并视频剪辑进行标注/"/>
        <id>https://vercel.juzhong.xyz/2025/10/linux 录屏并视频剪辑进行标注/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/10/linux 录屏并视频剪辑进行标注/">&lt;h1 id=&quot;jie-ping-lu-ping-gong-ju&quot;&gt;截屏、录屏工具&lt;&#x2F;h1&gt;
&lt;p&gt;录屏软件使用ubuntu gnome自带的截屏工具&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;直接PriSc 键即可开启&lt;&#x2F;li&gt;
&lt;li&gt;选择区域&lt;&#x2F;li&gt;
&lt;li&gt;开始录屏即可&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h1 id=&quot;shi-pin-jian-ji&quot;&gt;视频剪辑&lt;&#x2F;h1&gt;
&lt;p&gt;使用开源的shotcut进行简单的视频剪辑&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;apt install shotcut
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol&gt;
&lt;li&gt;打开shotcut后可以直接拖拽视频文件到软件中
可能会遇到视频需要预处理的情况， 根据情况正常处理即可
&lt;img src=&quot;&#x2F;images&#x2F;2025-10-09-14-31-08.png&quot; alt=&quot;视频预处理&quot; &#x2F;&gt;&lt;&#x2F;li&gt;
&lt;li&gt;从播放列表中拖拽视频到[时间线]轨道
注意视频在时间线上是可以左右拖动的， 如果没有顶格左边， 则会在开始插入黑屏？！
&lt;img src=&quot;&#x2F;images&#x2F;2025-10-09-14-33-33.png&quot; alt=&quot;时间线&quot; &#x2F;&gt;&lt;&#x2F;li&gt;
&lt;li&gt;复制一条轨道V2， 并复制视频放置到轨道V2上
现在两条轨道的视频一样
&lt;img src=&quot;&#x2F;images&#x2F;2025-10-09-14-58-40.png&quot; alt=&quot;复制轨道&quot; &#x2F;&gt;&lt;&#x2F;li&gt;
&lt;li&gt;轨道V1在下层， 轨道V2在上层， 并分别添加滤镜
&lt;img src=&quot;&#x2F;images&#x2F;2025-10-09-15-20-30.png&quot; alt=&quot;滤镜&quot; &#x2F;&gt;
V1：添加【棕褐色调】
V2：添加【蒙板：简易形状】, 操作为： 减去&lt;&#x2F;li&gt;
&lt;li&gt;观看效果， 导出视频即可&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>feat: 编程 术语-Terminology</title>
        <published>2025-10-08T17:36:54+08:00</published>
        <updated>2025-10-08T17:36:54+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/10/feat: 编程 术语-Terminology/"/>
        <id>https://vercel.juzhong.xyz/2025/10/feat: 编程 术语-Terminology/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/10/feat: 编程 术语-Terminology/">&lt;h1 id=&quot;terminology&quot;&gt;terminology&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;良构&lt;&#x2F;li&gt;
&lt;li&gt;硬编码 =&amp;gt; 变量&lt;&#x2F;li&gt;
&lt;li&gt;魔术&lt;&#x2F;li&gt;
&lt;li&gt;PKI 公钥基础设施（Public Key Infrastructure）&lt;&#x2F;li&gt;
&lt;li&gt;PKCS (Public-Key Cryptography Standards，公钥密码学标准)&lt;&#x2F;li&gt;
&lt;li&gt;key_forward&lt;&#x2F;li&gt;
&lt;li&gt;key_backward&lt;&#x2F;li&gt;
&lt;li&gt;digest_forward&lt;&#x2F;li&gt;
&lt;li&gt;digest_backward&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;lian-jie&quot;&gt;链接&lt;&#x2F;h1&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>cloudflare代理的常用网站</title>
        <published>2025-10-08T16:49:27+08:00</published>
        <updated>2025-10-08T16:49:27+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/10/cloudflare代理的常用网站/"/>
        <id>https://vercel.juzhong.xyz/2025/10/cloudflare代理的常用网站/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/10/cloudflare代理的常用网站/">&lt;h1 id=&quot;chang-yong-wang-zhan&quot;&gt;常用网站&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text &quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;alejandracaiccedo.com
cdn.anycast.eu.org
download.yunzhongzhuan.com
fbi.gov
gur.gov.ua
icook.hk
icook.tw
iplocation.io
ip.sb
japan.com
log.bpminecraft.com
malaysia.com
russia.com
shopify.com
singapore.com
skk.moe
time.cloudflare.com
time.is
whatismyipaddress.com
www.4chan.org
www.csgo.com
www.d-555.com
www.digitalocean.com
www.gco.gov.qa
www.glassdoor.com
www.gov.se
www.gov.ua
www.hugedomains.com
www.iakeys.com
www.ipaddress.my
www.ipchicken.com
www.ipget.net
www.iplocation.net
www.okcupid.com
www.pcmag.com
www.sean-now.com
www.shopify.com
www.udacity.com
www.udemy.com
www.visa.co.jp
www.visa.com
www.visa.com.hk
www.visa.com.sg
www.visa.com.tw
www.visakorea.com
www.whatismyip.com
www.whoer.net
www.who.int
www.wto.org
www.zsu.gov.ua
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;cloudflare-kai-fang-de-duan-kou&quot;&gt;cloudflare 开放的端口&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;http-ports-supported-by-cloudflare&quot;&gt;HTTP ports supported by Cloudflare&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;HTTP支持端口：80，8080，8880，2052，2082，2086，2095；&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;https-ports-supported-by-cloudflare&quot;&gt;HTTPS ports supported by Cloudflare&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;HTTPS支持端口：443，2053，2083，2087，2096，8443;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;ports-supported-by-cloudflare-but-with-caching-disabled&quot;&gt;Ports supported by Cloudflare, but with caching disabled&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;2052 2053 2082 2083 2086 2087 2095 2096 8880 8443&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;https:&#x2F;&#x2F;developers.cloudflare.com&#x2F;fundamentals&#x2F;reference&#x2F;network-ports&#x2F;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;cloudflare-di-zhi-fan-wei&quot;&gt;cloudflare 地址范围&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text &quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;173.245.48.0&amp;#x2F;20
103.21.244.0&amp;#x2F;22
103.22.200.0&amp;#x2F;22
103.31.4.0&amp;#x2F;22
141.101.64.0&amp;#x2F;18
108.162.192.0&amp;#x2F;18
190.93.240.0&amp;#x2F;20
188.114.96.0&amp;#x2F;20
197.234.240.0&amp;#x2F;22
198.41.128.0&amp;#x2F;17
162.158.0.0&amp;#x2F;15
104.16.0.0&amp;#x2F;13
104.24.0.0&amp;#x2F;14
172.64.0.0&amp;#x2F;13
131.0.72.0&amp;#x2F;22

2400:cb00::&amp;#x2F;32
2606:4700::&amp;#x2F;32
2803:f800::&amp;#x2F;32
2405:b500::&amp;#x2F;32
2405:8100::&amp;#x2F;32
2a06:98c0::&amp;#x2F;29
2c0f:f248::&amp;#x2F;32
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.cloudflare-cn.com&#x2F;ips&#x2F;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;blog.cmliussss.com&#x2F;p&#x2F;CloudFlare%E4%BC%98%E9%80%89&#x2F;&quot;&gt;优选域名&lt;&#x2F;a&gt;
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.cloudflare-cn.com&#x2F;ips&#x2F;&quot;&gt;cloudflare-ips&lt;&#x2F;a&gt;
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;XIU2&#x2F;CloudflareSpeedTest&quot;&gt;cloudflare-speedtest&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>clash verge 与 233boy sing-box 配合使用</title>
        <published>2025-10-06T16:44:12+08:00</published>
        <updated>2025-10-06T16:44:12+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/10/clash verge 与 233boy sing-box 配合使用/"/>
        <id>https://vercel.juzhong.xyz/2025/10/clash verge 与 233boy sing-box 配合使用/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/10/clash verge 与 233boy sing-box 配合使用/">&lt;h1 id=&quot;sing-box-fu-wu-duan-pei-zhi&quot;&gt;sing-box 服务端配置&lt;&#x2F;h1&gt;
&lt;p&gt;在vps 上配置一个代理节点&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;bash &amp;lt;(wget -qO- -o- https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;233boy&amp;#x2F;sing-box&amp;#x2F;raw&amp;#x2F;main&amp;#x2F;install.sh)
sing-box
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;an-zhuang-clash-verge-ke-hu-duan&quot;&gt;安装clash verge 客户端&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;
wget https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;clash-verge-rev&amp;#x2F;clash-verge-rev&amp;#x2F;releases&amp;#x2F;download&amp;#x2F;v2.4.2&amp;#x2F;Clash.Verge_2.4.2_amd64.deb
sudo apt install .&amp;#x2F;Clash.Verge_2.4.2_amd64.deb
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;pei-zhi-clash-verge-tian-jia-zi-jian-jie-dian&quot;&gt;配置clash verge 添加自建节点&lt;&#x2F;h1&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;在clash的订阅页面新建一个local本地配置,文件可以置空
&lt;img src=&quot;&#x2F;images&#x2F;2025-10-06-16-52-57-clash-verge.png&quot; alt=&quot;clash verge sub&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;右击编译本地配置文件
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.clashverge.dev&#x2F;guide&#x2F;config.html&quot;&gt;配置模板&lt;&#x2F;a&gt;
&lt;img src=&quot;&#x2F;images&#x2F;2025-10-06-17-05-03-clash-verge-config.png&quot; alt=&quot;clash-config&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;右击编辑本地节点
将服务端的配置复制进来即可
复制【链接（RUL）】&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 查看服务端配置
sb info
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2025-10-06-17-09-02-vless-config.png&quot; alt=&quot;vless-config&quot; &#x2F;&gt;
&lt;img src=&quot;&#x2F;images&#x2F;2025-10-06-17-12-00-clash-proxy-node.png&quot; alt=&quot;clash-node-config&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>233boy 代理脚本使用</title>
        <published>2025-10-06T14:02:52+08:00</published>
        <updated>2025-10-06T14:02:52+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/10/learn/233boy 代理脚本使用/"/>
        <id>https://vercel.juzhong.xyz/2025/10/learn/233boy 代理脚本使用/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/10/learn/233boy 代理脚本使用/">&lt;h1 id=&quot;ming-ling-xing-guan-li-he-an-zhuang-sing-box-huo-xray&quot;&gt;命令行管理和安装sing-box 或 xray&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;bash &amp;lt;(wget -qO- -o- https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;233boy&amp;#x2F;sing-box&amp;#x2F;raw&amp;#x2F;main&amp;#x2F;install.sh)
sing-box
sb

bash &amp;lt;(wget -qO- -o- https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;233boy&amp;#x2F;xray&amp;#x2F;raw&amp;#x2F;main&amp;#x2F;install.sh)
xray
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;web-ui-mian-ban&quot;&gt;web ui 面板&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;vaxilu&amp;#x2F;x-ui.git
bash &amp;lt;(curl -Ls https:&amp;#x2F;&amp;#x2F;raw.githubusercontent.com&amp;#x2F;mhsanaei&amp;#x2F;3x-ui&amp;#x2F;master&amp;#x2F;install.sh)
x-ui   # tui config
# https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;alireza0&amp;#x2F;s-ui.git
bash &amp;lt;(curl -Ls https:&amp;#x2F;&amp;#x2F;raw.githubusercontent.com&amp;#x2F;alireza0&amp;#x2F;s-ui&amp;#x2F;master&amp;#x2F;install.sh)
s-ui
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>sing-box手动配置</title>
        <published>2025-10-05T22:28:01+08:00</published>
        <updated>2025-10-05T22:28:01+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/10/learn/sing-box手动配置/"/>
        <id>https://vercel.juzhong.xyz/2025/10/learn/sing-box手动配置/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/10/learn/sing-box手动配置/">&lt;h1 id=&quot;an-zhuang-sing-box&quot;&gt;安装sing-box&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo mkdir -p &amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;keyrings &amp;amp;&amp;amp;
   sudo curl -fsSL https:&amp;#x2F;&amp;#x2F;sing-box.app&amp;#x2F;gpg.key -o &amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;keyrings&amp;#x2F;sagernet.asc &amp;amp;&amp;amp;
   sudo chmod a+r &amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;keyrings&amp;#x2F;sagernet.asc &amp;amp;&amp;amp;
   echo &amp;#x27;
Types: deb
URIs: https:&amp;#x2F;&amp;#x2F;deb.sagernet.org&amp;#x2F;
Suites: *
Components: *
Enabled: yes
Signed-By: &amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;keyrings&amp;#x2F;sagernet.asc
&amp;#x27; | sudo tee &amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;sources.list.d&amp;#x2F;sagernet.sources &amp;amp;&amp;amp;
   sudo apt-get update &amp;amp;&amp;amp;
   sudo apt-get install sing-box # or sing-box-beta

# manual install
curl -fsSL https:&amp;#x2F;&amp;#x2F;sing-box.app&amp;#x2F;install.sh | sh
curl -fsSL https:&amp;#x2F;&amp;#x2F;sing-box.app&amp;#x2F;install.sh | sh -s -- --version &amp;lt;version&amp;gt;
# 从github下载安装
sudo mkdir -p &amp;#x2F;opt&amp;#x2F;sing-box&amp;#x2F;conf
wget https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;SagerNet&amp;#x2F;sing-box&amp;#x2F;releases&amp;#x2F;download&amp;#x2F;v1.12.9&amp;#x2F;sing-box-1.12.9-linux-amd64.tar.gz 
sudo tar xvzf sing-box-1.12.9-linux-amd64.tar.gz -C &amp;#x2F;opt&amp;#x2F;sing-box&amp;#x2F;
sudo cp &amp;#x2F;opt&amp;#x2F;sing-box&amp;#x2F;sing-box-1.12.9-linux-amd64&amp;#x2F;sing-box &amp;#x2F;opt&amp;#x2F;sing-box&amp;#x2F;sing-box

mkdir -p ~&amp;#x2F;.proxy&amp;#x2F;conf
wget https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;SagerNet&amp;#x2F;sing-box&amp;#x2F;releases&amp;#x2F;download&amp;#x2F;v1.12.9&amp;#x2F;sing-box-1.12.9-linux-amd64.tar.gz 
tar xvzf sing-box-1.12.9-linux-amd64.tar.gz -C ~&amp;#x2F;.proxy&amp;#x2F;
cp ~&amp;#x2F;.proxy&amp;#x2F;sing-box-1.12.9-linux-amd64&amp;#x2F;sing-box ~&amp;#x2F;.proxy&amp;#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;any-realityyuan-li&quot;&gt;any-reality原理&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;其实我们可以把处理需要代理的数据分成三个部分:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;ol&gt;
&lt;li&gt;最上层的第一个部分就是我们熟知的各种代理协议，比如ss、vmess、vless、trojan、socks、anytls等等&lt;&#x2F;li&gt;
&lt;li&gt;第二部分是传输方式，也就是上层经过代理协议处理的数据用什么方式传输，比如raw原始状态、ws、kcp、grpc、xhttp、httpupgrade、meek等等
我们熟悉的vmess+ws，就是将上层vmess处理后的数据通过ws传输，这层一般不对数据进行加密，要么是在第一层就通过代理协议加密了，要么是交给第三层的传输安全来处理&lt;&#x2F;li&gt;
&lt;li&gt;最底层也就是我们熟知的tls以及reality&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;pei-zhi-zu-he&quot;&gt;配置组合&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;anytls-reality.png&quot; alt=&quot;anytls-reality&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;通过这个图我们就可以实现任意协议组合任意传输，比如我可以搭建普通的vmess节点，也可以搭建ss+ws的节点，或者ss+grpc+reality&lt;&#x2F;li&gt;
&lt;li&gt;还可以将原本的协议组合打乱，比如trojan协议默认情况下就是套了tls，我们可以给她换成reality或者直接脱掉tls让她裸奔&lt;&#x2F;li&gt;
&lt;li&gt;anytls也是类似，协议默认设计成了套tls，但我们可以给他套上reality，也就变成了anyreality了&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;pei-zhi-any-reality&quot;&gt;配置any-reality&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo loginctl enable-linger peter
sudo loginctl show-user peter
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;如果您希望为所有用户启用linger，可以编辑 &#x2F;etc&#x2F;systemd&#x2F;logind.conf 文件，并将 LingerDefault 选项设置为 yes，然后重启 systemd-logind&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sheng-cheng-reality-keypair&quot;&gt;生成reality keypair&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sing-box generate reality-keypair
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;anytls-reality-server-pei-zhi&quot;&gt;anytls-reality server 配置&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo mkdir -p &amp;#x2F;opt&amp;#x2F;sing-box&amp;#x2F;conf
cat &amp;lt;&amp;lt;EOF |sudo tee &amp;#x2F;etc&amp;#x2F;systemd&amp;#x2F;system&amp;#x2F;sing-box-manual.service
[Unit]
Description=sing-box Service
Documentation=https:&amp;#x2F;&amp;#x2F;sing-box.sagernet.org&amp;#x2F;
After=network.target nss-lookup.target
[Service]
User=peter
ExecStart=&amp;#x2F;opt&amp;#x2F;sing-box&amp;#x2F;sing-box run -c &amp;#x2F;opt&amp;#x2F;sing-box&amp;#x2F;config.json -C &amp;#x2F;opt&amp;#x2F;sing-box&amp;#x2F;conf
Restart=on-failure
RestartPreventExitStatus=23
RestartSec=10s
LimitNPROC=10000
LimitNOFILE=1048576
PrivateTmp=true
ProtectSystem=full
#CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
#AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
EOF
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;json&quot; class=&quot;language-json &quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;# 后续需要添加新的outbounds可以直接添加在&amp;#x2F;opt&amp;#x2F;sing-box&amp;#x2F;conf&amp;#x2F;中， sing-box 会自动merge
# 主配置在config.json中
cat &amp;lt;&amp;lt;EOF | sudo tee &amp;#x2F;opt&amp;#x2F;sing-box&amp;#x2F;config.json 
{
    &amp;quot;inbounds&amp;quot;: [
        {
            &amp;quot;type&amp;quot;: &amp;quot;anytls&amp;quot;,
            &amp;quot;listen&amp;quot;: &amp;quot;::&amp;quot;,
            &amp;quot;listen_port&amp;quot;: 6443,
            &amp;quot;users&amp;quot;: [
                {
                    &amp;quot;name&amp;quot;: &amp;quot;user&amp;quot;,
                    &amp;quot;password&amp;quot;: &amp;quot;123456&amp;quot;
                }
            ],
            &amp;quot;padding_scheme&amp;quot;: [
                &amp;quot;stop=8&amp;quot;,
                &amp;quot;0=30-30&amp;quot;,
                &amp;quot;1=100-400&amp;quot;,
                &amp;quot;2=400-500,c,500-1000,c,500-1000,c,500-1000,c,500-1000&amp;quot;,
                &amp;quot;3=9-9,500-1000&amp;quot;,
                &amp;quot;4=500-1000&amp;quot;,
                &amp;quot;5=500-1000&amp;quot;,
                &amp;quot;6=500-1000&amp;quot;,
                &amp;quot;7=500-1000&amp;quot;
            ],
            &amp;quot;tls&amp;quot;: {
                &amp;quot;enabled&amp;quot;: true,
                &amp;quot;server_name&amp;quot;: &amp;quot;yahoo.com&amp;quot;,
                &amp;quot;reality&amp;quot;: {
                    &amp;quot;enabled&amp;quot;: true,
                    &amp;quot;handshake&amp;quot;: {
                        &amp;quot;server&amp;quot;: &amp;quot;yahoo.com&amp;quot;,
                        &amp;quot;server_port&amp;quot;: 443
                    },
                    &amp;quot;private_key&amp;quot;: &amp;quot;eO3B3EMGXrYfGOe87NkUVusaeUxtLB4vxiqjVXqb9GU&amp;quot;,
                    &amp;quot;short_id&amp;quot;: &amp;quot;0123456789abcdef&amp;quot;
                }
            }
        }
    ],
    &amp;quot;outbounds&amp;quot;: [
        {
            &amp;quot;type&amp;quot;: &amp;quot;direct&amp;quot;,
            &amp;quot;tag&amp;quot;: &amp;quot;public_key_u4v3a_-uhIXPE2RoGaNy9_W5EK5UYV_hVN4Vpei75lM&amp;quot;
        }
    ]
}
EOF
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;anytls-reality-client-pei-zhi&quot;&gt;anytls-reality client 配置&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;mkdir -p ~&amp;#x2F;.proxy&amp;#x2F;conf
cat &amp;lt;&amp;lt;EOF &amp;gt; ~&amp;#x2F;.config&amp;#x2F;systemd&amp;#x2F;user&amp;#x2F;sing-box-manual.service
[Unit]
Description=sing-box Service
Documentation=https:&amp;#x2F;&amp;#x2F;sing-box.sagernet.org&amp;#x2F;
After=network.target nss-lookup.target
[Service]
ExecStart=&amp;#x2F;home&amp;#x2F;peter&amp;#x2F;.proxy&amp;#x2F;sing-box run -c &amp;#x2F;home&amp;#x2F;peter&amp;#x2F;.proxy&amp;#x2F;config.json -C &amp;#x2F;home&amp;#x2F;peter&amp;#x2F;.proxy&amp;#x2F;conf
Restart=on-failure
RestartSec=10s
[Install]
WantedBy=default.target
EOF

systemctl --user daemon-reload
systemctl --user start sing-box-manual.service
systemctl --user show-environment
journalctl --user -ex -u sing-box-manual.service 
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;json&quot; class=&quot;language-json &quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;cat &amp;lt;&amp;lt;EOF &amp;gt; &amp;#x2F;home&amp;#x2F;peter&amp;#x2F;.proxy&amp;#x2F;conf&amp;#x2F;anytls-reality.json
{
    &amp;quot;outbounds&amp;quot;: [
        {
            &amp;quot;type&amp;quot;: &amp;quot;anytls&amp;quot;,
            &amp;quot;tag&amp;quot;: &amp;quot;anytls-out&amp;quot;,
            &amp;quot;server&amp;quot;: &amp;quot;10.32.118.200&amp;quot;,
            &amp;quot;server_port&amp;quot;: 6443,
            &amp;quot;password&amp;quot;: &amp;quot;123456&amp;quot;,
            &amp;quot;idle_session_check_interval&amp;quot;: &amp;quot;30s&amp;quot;,
            &amp;quot;idle_session_timeout&amp;quot;: &amp;quot;30s&amp;quot;,
            &amp;quot;min_idle_session&amp;quot;: 5,
            &amp;quot;tls&amp;quot;: {
                &amp;quot;enabled&amp;quot;: true,
                &amp;quot;disable_sni&amp;quot;: false,
                &amp;quot;server_name&amp;quot;: &amp;quot;yahoo.com&amp;quot;,
                &amp;quot;insecure&amp;quot;: false,
                &amp;quot;utls&amp;quot;: {
                    &amp;quot;enabled&amp;quot;: true,
                    &amp;quot;fingerprint&amp;quot;: &amp;quot;chrome&amp;quot;
                },
                &amp;quot;reality&amp;quot;: {
                    &amp;quot;enabled&amp;quot;: true,
                    &amp;quot;public_key&amp;quot;: &amp;quot;u4v3a_-uhIXPE2RoGaNy9_W5EK5UYV_hVN4Vpei75lM&amp;quot;,
                    &amp;quot;short_id&amp;quot;: &amp;quot;0123456789abcdef&amp;quot;
                }
            }
        },
        {
            &amp;quot;type&amp;quot;: &amp;quot;direct&amp;quot;,
            &amp;quot;tag&amp;quot;: &amp;quot;direct&amp;quot;
        }
    ]
}
EOF
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;基础配置&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;json&quot; class=&quot;language-json &quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;cat &amp;lt;&amp;lt;EOF &amp;gt; &amp;#x2F;home&amp;#x2F;peter&amp;#x2F;.proxy&amp;#x2F;config.json
{
  &amp;quot;log&amp;quot;: {
    &amp;quot;disabled&amp;quot;: false,
    &amp;quot;level&amp;quot;: &amp;quot;debug&amp;quot;,
    &amp;quot;output&amp;quot;: &amp;quot;&amp;quot;,
    &amp;quot;timestamp&amp;quot;: true
  },
  &amp;quot;experimental&amp;quot;: {
    &amp;quot;clash_api&amp;quot;: {
      &amp;quot;external_controller&amp;quot;: &amp;quot;127.0.0.1:10807&amp;quot;,
      &amp;quot;external_ui&amp;quot;: &amp;quot;ui&amp;quot;,
      &amp;quot;external_ui_download_url&amp;quot;: &amp;quot;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;MetaCubeX&amp;#x2F;metacubexd&amp;#x2F;archive&amp;#x2F;gh-pages.zip&amp;quot;,
      &amp;quot;external_ui_download_detour&amp;quot;: &amp;quot;vless-out&amp;quot;,
      &amp;quot;default_mode&amp;quot;: &amp;quot;rule&amp;quot;,
      &amp;quot;access_control_allow_origin&amp;quot;: [ &amp;quot;*&amp;quot; ],
      &amp;quot;access_control_allow_private_network&amp;quot;: false
    },
    &amp;quot;cache_file&amp;quot;: {
      &amp;quot;enabled&amp;quot;: true,
      &amp;quot;path&amp;quot;: &amp;quot;cache.db&amp;quot;,
      &amp;quot;cache_id&amp;quot;: &amp;quot;&amp;quot;,
      &amp;quot;store_fakeip&amp;quot;: true,
      &amp;quot;store_rdrc&amp;quot;: true,
      &amp;quot;rdrc_timeout&amp;quot;: &amp;quot;7d&amp;quot;
    }
  },
  &amp;quot;inbounds&amp;quot;: [
    {
      &amp;quot;address&amp;quot;: [&amp;quot;172.18.0.1&amp;#x2F;30&amp;quot;, &amp;quot;fdfe:dcba:9876::1&amp;#x2F;126&amp;quot;],
      &amp;quot;route_address&amp;quot;: [&amp;quot;0.0.0.0&amp;#x2F;1&amp;quot;, &amp;quot;128.0.0.0&amp;#x2F;1&amp;quot;, &amp;quot;::&amp;#x2F;1&amp;quot;, &amp;quot;8000::&amp;#x2F;1&amp;quot;],
      &amp;quot;route_exclude_address&amp;quot;: [
        &amp;quot;192.168.0.0&amp;#x2F;16&amp;quot;,
        &amp;quot;10.0.0.0&amp;#x2F;8&amp;quot;,
        &amp;quot;172.16.0.0&amp;#x2F;12&amp;quot;,
        &amp;quot;fc00::&amp;#x2F;7&amp;quot;
      ],
      &amp;quot;auto_route&amp;quot;: true,
      &amp;quot;strict_route&amp;quot;: true,
      &amp;quot;type&amp;quot;: &amp;quot;tun&amp;quot;
    },
    {
      &amp;quot;type&amp;quot;: &amp;quot;mixed&amp;quot;,
      &amp;quot;tag&amp;quot;: &amp;quot;mixed-in&amp;quot;,
      &amp;quot;listen&amp;quot;: &amp;quot;127.0.0.1&amp;quot;,
      &amp;quot;listen_port&amp;quot;: 10806,
      &amp;quot;tcp_fast_open&amp;quot;: false,
      &amp;quot;tcp_multi_path&amp;quot;: false,
      &amp;quot;udp_fragment&amp;quot;: false
    }
  ],
  &amp;quot;outbounds&amp;quot;: [
    {
      &amp;quot;type&amp;quot;: &amp;quot;vless&amp;quot;,
      &amp;quot;tag&amp;quot;: &amp;quot;vless-out&amp;quot;,
      &amp;quot;server&amp;quot;: &amp;quot;10.50.228.53&amp;quot;,
      &amp;quot;server_port&amp;quot;: 13584,
      &amp;quot;uuid&amp;quot;: &amp;quot;211d952d-cbef-4811-a3f0-xxxxxxxxxxxx&amp;quot;,
      &amp;quot;flow&amp;quot;: &amp;quot;xtls-rprx-vision&amp;quot;,
      &amp;quot;network&amp;quot;: &amp;quot;tcp&amp;quot;,
      &amp;quot;tls&amp;quot;: {
          &amp;quot;enabled&amp;quot;: true,
          &amp;quot;disable_sni&amp;quot;: false,
          &amp;quot;server_name&amp;quot;: &amp;quot;aws.amazon.com&amp;quot;,
          &amp;quot;utls&amp;quot;: {
          &amp;quot;enabled&amp;quot;: true,
          &amp;quot;fingerprint&amp;quot;: &amp;quot;chrome&amp;quot;
          },
          &amp;quot;reality&amp;quot;: {
          &amp;quot;enabled&amp;quot;: true,
          &amp;quot;public_key&amp;quot;: &amp;quot;xxxxxx-3J5ReO_EpOBSix7PYhFOzaor0r8xQtEUdjS8&amp;quot;,
          &amp;quot;short_id&amp;quot;: &amp;quot;&amp;quot;
          }
      }
    },
    {
      &amp;quot;type&amp;quot;: &amp;quot;selector&amp;quot;,
      &amp;quot;tag&amp;quot;: &amp;quot;🚀 Select&amp;quot;,
      &amp;quot;interrupt_exist_connections&amp;quot;: true,
      &amp;quot;outbounds&amp;quot;: [
        &amp;quot;vless-out&amp;quot;,
        &amp;quot;🎈 Auto&amp;quot;
      ]
    },
    {
      &amp;quot;type&amp;quot;: &amp;quot;urltest&amp;quot;,
      &amp;quot;tag&amp;quot;: &amp;quot;🎈 Auto&amp;quot;,
      &amp;quot;url&amp;quot;: &amp;quot;https:&amp;#x2F;&amp;#x2F;www.gstatic.com&amp;#x2F;generate_204&amp;quot;,
      &amp;quot;interval&amp;quot;: &amp;quot;3m&amp;quot;,
      &amp;quot;tolerance&amp;quot;: 150,
      &amp;quot;interrupt_exist_connections&amp;quot;: true,
      &amp;quot;outbounds&amp;quot;: [
        &amp;quot;vless-out&amp;quot;
      ]
    },
    {
      &amp;quot;type&amp;quot;: &amp;quot;direct&amp;quot;,
      &amp;quot;tag&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
    },
    {
      &amp;quot;type&amp;quot;: &amp;quot;selector&amp;quot;,
      &amp;quot;tag&amp;quot;: &amp;quot;🐟 Fallback&amp;quot;,
      &amp;quot;interrupt_exist_connections&amp;quot;: true,
      &amp;quot;outbounds&amp;quot;: [
        &amp;quot;🚀 Select&amp;quot;,
        &amp;quot;🎯 Direct&amp;quot;
      ]
    },
    {
      &amp;quot;type&amp;quot;: &amp;quot;selector&amp;quot;,
      &amp;quot;tag&amp;quot;: &amp;quot;GLOBAL&amp;quot;,
      &amp;quot;interrupt_exist_connections&amp;quot;: true,
      &amp;quot;outbounds&amp;quot;: [
        &amp;quot;🚀 Select&amp;quot;,
        &amp;quot;🎈 Auto&amp;quot;,
        &amp;quot;🎯 Direct&amp;quot;,
        &amp;quot;🐟 Fallback&amp;quot;
      ]
    },
  ],
  &amp;quot;route&amp;quot;: {
    &amp;quot;rules&amp;quot;: [
      {
        &amp;quot;action&amp;quot;: &amp;quot;hijack-dns&amp;quot;,
        &amp;quot;protocol&amp;quot;: &amp;quot;dns&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;clash_mode&amp;quot;: &amp;quot;direct&amp;quot;,
        &amp;quot;outbound&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;clash_mode&amp;quot;: &amp;quot;global&amp;quot;,
        &amp;quot;outbound&amp;quot;: &amp;quot;GLOBAL&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;network&amp;quot;: &amp;quot;icmp&amp;quot;,
        &amp;quot;outbound&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;reject&amp;quot;,
        &amp;quot;protocol&amp;quot;: &amp;quot;quic&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;reject&amp;quot;,
        &amp;quot;rule_set&amp;quot;: [
          &amp;quot;Category-Ads&amp;quot;
        ]
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;rule_set&amp;quot;: [
          &amp;quot;GeoSite-Private&amp;quot;
        ],
        &amp;quot;outbound&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;rule_set&amp;quot;: [
          &amp;quot;GeoSite-CN&amp;quot;
        ],
        &amp;quot;outbound&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;rule_set&amp;quot;: [
          &amp;quot;GeoIP-Private&amp;quot;
        ],
        &amp;quot;outbound&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;rule_set&amp;quot;: [
          &amp;quot;GeoIP-CN&amp;quot;
        ],
        &amp;quot;outbound&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;rule_set&amp;quot;: [
          &amp;quot;GeoLocation-!CN&amp;quot;
        ],
        &amp;quot;outbound&amp;quot;: &amp;quot;🚀 Select&amp;quot;
      }
    ],
    &amp;quot;rule_set&amp;quot;: [
      {
        &amp;quot;tag&amp;quot;: &amp;quot;Category-Ads&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;remote&amp;quot;,
        &amp;quot;url&amp;quot;: &amp;quot;https:&amp;#x2F;&amp;#x2F;testingcf.jsdelivr.net&amp;#x2F;gh&amp;#x2F;MetaCubeX&amp;#x2F;meta-rules-dat@sing&amp;#x2F;geo&amp;#x2F;geosite&amp;#x2F;category-ads-all.srs&amp;quot;,
        &amp;quot;format&amp;quot;: &amp;quot;binary&amp;quot;,
        &amp;quot;download_detour&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;tag&amp;quot;: &amp;quot;GeoIP-Private&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;remote&amp;quot;,
        &amp;quot;url&amp;quot;: &amp;quot;https:&amp;#x2F;&amp;#x2F;testingcf.jsdelivr.net&amp;#x2F;gh&amp;#x2F;MetaCubeX&amp;#x2F;meta-rules-dat@sing&amp;#x2F;geo&amp;#x2F;geoip&amp;#x2F;private.srs&amp;quot;,
        &amp;quot;format&amp;quot;: &amp;quot;binary&amp;quot;,
        &amp;quot;download_detour&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;tag&amp;quot;: &amp;quot;GeoSite-Private&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;remote&amp;quot;,
        &amp;quot;url&amp;quot;: &amp;quot;https:&amp;#x2F;&amp;#x2F;testingcf.jsdelivr.net&amp;#x2F;gh&amp;#x2F;MetaCubeX&amp;#x2F;meta-rules-dat@sing&amp;#x2F;geo&amp;#x2F;geosite&amp;#x2F;private.srs&amp;quot;,
        &amp;quot;format&amp;quot;: &amp;quot;binary&amp;quot;,
        &amp;quot;download_detour&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;tag&amp;quot;: &amp;quot;GeoIP-CN&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;remote&amp;quot;,
        &amp;quot;url&amp;quot;: &amp;quot;https:&amp;#x2F;&amp;#x2F;testingcf.jsdelivr.net&amp;#x2F;gh&amp;#x2F;MetaCubeX&amp;#x2F;meta-rules-dat@sing&amp;#x2F;geo&amp;#x2F;geoip&amp;#x2F;cn.srs&amp;quot;,
        &amp;quot;format&amp;quot;: &amp;quot;binary&amp;quot;,
        &amp;quot;download_detour&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;tag&amp;quot;: &amp;quot;GeoSite-CN&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;remote&amp;quot;,
        &amp;quot;url&amp;quot;: &amp;quot;https:&amp;#x2F;&amp;#x2F;testingcf.jsdelivr.net&amp;#x2F;gh&amp;#x2F;MetaCubeX&amp;#x2F;meta-rules-dat@sing&amp;#x2F;geo&amp;#x2F;geosite&amp;#x2F;cn.srs&amp;quot;,
        &amp;quot;format&amp;quot;: &amp;quot;binary&amp;quot;,
        &amp;quot;download_detour&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;tag&amp;quot;: &amp;quot;GeoLocation-!CN&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;remote&amp;quot;,
        &amp;quot;url&amp;quot;: &amp;quot;https:&amp;#x2F;&amp;#x2F;testingcf.jsdelivr.net&amp;#x2F;gh&amp;#x2F;MetaCubeX&amp;#x2F;meta-rules-dat@sing&amp;#x2F;geo&amp;#x2F;geosite&amp;#x2F;geolocation-!cn.srs&amp;quot;,
        &amp;quot;format&amp;quot;: &amp;quot;binary&amp;quot;,
        &amp;quot;download_detour&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      }
    ],
    &amp;quot;auto_detect_interface&amp;quot;: true,
    &amp;quot;final&amp;quot;: &amp;quot;🐟 Fallback&amp;quot;,
    &amp;quot;default_domain_resolver&amp;quot;: {
      &amp;quot;server&amp;quot;: &amp;quot;Local-DNS&amp;quot;
    }
  },
  &amp;quot;dns&amp;quot;: {
    &amp;quot;servers&amp;quot;: [
      {
        &amp;quot;tag&amp;quot;: &amp;quot;Local-DNS&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;https&amp;quot;,
        &amp;quot;domain_resolver&amp;quot;: &amp;quot;Local-DNS-Resolver&amp;quot;,
        &amp;quot;server_port&amp;quot;: 443,
        &amp;quot;server&amp;quot;: &amp;quot;223.5.5.5&amp;quot;,
        &amp;quot;path&amp;quot;: &amp;quot;&amp;#x2F;dns-query&amp;quot;
      },
      {
        &amp;quot;tag&amp;quot;: &amp;quot;Local-DNS-Resolver&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;udp&amp;quot;,
        &amp;quot;server_port&amp;quot;: 53,
        &amp;quot;server&amp;quot;: &amp;quot;223.5.5.5&amp;quot;
      },
      {
        &amp;quot;tag&amp;quot;: &amp;quot;Remote-DNS&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;tls&amp;quot;,
        &amp;quot;detour&amp;quot;: &amp;quot;🚀 Select&amp;quot;,
        &amp;quot;domain_resolver&amp;quot;: &amp;quot;Remote-DNS-Resolver&amp;quot;,
        &amp;quot;server_port&amp;quot;: 853,
        &amp;quot;server&amp;quot;: &amp;quot;8.8.8.8&amp;quot;
      },
      {
        &amp;quot;tag&amp;quot;: &amp;quot;Remote-DNS-Resolver&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;udp&amp;quot;,
        &amp;quot;detour&amp;quot;: &amp;quot;🚀 Select&amp;quot;,
        &amp;quot;server_port&amp;quot;: 53,
        &amp;quot;server&amp;quot;: &amp;quot;8.8.8.8&amp;quot;
      }
    ],
    &amp;quot;rules&amp;quot;: [
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;clash_mode&amp;quot;: &amp;quot;direct&amp;quot;,
        &amp;quot;server&amp;quot;: &amp;quot;Local-DNS&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;clash_mode&amp;quot;: &amp;quot;global&amp;quot;,
        &amp;quot;server&amp;quot;: &amp;quot;Remote-DNS&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;rule_set&amp;quot;: [
          &amp;quot;GeoSite-CN&amp;quot;
        ],
        &amp;quot;server&amp;quot;: &amp;quot;Local-DNS&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;rule_set&amp;quot;: [
          &amp;quot;GeoLocation-!CN&amp;quot;
        ],
        &amp;quot;server&amp;quot;: &amp;quot;Remote-DNS&amp;quot;
      }
    ],
    &amp;quot;disable_cache&amp;quot;: false,
    &amp;quot;disable_expire&amp;quot;: false,
    &amp;quot;independent_cache&amp;quot;: false,
    &amp;quot;final&amp;quot;: &amp;quot;Remote-DNS&amp;quot;
  }
}
EOF
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;andriod-ban-ben-shi-yong&quot;&gt;andriod 版本使用&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;json&quot; class=&quot;language-json &quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;{
  &amp;quot;log&amp;quot;: {
    &amp;quot;disabled&amp;quot;: false,
    &amp;quot;level&amp;quot;: &amp;quot;debug&amp;quot;,
    &amp;quot;output&amp;quot;: &amp;quot;&amp;quot;,
    &amp;quot;timestamp&amp;quot;: true
  },
  &amp;quot;inbounds&amp;quot;: [
    {
      &amp;quot;type&amp;quot;: &amp;quot;tun&amp;quot;,
      &amp;quot;address&amp;quot;: [&amp;quot;172.19.0.1&amp;#x2F;30&amp;quot;],
      &amp;quot;auto_route&amp;quot;: true,
      &amp;#x2F;&amp;#x2F; &amp;quot;auto_redirect&amp;quot;: true, &amp;#x2F;&amp;#x2F; On linux
      &amp;quot;strict_route&amp;quot;: true
    }
  ],
  &amp;quot;outbounds&amp;quot;: [
    {
      &amp;quot;type&amp;quot;: &amp;quot;selector&amp;quot;,
      &amp;quot;tag&amp;quot;: &amp;quot;🚀 Select&amp;quot;,
      &amp;quot;interrupt_exist_connections&amp;quot;: true,
      &amp;quot;outbounds&amp;quot;: [
        &amp;quot;vless-out&amp;quot;,
        &amp;quot;🎈 Auto&amp;quot;
      ]
    },
    {
      &amp;quot;type&amp;quot;: &amp;quot;urltest&amp;quot;,
      &amp;quot;tag&amp;quot;: &amp;quot;🎈 Auto&amp;quot;,
      &amp;quot;url&amp;quot;: &amp;quot;https:&amp;#x2F;&amp;#x2F;www.gstatic.com&amp;#x2F;generate_204&amp;quot;,
      &amp;quot;interval&amp;quot;: &amp;quot;3m&amp;quot;,
      &amp;quot;tolerance&amp;quot;: 150,
      &amp;quot;interrupt_exist_connections&amp;quot;: true,
      &amp;quot;outbounds&amp;quot;: [
        &amp;quot;vless-out&amp;quot;
      ]
    },
    {
      &amp;quot;type&amp;quot;: &amp;quot;direct&amp;quot;,
      &amp;quot;tag&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
    },
    {
      &amp;quot;type&amp;quot;: &amp;quot;selector&amp;quot;,
      &amp;quot;tag&amp;quot;: &amp;quot;🐟 Fallback&amp;quot;,
      &amp;quot;interrupt_exist_connections&amp;quot;: true,
      &amp;quot;outbounds&amp;quot;: [
        &amp;quot;🚀 Select&amp;quot;,
        &amp;quot;🎯 Direct&amp;quot;
      ]
    },
    {
      &amp;quot;type&amp;quot;: &amp;quot;selector&amp;quot;,
      &amp;quot;tag&amp;quot;: &amp;quot;GLOBAL&amp;quot;,
      &amp;quot;interrupt_exist_connections&amp;quot;: true,
      &amp;quot;outbounds&amp;quot;: [
        &amp;quot;🚀 Select&amp;quot;,
        &amp;quot;🎈 Auto&amp;quot;,
        &amp;quot;🎯 Direct&amp;quot;,
        &amp;quot;🐟 Fallback&amp;quot;
      ]
    },
    {
      &amp;quot;type&amp;quot;: &amp;quot;vless&amp;quot;,
      &amp;quot;tag&amp;quot;: &amp;quot;vless-out&amp;quot;,
      &amp;quot;server&amp;quot;: &amp;quot;10.50.228.53&amp;quot;,
      &amp;quot;server_port&amp;quot;: 13584,
      &amp;quot;uuid&amp;quot;: &amp;quot;211d952d-cbef-4811-a3f0-xxxxxxxxxxxx&amp;quot;,
      &amp;quot;flow&amp;quot;: &amp;quot;xtls-rprx-vision&amp;quot;,
      &amp;quot;network&amp;quot;: &amp;quot;tcp&amp;quot;,
      &amp;quot;tls&amp;quot;: {
        &amp;quot;enabled&amp;quot;: true,
        &amp;quot;disable_sni&amp;quot;: false,
        &amp;quot;server_name&amp;quot;: &amp;quot;aws.amazon.com&amp;quot;,
        &amp;quot;utls&amp;quot;: {
          &amp;quot;enabled&amp;quot;: true,
          &amp;quot;fingerprint&amp;quot;: &amp;quot;chrome&amp;quot;
        },
        &amp;quot;reality&amp;quot;: {
          &amp;quot;enabled&amp;quot;: true,
          &amp;quot;public_key&amp;quot;: &amp;quot;Uqr4g5-3J5ReO_EpOBSix7PYhxxxxxxxxxxxxxxxxxx&amp;quot;,
          &amp;quot;short_id&amp;quot;: &amp;quot;&amp;quot;
        }
      }
    }
  ],
  &amp;quot;route&amp;quot;: {
    &amp;quot;rules&amp;quot;: [
      {
        &amp;quot;action&amp;quot;: &amp;quot;hijack-dns&amp;quot;,
        &amp;quot;protocol&amp;quot;: &amp;quot;dns&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;clash_mode&amp;quot;: &amp;quot;direct&amp;quot;,
        &amp;quot;outbound&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;clash_mode&amp;quot;: &amp;quot;global&amp;quot;,
        &amp;quot;outbound&amp;quot;: &amp;quot;GLOBAL&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;network&amp;quot;: &amp;quot;icmp&amp;quot;,
        &amp;quot;outbound&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;reject&amp;quot;,
        &amp;quot;protocol&amp;quot;: &amp;quot;quic&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;reject&amp;quot;,
        &amp;quot;rule_set&amp;quot;: [
          &amp;quot;Category-Ads&amp;quot;
        ]
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;rule_set&amp;quot;: [
          &amp;quot;GeoSite-Private&amp;quot;
        ],
        &amp;quot;outbound&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;rule_set&amp;quot;: [
          &amp;quot;GeoSite-CN&amp;quot;
        ],
        &amp;quot;outbound&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;rule_set&amp;quot;: [
          &amp;quot;GeoIP-Private&amp;quot;
        ],
        &amp;quot;outbound&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;rule_set&amp;quot;: [
          &amp;quot;GeoIP-CN&amp;quot;
        ],
        &amp;quot;outbound&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;rule_set&amp;quot;: [
          &amp;quot;GeoLocation-!CN&amp;quot;
        ],
        &amp;quot;outbound&amp;quot;: &amp;quot;🚀 Select&amp;quot;
      }
    ],
    &amp;quot;rule_set&amp;quot;: [
      {
        &amp;quot;tag&amp;quot;: &amp;quot;Category-Ads&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;remote&amp;quot;,
        &amp;quot;url&amp;quot;: &amp;quot;https:&amp;#x2F;&amp;#x2F;testingcf.jsdelivr.net&amp;#x2F;gh&amp;#x2F;MetaCubeX&amp;#x2F;meta-rules-dat@sing&amp;#x2F;geo&amp;#x2F;geosite&amp;#x2F;category-ads-all.srs&amp;quot;,
        &amp;quot;format&amp;quot;: &amp;quot;binary&amp;quot;,
        &amp;quot;download_detour&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;tag&amp;quot;: &amp;quot;GeoIP-Private&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;remote&amp;quot;,
        &amp;quot;url&amp;quot;: &amp;quot;https:&amp;#x2F;&amp;#x2F;testingcf.jsdelivr.net&amp;#x2F;gh&amp;#x2F;MetaCubeX&amp;#x2F;meta-rules-dat@sing&amp;#x2F;geo&amp;#x2F;geoip&amp;#x2F;private.srs&amp;quot;,
        &amp;quot;format&amp;quot;: &amp;quot;binary&amp;quot;,
        &amp;quot;download_detour&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;tag&amp;quot;: &amp;quot;GeoSite-Private&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;remote&amp;quot;,
        &amp;quot;url&amp;quot;: &amp;quot;https:&amp;#x2F;&amp;#x2F;testingcf.jsdelivr.net&amp;#x2F;gh&amp;#x2F;MetaCubeX&amp;#x2F;meta-rules-dat@sing&amp;#x2F;geo&amp;#x2F;geosite&amp;#x2F;private.srs&amp;quot;,
        &amp;quot;format&amp;quot;: &amp;quot;binary&amp;quot;,
        &amp;quot;download_detour&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;tag&amp;quot;: &amp;quot;GeoIP-CN&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;remote&amp;quot;,
        &amp;quot;url&amp;quot;: &amp;quot;https:&amp;#x2F;&amp;#x2F;testingcf.jsdelivr.net&amp;#x2F;gh&amp;#x2F;MetaCubeX&amp;#x2F;meta-rules-dat@sing&amp;#x2F;geo&amp;#x2F;geoip&amp;#x2F;cn.srs&amp;quot;,
        &amp;quot;format&amp;quot;: &amp;quot;binary&amp;quot;,
        &amp;quot;download_detour&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;tag&amp;quot;: &amp;quot;GeoSite-CN&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;remote&amp;quot;,
        &amp;quot;url&amp;quot;: &amp;quot;https:&amp;#x2F;&amp;#x2F;testingcf.jsdelivr.net&amp;#x2F;gh&amp;#x2F;MetaCubeX&amp;#x2F;meta-rules-dat@sing&amp;#x2F;geo&amp;#x2F;geosite&amp;#x2F;cn.srs&amp;quot;,
        &amp;quot;format&amp;quot;: &amp;quot;binary&amp;quot;,
        &amp;quot;download_detour&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      },
      {
        &amp;quot;tag&amp;quot;: &amp;quot;GeoLocation-!CN&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;remote&amp;quot;,
        &amp;quot;url&amp;quot;: &amp;quot;https:&amp;#x2F;&amp;#x2F;testingcf.jsdelivr.net&amp;#x2F;gh&amp;#x2F;MetaCubeX&amp;#x2F;meta-rules-dat@sing&amp;#x2F;geo&amp;#x2F;geosite&amp;#x2F;geolocation-!cn.srs&amp;quot;,
        &amp;quot;format&amp;quot;: &amp;quot;binary&amp;quot;,
        &amp;quot;download_detour&amp;quot;: &amp;quot;🎯 Direct&amp;quot;
      }
    ],
    &amp;quot;auto_detect_interface&amp;quot;: true,
    &amp;quot;final&amp;quot;: &amp;quot;🐟 Fallback&amp;quot;,
    &amp;quot;default_domain_resolver&amp;quot;: {
      &amp;quot;server&amp;quot;: &amp;quot;Local-DNS&amp;quot;
    }
  },
  &amp;quot;dns&amp;quot;: {
    &amp;quot;servers&amp;quot;: [
      {
        &amp;quot;tag&amp;quot;: &amp;quot;Local-DNS&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;https&amp;quot;,
        &amp;quot;domain_resolver&amp;quot;: &amp;quot;Local-DNS-Resolver&amp;quot;,
        &amp;quot;server_port&amp;quot;: 443,
        &amp;quot;server&amp;quot;: &amp;quot;223.5.5.5&amp;quot;,
        &amp;quot;path&amp;quot;: &amp;quot;&amp;#x2F;dns-query&amp;quot;
      },
      {
        &amp;quot;tag&amp;quot;: &amp;quot;Local-DNS-Resolver&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;udp&amp;quot;,
        &amp;quot;server_port&amp;quot;: 53,
        &amp;quot;server&amp;quot;: &amp;quot;223.5.5.5&amp;quot;
      },
      {
        &amp;quot;tag&amp;quot;: &amp;quot;Remote-DNS&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;tls&amp;quot;,
        &amp;quot;detour&amp;quot;: &amp;quot;🚀 Select&amp;quot;,
        &amp;quot;domain_resolver&amp;quot;: &amp;quot;Remote-DNS-Resolver&amp;quot;,
        &amp;quot;server_port&amp;quot;: 853,
        &amp;quot;server&amp;quot;: &amp;quot;8.8.8.8&amp;quot;
      },
      {
        &amp;quot;tag&amp;quot;: &amp;quot;Remote-DNS-Resolver&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;udp&amp;quot;,
        &amp;quot;detour&amp;quot;: &amp;quot;🚀 Select&amp;quot;,
        &amp;quot;server_port&amp;quot;: 53,
        &amp;quot;server&amp;quot;: &amp;quot;8.8.8.8&amp;quot;
      }
    ],
    &amp;quot;rules&amp;quot;: [
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;clash_mode&amp;quot;: &amp;quot;direct&amp;quot;,
        &amp;quot;server&amp;quot;: &amp;quot;Local-DNS&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;clash_mode&amp;quot;: &amp;quot;global&amp;quot;,
        &amp;quot;server&amp;quot;: &amp;quot;Remote-DNS&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;rule_set&amp;quot;: [
          &amp;quot;GeoSite-CN&amp;quot;
        ],
        &amp;quot;server&amp;quot;: &amp;quot;Local-DNS&amp;quot;
      },
      {
        &amp;quot;action&amp;quot;: &amp;quot;route&amp;quot;,
        &amp;quot;rule_set&amp;quot;: [
          &amp;quot;GeoLocation-!CN&amp;quot;
        ],
        &amp;quot;server&amp;quot;: &amp;quot;Remote-DNS&amp;quot;
      }
    ],
    &amp;quot;disable_cache&amp;quot;: false,
    &amp;quot;disable_expire&amp;quot;: false,
    &amp;quot;independent_cache&amp;quot;: false,
    &amp;quot;final&amp;quot;: &amp;quot;Remote-DNS&amp;quot;
  }
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>pve kernel切换debian kernel</title>
        <published>2025-10-05T14:54:48+08:00</published>
        <updated>2025-10-05T14:54:48+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/10/pve kernel切换debian kernel/"/>
        <id>https://vercel.juzhong.xyz/2025/10/pve kernel切换debian kernel/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/10/pve kernel切换debian kernel/">&lt;h1 id=&quot;pve-shi-yong-de-shi-pve-kernel-ta-ji-yu-debian-de-linux-image-dan-e-wai-bao-han&quot;&gt;PVE 使用的是 pve-kernel，它基于 Debian 的 linux-image，但额外包含：&lt;&#x2F;h1&gt;
&lt;p&gt;pve kernel 和普通的debian内核比较做了部分特殊优化：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;ZFS on Linux 官方支持（关键！）&lt;&#x2F;li&gt;
&lt;li&gt;PVE 官方内核预编译了 ZFS 模块&lt;&#x2F;li&gt;
&lt;li&gt;与 zfsutils-linux 包完美兼容&lt;&#x2F;li&gt;
&lt;li&gt;Ceph&#x2F;RBD 优化&lt;&#x2F;li&gt;
&lt;li&gt;KVM&#x2F;QEMU 虚拟化相关补丁&lt;&#x2F;li&gt;
&lt;li&gt;长期稳定 + 安全更新由 Proxmox 团队维护&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;如果不使用这些特性可以切换为正常的debian内核&lt;&#x2F;p&gt;
&lt;h1 id=&quot;qie-huan-debianpu-tong-nei-he&quot;&gt;切换debian普通内核&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 检查是否有 ZFS 池
zpool status
# 检查根文件系统是否在 ZFS 上
df &amp;#x2F; 
# 如果显示类似 zfs 或 rpool&amp;#x2F;ROOT，说明根在 ZFS 上 → ❌ 不要继续！
# 检查 PVE 存储配置
pvesm status
# 确保所有存储类型是 ext4、lvm、nfs、ceph 等，**不是 zfspool 或 zfs**

# 安装普通内核
apt install linux-image-amd64 linux-headers-amd64
# 更新 grub（确保新内核在启动项中）
update-grub
# 安装固件包: 这个安装时失败了， 说让彻底删除pve， 先不安装了
apt install firmware-linux firmware-realtek firmware-intel-sound
# 查看已安装的内核
dpkg -l | grep linux-image
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;pei-zhi-grub-qi-dong-debiannei-he&quot;&gt;配置grub 启动debian内核&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo grep -En &amp;quot;\b(menuentry|submenu)\b&amp;quot; &amp;#x2F;boot&amp;#x2F;grub&amp;#x2F;grub.cfg
# 设置永久默认项（通过编号）
sudo grub-set-default 0
# 验证设置
sudo grub-editenv list
# Debian&amp;#x2F;Ubuntu 图形化配置
sudo apt install grub-customizer
# 然后运行：grub-customizer

# GRUB 2.00+ 版本将不同内核版本放入了 &amp;quot;Advanced options&amp;quot; 子菜单中，所以完整的菜单路径:
sudo grub-reboot &amp;quot;Advanced options for Proxmox VE GNU&amp;#x2F;Linux&amp;gt;Proxmox VE GNU&amp;#x2F;Linux, with Linux 6.1.0-40-amd64&amp;quot;
# 已切换到 Debian 内核且不用 ZFS，可以禁用这个无用的脚本避免未来干扰
sudo mv &amp;#x2F;etc&amp;#x2F;kernel&amp;#x2F;postinst.d&amp;#x2F;zz-proxmox-boot &amp;#x2F;etc&amp;#x2F;kernel&amp;#x2F;postinst.d&amp;#x2F;zz-proxmox-boot.disabled
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;xiu-fu-qie-huan-nei-he-hou-xu-ni-ji-wang-luo-shi-xiao&quot;&gt;修复切换内核后虚拟机网络失效&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;lsmod | grep virtio
modprobe virtio-net
update-initramfs -u -k $(uname -r)

echo virtio-net | sudo tee -a &amp;#x2F;etc&amp;#x2F;modules-load.d&amp;#x2F;virtio.conf
echo virtio-blk | sudo tee -a &amp;#x2F;etc&amp;#x2F;modules-load.d&amp;#x2F;virtio.conf

# 显卡固件
wget https:&amp;#x2F;&amp;#x2F;git.kernel.org&amp;#x2F;pub&amp;#x2F;scm&amp;#x2F;linux&amp;#x2F;kernel&amp;#x2F;git&amp;#x2F;firmware&amp;#x2F;linux-firmware.git&amp;#x2F;plain&amp;#x2F;i915&amp;#x2F;dg2_dmc_ver2_07.bin
sudo mkdir -p &amp;#x2F;lib&amp;#x2F;firmware&amp;#x2F;i915&amp;#x2F;
sudo cp dg2_dmc_ver2_07.bin &amp;#x2F;lib&amp;#x2F;firmware&amp;#x2F;i915&amp;#x2F;
sudo update-initramfs -u -k $(uname -r)

cat &amp;#x2F;etc&amp;#x2F;network&amp;#x2F;interfaces
cat &amp;#x2F;etc&amp;#x2F;pve&amp;#x2F;qemu-server&amp;#x2F;100.conf

iptables -L -n  # 检查是否有阻止流量的规则
ip route        # 检查默认路由是否正确o

# 如果策略是 DROP，需要放行桥接流量
sudo iptables -I FORWARD -i vmbr0 -s 192.168.2.0&amp;#x2F;24 -j ACCEPT
sudo iptables -I FORWARD -o vmbr0 -d 192.168.2.0&amp;#x2F;24 -j ACCEPT
systemctl enable netfilter-persistent
netfilter-persistent save
# sudo apt install iptables-persistent
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>waydroid 安装</title>
        <published>2025-10-03T22:00:34+08:00</published>
        <updated>2025-10-03T22:00:34+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/10/waydroid 安装/"/>
        <id>https://vercel.juzhong.xyz/2025/10/waydroid 安装/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/10/waydroid 安装/">&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt install curl ca-certificates -y
curl -s https:&amp;#x2F;&amp;#x2F;repo.waydro.id | sudo bash
sudo apt install waydroid -y
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.waydro.id&#x2F;usage&#x2F;install-on-desktops&quot;&gt;waydro.id&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>linux 安全认证框架</title>
        <published>2025-10-02T20:23:46+08:00</published>
        <updated>2025-10-02T20:23:46+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/10/linux 安全认证框架/"/>
        <id>https://vercel.juzhong.xyz/2025/10/linux 安全认证框架/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/10/linux 安全认证框架/">&lt;ul&gt;
&lt;li&gt;NSS &#x2F; SSSD &#x2F; systemd-homed → 负责用户 身份信息来源与存储&lt;&#x2F;li&gt;
&lt;li&gt;PAM → 负责 认证（确认身份）&lt;&#x2F;li&gt;
&lt;li&gt;Polkit → 负责 授权（能不能做某件事，需要不要再认证）&lt;&#x2F;li&gt;
&lt;li&gt;SELinux &#x2F; AppArmor → 负责 强制控制（内核级别，防止越权访问）&lt;&#x2F;li&gt;
&lt;li&gt;LSM &#x2F; seccomp &#x2F; capabilities &#x2F; namespaces → 提供内核安全机制&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>systemd服务配置ssh反向端口转发</title>
        <published>2025-09-30T17:12:55+08:00</published>
        <updated>2025-09-30T17:12:55+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/09/systemd服务配置ssh反向端口转发/"/>
        <id>https://vercel.juzhong.xyz/2025/09/systemd服务配置ssh反向端口转发/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/09/systemd服务配置ssh反向端口转发/">&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# sudo systemctl daemon-reexec
sudo systemctl daemon-reload
sudo systemctl enable --now ssh-reverse-tunnel.service
sudo systemctl start ssh-reverse-tunnel.service
sudo useradd -M -s &amp;#x2F;bin&amp;#x2F;bash ssh-tunnel
sudo mkdir -p &amp;#x2F;home&amp;#x2F;ssh-tunnel&amp;#x2F;.ssh
sudo chmod -R 700 &amp;#x2F;home&amp;#x2F;ssh-tunnel&amp;#x2F;
sudo cp &amp;#x2F;home&amp;#x2F;peter&amp;#x2F;.ssh&amp;#x2F;id_rsa &amp;#x2F;home&amp;#x2F;ssh-tunnel&amp;#x2F;.ssh&amp;#x2F;id_rsa
sudo chmod 600 &amp;#x2F;home&amp;#x2F;ssh-tunnel&amp;#x2F;.ssh&amp;#x2F;id_rsa
sudo chown -R ssh-tunnel:ssh-tunnel &amp;#x2F;home&amp;#x2F;ssh-tunnel

ssh-keyscan aliyun.mydomain.com | sort -u - ~&amp;#x2F;.ssh&amp;#x2F;known_hosts &amp;gt; ~&amp;#x2F;.ssh&amp;#x2F;known_hosts.new
# mv ~&amp;#x2F;.ssh&amp;#x2F;known_hosts.new ~&amp;#x2F;.ssh&amp;#x2F;known_hosts
sudo chsh -s &amp;#x2F;sbin&amp;#x2F;nologin ssh-tunnel
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;cat &amp;lt;&amp;lt;EOF | sudo tee &amp;#x2F;etc&amp;#x2F;systemd&amp;#x2F;system&amp;#x2F;ssh-reverse-tunnel.service
[Unit]
Description=SSH Reverse Tunnel to Aliyun
After=network.target

[Service]
# User 变量影响id_rsa密钥的选择：~&amp;#x2F;.ssh&amp;#x2F;id_rsa 和用户有关
User=ssh-tunnel
ExecStart=&amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;autossh -M 0 -N -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -o ExitOnForwardFailure=yes -R 6022:localhost:22 -i &amp;#x2F;home&amp;#x2F;ssh-tunnel&amp;#x2F;.ssh&amp;#x2F;id_rsa root@aliyun.mydomain.com
Restart=always
RestartSec=10
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=autossh-tunnel

[Install]
WantedBy=multi-user.target
EOF
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>gdb如何在函数返回处下断点</title>
        <published>2025-09-29T20:46:39+08:00</published>
        <updated>2025-09-29T20:46:39+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/09/如何在函数返回处下断点/"/>
        <id>https://vercel.juzhong.xyz/2025/09/如何在函数返回处下断点/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/09/如何在函数返回处下断点/">&lt;h1 id=&quot;shi-yong-finishming-ling&quot;&gt;使用finish命令&lt;&#x2F;h1&gt;
&lt;p&gt;先进入目标函数内部（通过step命令），然后执行finish命令，程序会运行至当前函数返回前暂停。该方法适用于已进入函数内部的情况&lt;&#x2F;p&gt;
&lt;h1 id=&quot;shi-yong-until-ming-ling&quot;&gt;使用 until 命令&lt;&#x2F;h1&gt;
&lt;p&gt;until 命令会让程序运行到当前行之后的某一行或当前循环体之外。&lt;&#x2F;p&gt;
&lt;p&gt;如果你在函数的某一行，想让它运行到函数末尾（假设末尾是 }），可以：
gdb
编辑
(gdb) until
或者指定大括号所在的行号：
gdb
编辑
(gdb) until 90  # 假设 } 在第90行&lt;&#x2F;p&gt;
&lt;h1 id=&quot;cheng-xu-qi-dong-hou-zhi-jie-zan-ting&quot;&gt;程序启动后直接暂停&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;use std::env;
use std::process;
use std::ffi::CString;

fn wait_for_gdb() {
    unsafe {
        &amp;#x2F;&amp;#x2F; 打印 PID，方便 attach
        let pid = libc::getpid();
        println!(&amp;quot;PID: {} waiting for gdb...&amp;quot;, pid);

        &amp;#x2F;&amp;#x2F; 主动给自己发 SIGSTOP
        libc::raise(libc::SIGSTOP);
    }
}

fn main() {
    &amp;#x2F;&amp;#x2F; 可选：通过环境变量控制，只有在需要调试时才挂起
    if env::var(&amp;quot;WAIT_GDB&amp;quot;).is_ok() {
        wait_for_gdb();
    }

    println!(&amp;quot;Program resumed!&amp;quot;);
    &amp;#x2F;&amp;#x2F; 你的正常逻辑
    for i in 0..5 {
        println!(&amp;quot;i = {}&amp;quot;, i);
        std::thread::sleep(std::time::Duration::from_secs(1));
    }
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;shi-yong-gdb-record-cha-kan-tui-chu-yuan-yin&quot;&gt;使用gdb record 查看退出原因&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 1. 启动 GDB
gdb target&amp;#x2F;debug&amp;#x2F;your_program

# 2. 设置环境变量（可选但推荐）
(gdb) set environment RUST_BACKTRACE=1
(gdb) set environment RUST_LOG=debug  # 如果使用日志
# 如果程序运行时间很长，设置缓冲区大小
(gdb) set record full stop-at-limit on
(gdb) set record full insn-number-max 1000000
# 3. 开始录制
(gdb) record
# 4. 运行程序
(gdb) run

# 查看程序是如何退出的
(gdb) info program
# 查看最后的信号信息
(gdb) info signals
# 查看当前堆栈
(gdb) bt
# 查看退出前的最后几个函数调用
(gdb) reverse-finish
(gdb) reverse-finish
(gdb) reverse-finish
# 或者逐步回退
(gdb) reverse-step
(gdb) reverse-step
# 查看寄存器状态（可能显示段错误原因）
(gdb) info registers
# 查看内存映射
(gdb) info proc mappings
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;rust-cheng-xu-diao-shi&quot;&gt;rust 程序调试&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 安装 rust-gdb（如果可用）
rust-gdb target&amp;#x2F;debug&amp;#x2F;your_program
# 或者在普通 gdb 中设置
(gdb) break core::panicking::panic
(gdb) break std::sys_common::backtrace::__rust_end_short_backtrace
(gdb) break std::process::exit
# 查看字符串内容（Rust 的 String 和 &amp;amp;str）
(gdb) print your_string_variable
# 查看 Vec 内容
(gdb) print *your_vec_pointer@your_vec_pointer.len
# 查看 Option&amp;#x2F;Result
(gdb) print your_option.Some
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;shi-yong-rr-gong-ju-hui-fang-tui-jian-ti-dai-fang-an&quot;&gt;使用 rr 工具回放（推荐替代方案）&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 安装 rr (Ubuntu&amp;#x2F;Debian)
sudo apt install rr
# 录制程序执行
rr record target&amp;#x2F;debug&amp;#x2F;your_program
# 回放并调试
rr replay
# 在 replay 模式下，可以使用所有 reverse debugging 命令
(rr) reverse-continue
(rr) reverse-step
(rr) bt
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>knock端口敲门</title>
        <published>2025-09-29T17:23:02+08:00</published>
        <updated>2025-09-29T17:23:02+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/09/knock端口敲门/"/>
        <id>https://vercel.juzhong.xyz/2025/09/knock端口敲门/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/09/knock端口敲门/">&lt;h1 id=&quot;knockfu-wu&quot;&gt;Knock服务&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;即端口敲门（Port Knocking），是一种利用一系列预设的端口序列来“敲门”，从而动态地打开防火墙上的目标服务端口以实现访问控制的安全技术。&lt;&#x2F;li&gt;
&lt;li&gt;其核心原理是服务器上的端口默认是隐藏的，只有客户端按照事先约定好的顺序依次尝试访问一系列“秘密”的端口，服务器端的knockd服务才会识别出这个“暗号”，并暂时打开关键服务端口（如SSH的22端口），允许合法用户连接。&lt;&#x2F;li&gt;
&lt;li&gt;当服务使用完毕后，服务器会停止开放端口，进一步提升了系统的安全性，降低了被端口扫描和暴力破解的风险。﻿&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;an-zhuang&quot;&gt;安装&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;apt install knockd
echo &amp;lt;&amp;lt;EOF &amp;gt; &amp;#x2F;etc&amp;#x2F;knockd.conf
[options]
        # UseSyslog
        Interface = eth0
        LogFile = &amp;#x2F;var&amp;#x2F;log&amp;#x2F;knockd.log
[openSSH]
        # sequence    = 1357:tcp, 1234:tcp, 6789:tcp
        sequence    = 1357, 1234, 6789
        seq_timeout = 20
        command     = &amp;#x2F;sbin&amp;#x2F;iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
        tcpflags    = syn
        # start_command = &amp;#x2F;sbin&amp;#x2F;iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
        # cmd_timeout = 60
        # stop_command = &amp;#x2F;sbin&amp;#x2F;iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
[closeSSH]
        sequence    = 6789, 1234, 1357
        seq_timeout = 5
        command     = &amp;#x2F;sbin&amp;#x2F;iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
        tcpflags    = syn
&amp;lt;&amp;lt;EOF
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;ce-shi&quot;&gt;测试&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;nmap -A -p 22 192.168.7.7 -oA output
# 开门
knock -v 192.168.7.7 1356 1234 6789
nmap -A -p 22 192.168.7.7 -oA output
iptalbes -nvL | grep 22
# 关门
knock -v 192.168.7.7 6789 1234 1357

# 破解端口敲门序列
target=192.168.7.7
# 查看开放的端口
nmap -p- 192.168.7.7
nmap -p- -sU 192.168.7.7
# 分别向12001-12005端口都发送设置了 FIN&amp;#x2F;URG&amp;#x2F;RST&amp;#x2F;SYN 标志的 TCP 数据包
for port in 12001 12002 12003 12004 12005; do
        for flag in F U R S; do
                hping3 -c 5 -$flag -p $port $target
        done
done
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;gong-zuo-yuan-li&quot;&gt;工作原理&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;预设序列：管理员定义一个端口序列（例如，7000, 8000, 9000）作为“敲门暗号”。﻿&lt;&#x2F;li&gt;
&lt;li&gt;客户端“敲门”：客户端按照约定的顺序，依次向服务器的这些端口发送连接请求。﻿&lt;&#x2F;li&gt;
&lt;li&gt;服务器监听与识别：服务器上的knockd守护进程会监听这些端口的访问，并验证收到的端口序列是否与预设的匹配。﻿&lt;&#x2F;li&gt;
&lt;li&gt;动态开启服务：如果敲门序列正确，knockd服务会动态修改防火墙（如iptables）规则，临时开放预期的目标服务端口（如SSH的22端口），允许客户端进行连接。﻿&lt;&#x2F;li&gt;
&lt;li&gt;定时关闭：服务端口开放一段时间后，敲门服务会自动关闭该端口，恢复初始的防火墙规则，继续隐藏服务。﻿&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;zhu-yao-you-dian&quot;&gt;主要优点&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;提高安全性：通过隐藏服务端口，有效防止了未经授权的端口扫描和暴力破解攻击。﻿&lt;&#x2F;li&gt;
&lt;li&gt;降低攻击面：重要的服务端口不直接暴露在外，减少了潜在的攻击点。﻿&lt;&#x2F;li&gt;
&lt;li&gt;动态访问控制：允许在需要时进行访问，而不是一直开放服务端口，更安全。﻿&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;ying-yong-chang-jing&quot;&gt;应用场景&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;隐藏SSH服务：防止SSH服务被频繁扫描，保护服务器免受暴力破解攻击。﻿&lt;&#x2F;li&gt;
&lt;li&gt;保护其他敏感服务：用于对公共网络开放的其他重要服务，如数据库端口等。﻿&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>ubuntu docker 安装</title>
        <published>2025-09-28T16:03:40+08:00</published>
        <updated>2025-09-28T16:03:40+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/09/ubuntu docker 安装/"/>
        <id>https://vercel.juzhong.xyz/2025/09/ubuntu docker 安装/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/09/ubuntu docker 安装/">&lt;p&gt;安装依赖包&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;添加docker GPG密钥&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;curl -fsSL https:&amp;#x2F;&amp;#x2F;mirrors.ustc.edu.cn&amp;#x2F;docker-ce&amp;#x2F;linux&amp;#x2F;ubuntu&amp;#x2F;gpg | sudo tee &amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;keyrings&amp;#x2F;docker.asc
echo \
  &amp;quot;deb [arch=$(dpkg --print-architecture) signed-by=&amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;keyrings&amp;#x2F;docker.asc] https:&amp;#x2F;&amp;#x2F;mirrors.ustc.edu.cn&amp;#x2F;docker-ce&amp;#x2F;linux&amp;#x2F;ubuntu&amp;#x2F; \
 $(. &amp;#x2F;etc&amp;#x2F;os-release &amp;amp;&amp;amp; echo &amp;quot;$VERSION_CODENAME&amp;quot;) stable&amp;quot; | \
  sudo tee &amp;#x2F;etc&amp;#x2F;apt&amp;#x2F;sources.list.d&amp;#x2F;docker.list &amp;gt; &amp;#x2F;dev&amp;#x2F;null
sudo apt-get update
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;安装社区版本docker&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt-get update
# 安装最新版本的 Docker Engine-Community 和 containerd ，或者转到下一步安装特定版本：
sudo apt-get install docker-ce docker-ce-cli containerd.io
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>ibus-rime简体输入法配置</title>
        <published>2025-09-04T19:09:32+08:00</published>
        <updated>2025-09-04T19:09:32+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/09/ibus-rime简体输入法配置/"/>
        <id>https://vercel.juzhong.xyz/2025/09/ibus-rime简体输入法配置/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/09/ibus-rime简体输入法配置/">&lt;h1 id=&quot;an-zhuang-ibus-rime&quot;&gt;安装ibus-rime&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt update
sudo apt install ibus-rime
sudo apt install rime-data-pinyin-simp
ibus restart
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;打开 系统设置 → 键盘 → 输入源&lt;&#x2F;li&gt;
&lt;li&gt;点击 添加输入源 → 搜索 Chinese (Rime) → 添加&lt;&#x2F;li&gt;
&lt;li&gt;切换输入法快捷键通常是 Super+Space 或 Ctrl+Space&lt;&#x2F;li&gt;
&lt;li&gt;此时你应该能切换到 Rime 了，默认是 朙月拼音（繁体输出）。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;pei-zhi-jian-ti-pin-yin&quot;&gt;配置简体拼音&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 快捷键Ctrl+Shift+4切换简体模式
# vim ~&amp;#x2F;.config&amp;#x2F;ibus&amp;#x2F;rime&amp;#x2F;default.custom.yaml
patch:
  schema_list:
    - schema: luna_pinyin_simp
  menu:
    page_size: 9
  # &amp;#x2F;usr&amp;#x2F;share&amp;#x2F;rime-data&amp;#x2F;default.yaml
  switcher:
    hotkeys:
      - Control+Shift+grave
      - F4
  ascii_composer&amp;#x2F;switch_key:
    Shift_L: commit_code
  key_binder&amp;#x2F;bindings:
    # 当有候选框时，Esc 关闭候选框
    - { when: has_menu, accept: Escape, send: Escape }
    # 当正在输入拼音（composing）时，Esc 清空并切出
    - { when: composing, accept: Escape, send: Escape, commit: &amp;quot;&amp;quot; }
    - { when: always, accept: Escape, toggle: ascii_mode }

# vim ~&amp;#x2F;.config&amp;#x2F;ibus&amp;#x2F;rime&amp;#x2F;ibus_rime.custom.yaml
patch:
  style:
    horizontal: true
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;bu-shu-sheng-xiao-pai-cha&quot;&gt;部署生效排查&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;修改配置后需通过系统托盘选择&quot;部署&quot;或执行ibus restart&lt;&#x2F;li&gt;
&lt;li&gt;若遇IBus未启动，可运行ibus-daemon -drx并添加至.bashrc&lt;&#x2F;li&gt;
&lt;li&gt;对于GNOME桌面用户，可安装ibus-tweaker插件优化界面显示效&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;ibus restart
rime_deployer --compile ~&amp;#x2F;.config&amp;#x2F;ibus&amp;#x2F;rime&amp;#x2F;
~&amp;#x2F;.config&amp;#x2F;ibus&amp;#x2F;rime&amp;#x2F;installer.sh --build
ibus list-engine
ibus read-cache
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;an-zhuang-kuo-zhan-ci-ku&quot;&gt;安装扩展词库&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 安装 Plum
curl -fsSL https:&amp;#x2F;&amp;#x2F;raw.githubusercontent.com&amp;#x2F;rime&amp;#x2F;plum&amp;#x2F;master&amp;#x2F;rime-install | bash
# 使用 Plum 安装扩展词库，例如雾凇拼音（参考其文档）或 emoji 支持
bash rime-install emoji
bash rime-install emoji:customize:schema=luna_pinyin_simp
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;zi-ding-yi-ci-hui-he-duan-yu&quot;&gt;自定义词汇和短语&lt;&#x2F;h1&gt;
&lt;p&gt;你可以通过编辑用户词典文件（如 luna_pinyin_simp.user.dict.yaml）来添加个人常用词条。文件格式通常如下：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# ~&amp;#x2F;.config&amp;#x2F;ibus&amp;#x2F;rime&amp;#x2F;luna_pinyin_simp.user.dict.yaml
name: luna_pinyin_simp.user
version: &amp;quot;2025.09.04&amp;quot;
sort: by_weight
use_preset_vocabulary: true
...
# 在此处添加你的自定义词条
import_tables:
  - luna_pinyin_simp
# 可以引入其他词库表
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;ling-yi-chong-jian-ti-pei-zhi&quot;&gt;另一种简体配置&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# vim luna_pinyin.custom.yaml
patch:
  switches:
    - name: ascii_mode
      reset: 0
      states: [ 中文, 西文 ]
    - name: full_shape
      reset: 0
      states: [ 半角, 全角 ]
    - name: simplification
      reset: 1        # 默认简体
      states: [ 繁體, 简体 ]

  engine&amp;#x2F;filters:
    - simplifier
    - uniquifier
# 关键是 reset: 1，这样启动时就是 简体字
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>dns泄漏检测</title>
        <published>2025-09-02T10:11:54+08:00</published>
        <updated>2025-09-02T10:11:54+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/09/dns泄漏检测/"/>
        <id>https://vercel.juzhong.xyz/2025/09/dns泄漏检测/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/09/dns泄漏检测/">&lt;h1 id=&quot;dnsxie-lu&quot;&gt;DNS泄露&lt;&#x2F;h1&gt;
&lt;p&gt;DNS泄露测试是每个关注在线隐私和安全的人必不可少的工具。当您使用 VPN服务来隐藏您的互联网活动时，确保您的DNS请求也得到保护是至关重要的。DNS泄露可能会暴露这些请求，将您访问的网站透露给您的互联网服务提供商（ISP）或任何监控您连接的窃听者。进行DNS泄露测试是一个简单的过程。通过运行DNS泄露测试，您可以确保您的在线活动不会通过DNS查询泄露出去。&lt;&#x2F;p&gt;
&lt;h1 id=&quot;jian-ce-wang-zhan&quot;&gt;检测网站&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;www.browserscan.net&#x2F;zh&#x2F;dns-leak&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;nordvpn.com&#x2F;zh-tw&#x2F;dns-leak-test&#x2F;&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;dnsleaktest.com&#x2F;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;chrome-de-dns-ji-zhi&quot;&gt;Chrome 的 DNS 机制&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;Chrome 在 &quot;系统代理&quot; 或者 &quot;手动代理&quot; 模式下，不会自己先去查 DNS，而是直接把域名字符串交给代理（SOCKS5 支持 domain 模式）。&lt;&#x2F;li&gt;
&lt;li&gt;所以域名解析是在代理端完成的，而不是在本地操作系统。&lt;&#x2F;li&gt;
&lt;li&gt;在 Linux 上，如果 Chrome 检测到使用 SOCKS5 代理，会把域名直接交给代理（默认 SOCKS5 remote DNS）。&lt;&#x2F;li&gt;
&lt;li&gt;在使用 HTTP 代理 时，也会把完整的 Host 字段交给代理，代理负责解析目标 IP。&lt;&#x2F;li&gt;
&lt;li&gt;只有在 直连 或 代理不支持域名转发 时，Chrome 才会调用 glibc 的 getaddrinfo()，触发系统 DNS 配置（&#x2F;etc&#x2F;resolv.conf, systemd-resolved 等）。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>win11 虚拟机安装</title>
        <published>2025-08-26T15:31:20+08:00</published>
        <updated>2025-08-26T15:31:20+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/08/win11 虚拟机安装/"/>
        <id>https://vercel.juzhong.xyz/2025/08/win11 虚拟机安装/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/08/win11 虚拟机安装/">&lt;h1 id=&quot;xu-ni-ji-an-zhuang&quot;&gt;虚拟机安装&lt;&#x2F;h1&gt;
&lt;p&gt;安装一个win11专业版本&lt;&#x2F;p&gt;
&lt;h1 id=&quot;zhang-hu-pei-zhi&quot;&gt;账户配置&lt;&#x2F;h1&gt;
&lt;ol&gt;
&lt;li&gt;登录foo@outlook.com账户， 可选修改在线账户密码&lt;&#x2F;li&gt;
&lt;li&gt;在设置中开启rdp(需要win11 专业版)&lt;&#x2F;li&gt;
&lt;li&gt;创建本地账户 , 并配置为administrator权限&lt;&#x2F;li&gt;
&lt;li&gt;xfreerdp &#x2F;v:192.168.122.79:3389 &#x2F;u:peter.l +clipboard &#x2F;dynamic-resolution 就可以正常远程登录了&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h1 id=&quot;pei-zhi-office&quot;&gt;配置office&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;OdysseusYuan&amp;#x2F;Mocreak
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>kitty终端快捷键</title>
        <published>2025-08-14T15:08:33+08:00</published>
        <updated>2025-08-14T15:08:33+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/08/kitty终端快捷键/"/>
        <id>https://vercel.juzhong.xyz/2025/08/kitty终端快捷键/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/08/kitty终端快捷键/">&lt;p&gt;kitty 终端模拟器有许多快捷键，主要用于导航、窗口管理、文本操作和配置等。以下是一些常用的快捷键：
基本导航:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Ctrl+Shift+Enter: 新建标签页﻿&lt;&#x2F;li&gt;
&lt;li&gt;Ctrl+Shift+W: 关闭标签页﻿&lt;&#x2F;li&gt;
&lt;li&gt;Ctrl+Shift+PageUp &#x2F; Ctrl+Shift+PageDown: 切换标签页﻿&lt;&#x2F;li&gt;
&lt;li&gt;Ctrl+Shift+左箭头 &#x2F; Ctrl+Shift+右箭头: 切换窗口﻿&lt;&#x2F;li&gt;
&lt;li&gt;Ctrl+Shift+方向键: 在当前窗口中移动光标﻿&lt;&#x2F;li&gt;
&lt;li&gt;Ctrl+Shift+T: 在当前窗口中打开一个新的标签页﻿&lt;&#x2F;li&gt;
&lt;li&gt;Ctrl+Shift+Q: 关闭当前窗口﻿&lt;&#x2F;li&gt;
&lt;li&gt;Ctrl+Shift+R: 重新加载配置文件﻿&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;文本操作:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Ctrl+Shift+C: 复制选中文本&lt;&#x2F;li&gt;
&lt;li&gt;Ctrl+Shift+V: 粘贴文本&lt;&#x2F;li&gt;
&lt;li&gt;Ctrl+Shift+X: 剪切选中文本&lt;&#x2F;li&gt;
&lt;li&gt;Ctrl+Shift+Z: 撤销&lt;&#x2F;li&gt;
&lt;li&gt;Ctrl+Shift+Y: 重做&lt;&#x2F;li&gt;
&lt;li&gt;Ctrl+Shift+方向键: 在文本中移动光标&lt;&#x2F;li&gt;
&lt;li&gt;Ctrl+Shift+PageUp &#x2F; Ctrl+Shift+PageDown: 在文本缓冲区中向上&#x2F;向下滚动﻿&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;其他快捷键:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Ctrl+Shift+F2: 编辑kitty 配置文件&lt;&#x2F;li&gt;
&lt;li&gt;Ctrl+Shift+F5: 重新加载kitty 配置文件&lt;&#x2F;li&gt;
&lt;li&gt;Ctrl+Shift+F6: 调试kitty 配置文件&lt;&#x2F;li&gt;
&lt;li&gt;Ctrl+Shift+Escape: 打开kitty 终端&lt;&#x2F;li&gt;
&lt;li&gt;Ctrl+Shift+加号 &#x2F; Ctrl+Shift+减号: 调整字体大小&lt;&#x2F;li&gt;
&lt;li&gt;Ctrl+Shift+F: 在当前窗口中查找文本﻿&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;自定义快捷键:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;可以在 kitty.conf 文件中自定义快捷键。例如，要将新建标签页的快捷键设置为 Ctrl+Alt+T，可以在 kitty.conf 中添加以下行：&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text &quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;map ctrl+alt+t launch --cwd=current
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;查找更多快捷键:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;可以在 kitty 文档 中查找更多快捷键和配置选项&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;pei-zhi-kittyzi-ti-ju-ti-ying-yong-chang-jing&quot;&gt;配置kitty字体： 具体应用场景&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt install fonts-jetbrains-mono
cat &amp;lt;&amp;lt;EOF &amp;gt;&amp;gt; ~&amp;#x2F;.config&amp;#x2F;kitty&amp;#x2F;kitty.conf
font_family JetBrains Mono
font_size 14.0
EOF
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;pei-zhi-alacrittyzi-ti-da-xiao&quot;&gt;配置alacritty字体大小&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;cat &amp;lt;&amp;lt;EOF &amp;gt;&amp;gt; ~&amp;#x2F;.config&amp;#x2F;alacritty&amp;#x2F;alacritty.toml
[font]
size = 18
EOF
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.escapelife.site&#x2F;posts&#x2F;8e342b57.html&quot;&gt;kitty&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>linux 字体高级配置</title>
        <published>2025-08-14T14:49:54+08:00</published>
        <updated>2025-08-14T14:49:54+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/08/linux 字体高级配置/"/>
        <id>https://vercel.juzhong.xyz/2025/08/linux 字体高级配置/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/08/linux 字体高级配置/">&lt;p&gt;在 Linux 系统中，字体配置主要通过 Fontconfig 库管理，这是一个跨平台的字体配置系统。以下是完整的配置文件、操作命令和最佳实践指南：&lt;&#x2F;p&gt;
&lt;h1 id=&quot;file-folder-he-xin-pei-zhi-wen-jian-jie-gou&quot;&gt;📁 核心配置文件结构&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;1-xi-tong-ji-pei-zhi&quot;&gt;1. 系统级配置&lt;&#x2F;h2&gt;
&lt;p&gt;路径	作用	修改权限&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&#x2F;etc&#x2F;fonts&#x2F;fonts.conf	主配置文件	root&lt;&#x2F;li&gt;
&lt;li&gt;&#x2F;etc&#x2F;fonts&#x2F;conf.d&#x2F;	配置片段目录（按数字顺序加载）	root&lt;&#x2F;li&gt;
&lt;li&gt;&#x2F;usr&#x2F;share&#x2F;fonts&#x2F;	系统字体安装目录	root&lt;&#x2F;li&gt;
&lt;li&gt;&#x2F;usr&#x2F;local&#x2F;share&#x2F;fonts&#x2F;	本地安装字体目录	root&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;2-yong-hu-ji-pei-zhi&quot;&gt;2. 用户级配置&lt;&#x2F;h2&gt;
&lt;p&gt;路径	作用&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;~&#x2F;.config&#x2F;fontconfig&#x2F;fonts.conf	用户主配置文件&lt;&#x2F;li&gt;
&lt;li&gt;~&#x2F;.config&#x2F;fontconfig&#x2F;conf.d&#x2F;	用户配置片段目录&lt;&#x2F;li&gt;
&lt;li&gt;~&#x2F;.local&#x2F;share&#x2F;fonts&#x2F;	用户字体目录&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;wrench-he-xin-cao-zuo-ming-ling&quot;&gt;🔧 核心操作命令&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;1-zi-ti-guan-li-ming-ling&quot;&gt;1. 字体管理命令&lt;&#x2F;h2&gt;
&lt;p&gt;命令	作用	示例&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;fc-cache	刷新字体缓存	fc-cache -fv (强制详细刷新)&lt;&#x2F;li&gt;
&lt;li&gt;fc-list	列出可用字体	fc-list : family style&lt;&#x2F;li&gt;
&lt;li&gt;fc-match	测试字体匹配	fc-match &quot;Arial&quot;&lt;&#x2F;li&gt;
&lt;li&gt;fc-query	检查字体文件属性	fc-query &#x2F;path&#x2F;to&#x2F;font.ttf&lt;&#x2F;li&gt;
&lt;li&gt;fc-scan	扫描字体文件元数据	fc-scan -v &#x2F;path&#x2F;to&#x2F;font.otf&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;2-zi-ti-an-zhuang&quot;&gt;2. 字体安装&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 系统级安装
sudo cp new_font.ttf &amp;#x2F;usr&amp;#x2F;share&amp;#x2F;fonts&amp;#x2F;truetype&amp;#x2F;
sudo fc-cache -fv
# 用户级安装
mkdir -p ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;fonts&amp;#x2F;
cp new_font.otf ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;fonts&amp;#x2F;
fc-cache -fv ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;fonts&amp;#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;gear-pei-zhi-wen-jian-xiang-jie&quot;&gt;⚙️ 配置文件详解&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;1-dian-xing-pei-zhi-wen-jian-jie-gou-xmlge-shi&quot;&gt;1. 典型配置文件结构 (XML格式)&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;xml&quot; class=&quot;language-xml &quot;&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;
&amp;lt;!DOCTYPE fontconfig SYSTEM &amp;quot;fonts.dtd&amp;quot;&amp;gt;
&amp;lt;fontconfig&amp;gt;
  &amp;lt;!-- 1. 添加字体目录 --&amp;gt;
  &amp;lt;dir&amp;gt;&amp;#x2F;usr&amp;#x2F;local&amp;#x2F;share&amp;#x2F;fonts&amp;lt;&amp;#x2F;dir&amp;gt;
  
  &amp;lt;!-- 2. 逻辑字体映射 --&amp;gt;
  &amp;lt;alias&amp;gt;
    &amp;lt;family&amp;gt;sans-serif&amp;lt;&amp;#x2F;family&amp;gt;
    &amp;lt;prefer&amp;gt;
      &amp;lt;family&amp;gt;Noto Sans&amp;lt;&amp;#x2F;family&amp;gt;
      &amp;lt;family&amp;gt;Source Han Sans SC&amp;lt;&amp;#x2F;family&amp;gt;
    &amp;lt;&amp;#x2F;prefer&amp;gt;
  &amp;lt;&amp;#x2F;alias&amp;gt;
  
  &amp;lt;!-- 3. 渲染优化 --&amp;gt;
  &amp;lt;match target=&amp;quot;font&amp;quot;&amp;gt;
    &amp;lt;edit name=&amp;quot;antialias&amp;quot; mode=&amp;quot;assign&amp;quot;&amp;gt;&amp;lt;bool&amp;gt;true&amp;lt;&amp;#x2F;bool&amp;gt;&amp;lt;&amp;#x2F;edit&amp;gt;
    &amp;lt;edit name=&amp;quot;hinting&amp;quot; mode=&amp;quot;assign&amp;quot;&amp;gt;&amp;lt;bool&amp;gt;true&amp;lt;&amp;#x2F;bool&amp;gt;&amp;lt;&amp;#x2F;edit&amp;gt;
    &amp;lt;edit name=&amp;quot;hintstyle&amp;quot; mode=&amp;quot;assign&amp;quot;&amp;gt;&amp;lt;const&amp;gt;hintslight&amp;lt;&amp;#x2F;const&amp;gt;&amp;lt;&amp;#x2F;edit&amp;gt;
    &amp;lt;edit name=&amp;quot;rgba&amp;quot; mode=&amp;quot;assign&amp;quot;&amp;gt;&amp;lt;const&amp;gt;rgb&amp;lt;&amp;#x2F;const&amp;gt;&amp;lt;&amp;#x2F;edit&amp;gt;
  &amp;lt;&amp;#x2F;match&amp;gt;
  
  &amp;lt;!-- 4. 禁用特定字体 --&amp;gt;
  &amp;lt;selectfont&amp;gt;
    &amp;lt;rejectfont&amp;gt;
      &amp;lt;pattern&amp;gt;
        &amp;lt;patelt name=&amp;quot;family&amp;quot;&amp;gt;&amp;lt;string&amp;gt;Comic Sans MS&amp;lt;&amp;#x2F;string&amp;gt;&amp;lt;&amp;#x2F;patelt&amp;gt;
      &amp;lt;&amp;#x2F;pattern&amp;gt;
    &amp;lt;&amp;#x2F;rejectfont&amp;gt;
  &amp;lt;&amp;#x2F;selectfont&amp;gt;
&amp;lt;&amp;#x2F;fontconfig&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;2-guan-jian-pei-zhi-can-shu&quot;&gt;2. 关键配置参数&lt;&#x2F;h2&gt;
&lt;p&gt;参数	值	作用&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;antialias	true&#x2F;false	启用抗锯齿&lt;&#x2F;li&gt;
&lt;li&gt;hinting	true&#x2F;false	启用字体微调&lt;&#x2F;li&gt;
&lt;li&gt;hintstyle	hintnone&#x2F;hintslight&#x2F;hintmedium&#x2F;hintfull	微调强度&lt;&#x2F;li&gt;
&lt;li&gt;rgba	none&#x2F;rgb&#x2F;bgr&#x2F;vrgb&#x2F;vbgr	子像素渲染模式&lt;&#x2F;li&gt;
&lt;li&gt;lcdfilter	lcddefault&#x2F;lcdlight&#x2F;lcdlegacy	LCD滤镜优化&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;tools-gao-ji-pei-zhi-ji-qiao&quot;&gt;🛠️ 高级配置技巧&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;1-duo-yu-yan-zi-ti-hui-tui&quot;&gt;1. 多语言字体回退&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;xml&quot; class=&quot;language-xml &quot;&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&amp;lt;!-- 中文优先使用思源黑体，英文用Roboto --&amp;gt;
&amp;lt;alias&amp;gt;
  &amp;lt;family&amp;gt;sans-serif&amp;lt;&amp;#x2F;family&amp;gt;
  &amp;lt;prefer&amp;gt;
    &amp;lt;family&amp;gt;Source Han Sans SC&amp;lt;&amp;#x2F;family&amp;gt;
    &amp;lt;family&amp;gt;Roboto&amp;lt;&amp;#x2F;family&amp;gt;
    &amp;lt;family&amp;gt;Noto Sans CJK SC&amp;lt;&amp;#x2F;family&amp;gt;
  &amp;lt;&amp;#x2F;prefer&amp;gt;
&amp;lt;&amp;#x2F;alias&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;2-dpisuo-fang-she-zhi&quot;&gt;2. DPI缩放设置&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 检查当前DPI
xdpyinfo | grep dots
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;xml&quot; class=&quot;language-xml &quot;&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;# 配置DPI (创建 ~&amp;#x2F;.config&amp;#x2F;fontconfig&amp;#x2F;conf.d&amp;#x2F;99-dpi.conf)
&amp;lt;match target=&amp;quot;pattern&amp;quot;&amp;gt;
  &amp;lt;edit name=&amp;quot;dpi&amp;quot; mode=&amp;quot;assign&amp;quot;&amp;gt;&amp;lt;double&amp;gt;144&amp;lt;&amp;#x2F;double&amp;gt;&amp;lt;&amp;#x2F;edit&amp;gt;
&amp;lt;&amp;#x2F;match&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;3-fu-hao-zi-ti-xiu-fu&quot;&gt;3. 符号字体修复&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;xml&quot; class=&quot;language-xml &quot;&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&amp;lt;!-- 修复终端符号显示 --&amp;gt;
&amp;lt;match target=&amp;quot;pattern&amp;quot;&amp;gt;
  &amp;lt;test name=&amp;quot;family&amp;quot;&amp;gt;&amp;lt;string&amp;gt;monospace&amp;lt;&amp;#x2F;string&amp;gt;&amp;lt;&amp;#x2F;test&amp;gt;
  &amp;lt;edit name=&amp;quot;family&amp;quot; mode=&amp;quot;append&amp;quot;&amp;gt;
    &amp;lt;string&amp;gt;Symbols Nerd Font&amp;lt;&amp;#x2F;string&amp;gt;
  &amp;lt;&amp;#x2F;edit&amp;gt;
&amp;lt;&amp;#x2F;match&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;mag-diao-shi-yu-wen-ti-pai-cha&quot;&gt;🔍 调试与问题排查&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;cha-kan-sheng-xiao-pei-zhi&quot;&gt;查看生效配置&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;fc-conflist  # 列出所有加载的配置文件
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;ce-shi-pei-zhi-xiao-guo&quot;&gt;测试配置效果&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;FC_DEBUG=4 fc-match sans-serif  # 输出详细匹配过程
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;chang-jian-wen-ti-jie-jue&quot;&gt;常见问题解决&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 字体不显示？
strace -e open fc-match &amp;quot;Arial&amp;quot; 2&amp;gt;&amp;amp;1 | grep fonts  # 检查文件访问路径
# 渲染异常？
FC_DEBUG=1024 fc-match sans-serif &amp;gt; debug.log  # 生成详细调试日志
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;bulb-zui-jia-shi-jian-jian-yi&quot;&gt;💡 最佳实践建议&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;mu-lu-jie-gou&quot;&gt;目录结构&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text &quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;~&amp;#x2F;.config&amp;#x2F;fontconfig&amp;#x2F;conf.d&amp;#x2F;
├── 10-font-paths.conf    # 添加字体目录
├── 20-universal-aliases.conf # 逻辑字体映射
├── 30-rendering-options.conf # 渲染参数
└── 99-local-overrides.conf   # 本地覆盖
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;pei-zhi-you-xian-ji&quot;&gt;配置优先级&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;mermaid flowchart&quot; class=&quot;language-mermaid flowchart &quot;&gt;&lt;code class=&quot;language-mermaid flowchart&quot; data-lang=&quot;mermaid flowchart&quot;&gt;graph LR
A[系统默认] --&amp;gt; B[&amp;#x2F;etc&amp;#x2F;fonts&amp;#x2F;conf.d&amp;#x2F;]
B --&amp;gt; C[~&amp;#x2F;.config&amp;#x2F;fontconfig&amp;#x2F;conf.d&amp;#x2F;]
C --&amp;gt; D[应用特定设置]
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;hui-fu-mo-ren-pei-zhi&quot;&gt;恢复默认配置&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;rm -rf ~&amp;#x2F;.config&amp;#x2F;fontconfig&amp;#x2F;  # 删除用户配置
sudo fc-cache -fv            # 重建缓存
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;通过合理配置这些文件和命令，您可以完全掌控 Linux 系统的字体渲染行为，解决多语言支持、高分屏适配等复杂场景问题。&lt;&#x2F;p&gt;
&lt;h1 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;lbqaq.top&#x2F;p&#x2F;linux-font&#x2F;&quot;&gt;字体配置&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>linux 字体如何配置</title>
        <published>2025-08-14T14:12:52+08:00</published>
        <updated>2025-08-14T14:12:52+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/08/linux 字体如何配置/"/>
        <id>https://vercel.juzhong.xyz/2025/08/linux 字体如何配置/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/08/linux 字体如何配置/">&lt;h1 id=&quot;zhu-yao-de-pei-zhi-wen-jian&quot;&gt;主要的配置文件&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;系统级
&lt;ul&gt;
&lt;li&gt;&#x2F;etc&#x2F;fonts&#x2F;fonts.conf&lt;&#x2F;li&gt;
&lt;li&gt;主配置文件（通常不建议直接修改）&lt;&#x2F;li&gt;
&lt;li&gt;&#x2F;etc&#x2F;fonts&#x2F;conf.d&#x2F;&lt;&#x2F;li&gt;
&lt;li&gt;符号链接到 &#x2F;usr&#x2F;share&#x2F;fontconfig&#x2F;conf.avail&#x2F; 中的配置片段&lt;&#x2F;li&gt;
&lt;li&gt;&#x2F;usr&#x2F;share&#x2F;fontconfig&#x2F;conf.avail&#x2F;&lt;&#x2F;li&gt;
&lt;li&gt;可用的配置片段（如 10-hinting.conf）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;用户级配置（推荐）
&lt;ul&gt;
&lt;li&gt;~&#x2F;.config&#x2F;fontconfig&#x2F;fonts.conf
&lt;ul&gt;
&lt;li&gt;用户自定义字体配置（最常用）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;~&#x2F;.fonts.conf
&lt;ul&gt;
&lt;li&gt;旧式用户配置（已废弃，但仍支持）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;zi-ti-wen-jian&quot;&gt;字体文件&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;系统级字体
&lt;ul&gt;
&lt;li&gt;&#x2F;usr&#x2F;share&#x2F;fonts&#x2F;&lt;&#x2F;li&gt;
&lt;li&gt;需 root 权限操作&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;用户级字体
&lt;ul&gt;
&lt;li&gt;~&#x2F;.fonts&#x2F; 或 ~&#x2F;.local&#x2F;share&#x2F;fonts&#x2F;&lt;&#x2F;li&gt;
&lt;li&gt;无需特权，仅影响当前用户&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;自定义目录
&lt;ul&gt;
&lt;li&gt;如 &#x2F;opt&#x2F;fonts&#x2F;&lt;&#x2F;li&gt;
&lt;li&gt;需在 fonts.conf 中添加 dir 标签&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;an-zhuang-zi-ti&quot;&gt;安装字体&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 系统级安装（需 root）
sudo cp newfont.ttf &amp;#x2F;usr&amp;#x2F;share&amp;#x2F;fonts&amp;#x2F;truetype&amp;#x2F;
sudo fc-cache -fv  # 刷新缓存
# 用户级安装
cp newfont.ttf ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;fonts&amp;#x2F;
fc-cache -fv  # 刷新用户缓存
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;diao-shi-gong-ju&quot;&gt;调试工具&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;fc-list :lang=zh  
# 测试字体匹配逻辑11
fc-match &amp;quot;Microsoft YaHei&amp;quot; 
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;xuan-ran-kong-zhi&quot;&gt;‌渲染控制‌&lt;&#x2F;h2&gt;
&lt;p&gt;修改 &#x2F;etc&#x2F;fonts&#x2F;conf.d&#x2F;10-antialias.conf 启用抗锯齿：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;xml&quot; class=&quot;language-xml &quot;&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&amp;lt;match target=&amp;quot;font&amp;quot;&amp;gt;
  &amp;lt;edit name=&amp;quot;antialias&amp;quot; mode=&amp;quot;assign&amp;quot;&amp;gt;&amp;lt;bool&amp;gt;true&amp;lt;&amp;#x2F;bool&amp;gt;&amp;lt;&amp;#x2F;edit&amp;gt;
&amp;lt;&amp;#x2F;match&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;you-xian-xian-shi-ce-lue&quot;&gt;优先显示策略‌&lt;&#x2F;h2&gt;
&lt;p&gt;在 fonts.conf 中强制指定中文字体族：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;xml&quot; class=&quot;language-xml &quot;&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&amp;lt;alias&amp;gt;
  &amp;lt;family&amp;gt;serif&amp;lt;&amp;#x2F;family&amp;gt;
  &amp;lt;prefer&amp;gt;
    &amp;lt;family&amp;gt;Source Han Serif SC&amp;lt;&amp;#x2F;family&amp;gt; &amp;lt;!-- 思源宋体 --&amp;gt;
  &amp;lt;&amp;#x2F;prefer&amp;gt;
&amp;lt;&amp;#x2F;alias&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;que-shi-jie-jue-fang-an&quot;&gt;‌缺失解决方案‌&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Windows 字体迁移：复制 C:\Windows\Fonts 下的 *.ttf 到 Linux 字体目录&lt;&#x2F;li&gt;
&lt;li&gt;安装开源字体包：&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt install fonts-noto-cjk  # Ubuntu&amp;#x2F;Debian
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;huan-cun-yu-sheng-xiao&quot;&gt;缓存与生效&lt;&#x2F;h1&gt;
&lt;p&gt;‌刷新缓存‌：任何字体增删后必须执行 fc-cache -fv
‌应用生效‌：部分应用需重启才能加载新配置（如终端、浏览器）&lt;&#x2F;p&gt;
&lt;h1 id=&quot;an-zhuang-zi-ti-1&quot;&gt;安装字体&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 创建用户字体目录
mkdir -p ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;fonts
# 复制字体文件（.ttf, .otf, .woff 等）
cp ~&amp;#x2F;Downloads&amp;#x2F;JetBrainsMono-Regular.ttf ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;fonts&amp;#x2F;
# 刷新字体缓存
fc-cache -fv
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;cha-kan-yi-an-zhuang-zi-ti&quot;&gt;查看已安装字体&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 列出所有字体族名
fc-list : family
# 搜索特定字体
fc-list : family | grep -i &amp;quot;jetbrains\|fira\|mono&amp;quot;
# 查看某个字体的详细信息
fc-query ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;fonts&amp;#x2F;JetBrainsMono-Regular.ttf | grep -A 2 -B 2 family
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;ce-shi-zi-ti-pi-pei&quot;&gt;测试字体匹配&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 查看 monospace 别名指向哪个字体
fc-match monospace
# 查看 sans-serif 指向哪个字体
fc-match &amp;quot;sans-serif&amp;quot;
# 查看你设置的字体是否能匹配
fc-match &amp;quot;JetBrains Mono&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;pei-zhi-zi-ti-bie-ming-li-ru-rang-monospace-shi-yong-jetbrains-mono&quot;&gt;配置字体别名（例如：让 monospace 使用 JetBrains Mono）&lt;&#x2F;h2&gt;
&lt;p&gt;编辑用户配置文件：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;mkdir -p ~&amp;#x2F;.config&amp;#x2F;fontconfig
nano ~&amp;#x2F;.config&amp;#x2F;fontconfig&amp;#x2F;fonts.conf
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;xml&quot; class=&quot;language-xml &quot;&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;
&amp;lt;!DOCTYPE fontconfig SYSTEM &amp;quot;fonts.dtd&amp;quot;&amp;gt;
&amp;lt;fontconfig&amp;gt;
  &amp;lt;!-- 设置 monospace 默认为 JetBrains Mono --&amp;gt;
  &amp;lt;alias&amp;gt;
    &amp;lt;family&amp;gt;monospace&amp;lt;&amp;#x2F;family&amp;gt;
    &amp;lt;prefer&amp;gt;
      &amp;lt;family&amp;gt;JetBrains Mono&amp;lt;&amp;#x2F;family&amp;gt;
      &amp;lt;family&amp;gt;DejaVu Sans Mono&amp;lt;&amp;#x2F;family&amp;gt;
      &amp;lt;family&amp;gt;Liberation Mono&amp;lt;&amp;#x2F;family&amp;gt;
    &amp;lt;&amp;#x2F;prefer&amp;gt;
  &amp;lt;&amp;#x2F;alias&amp;gt;

  &amp;lt;!-- 可选：设置 sans-serif --&amp;gt;
  &amp;lt;alias&amp;gt;
    &amp;lt;family&amp;gt;sans-serif&amp;lt;&amp;#x2F;family&amp;gt;
    &amp;lt;prefer&amp;gt;
      &amp;lt;family&amp;gt;Inter&amp;lt;&amp;#x2F;family&amp;gt;
      &amp;lt;family&amp;gt;Roboto&amp;lt;&amp;#x2F;family&amp;gt;
    &amp;lt;&amp;#x2F;prefer&amp;gt;
  &amp;lt;&amp;#x2F;alias&amp;gt;
&amp;lt;&amp;#x2F;fontconfig&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 保存后刷新缓存：
fc-cache -fv
# 验证
fc-match monospace
# 你应该看到输出指向 JetBrains Mono
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;pei-zhi-zi-ti-xuan-ran-xiao-guo-ke-xuan&quot;&gt;配置字体渲染效果（可选）&lt;&#x2F;h2&gt;
&lt;p&gt;你可以在 fonts.conf 中添加渲染优化：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;xml&quot; class=&quot;language-xml &quot;&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&amp;lt;match target=&amp;quot;font&amp;quot;&amp;gt;
  &amp;lt;edit name=&amp;quot;antialias&amp;quot; mode=&amp;quot;assign&amp;quot;&amp;gt;&amp;lt;bool&amp;gt;true&amp;lt;&amp;#x2F;bool&amp;gt;&amp;lt;&amp;#x2F;edit&amp;gt;
  &amp;lt;edit name=&amp;quot;hinting&amp;quot; mode=&amp;quot;assign&amp;quot;&amp;gt;&amp;lt;bool&amp;gt;true&amp;lt;&amp;#x2F;bool&amp;gt;&amp;lt;&amp;#x2F;edit&amp;gt;
  &amp;lt;edit name=&amp;quot;hintstyle&amp;quot; mode=&amp;quot;assign&amp;quot;&amp;gt;&amp;lt;const&amp;gt;hintslight&amp;lt;&amp;#x2F;const&amp;gt;&amp;lt;&amp;#x2F;edit&amp;gt;
  &amp;lt;edit name=&amp;quot;rgba&amp;quot; mode=&amp;quot;assign&amp;quot;&amp;gt;&amp;lt;const&amp;gt;rgb&amp;lt;&amp;#x2F;const&amp;gt;&amp;lt;&amp;#x2F;edit&amp;gt;
  &amp;lt;edit name=&amp;quot;lcdfilter&amp;quot; mode=&amp;quot;assign&amp;quot;&amp;gt;&amp;lt;const&amp;gt;lcddefault&amp;lt;&amp;#x2F;const&amp;gt;&amp;lt;&amp;#x2F;edit&amp;gt;
  &amp;lt;edit name=&amp;quot;autohint&amp;quot; mode=&amp;quot;assign&amp;quot;&amp;gt;&amp;lt;bool&amp;gt;false&amp;lt;&amp;#x2F;bool&amp;gt;&amp;lt;&amp;#x2F;edit&amp;gt;
&amp;lt;&amp;#x2F;match&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;解释：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;antialias: 启用抗锯齿&lt;&#x2F;li&gt;
&lt;li&gt;hinting: 字体微调（可选 hintnone, hintslight, hintmedium, hintfull）&lt;&#x2F;li&gt;
&lt;li&gt;rgba: 子像素渲染方向（LCD 屏幕适用）&lt;&#x2F;li&gt;
&lt;li&gt;lcdfilter: 平滑子像素边缘&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;💡 建议：笔记本&#x2F;高分屏用 hintslight + lcddefault，台式机 RGB 屏可用 rgb&lt;&#x2F;p&gt;
&lt;h1 id=&quot;pei-zhi-kittyzi-ti-ju-ti-ying-yong-chang-jing&quot;&gt;配置kitty字体： 具体应用场景&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt install fonts-jetbrains-mono
cat &amp;lt;&amp;lt;EOF &amp;gt;&amp;gt; ~&amp;#x2F;.config&amp;#x2F;kitty&amp;#x2F;kitty.conf
font_family JetBrains Mono
font_size 14.0
EOF
# 验证
fc-match &amp;quot;JetBrains Mono&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;rang-suo-you-ying-yong-you-xian-shi-yong-fira-code&quot;&gt;让所有应用优先使用 Fira Code&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt install fonts-firacode
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;xml&quot; class=&quot;language-xml &quot;&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&amp;lt;!-- ~&amp;#x2F;.config&amp;#x2F;fontconfig&amp;#x2F;fonts.conf --&amp;gt;
&amp;lt;alias&amp;gt;
  &amp;lt;family&amp;gt;monospace&amp;lt;&amp;#x2F;family&amp;gt;
  &amp;lt;prefer&amp;gt;
    &amp;lt;family&amp;gt;Fira Code&amp;lt;&amp;#x2F;family&amp;gt;
  &amp;lt;&amp;#x2F;prefer&amp;gt;
&amp;lt;&amp;#x2F;alias&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;然后 fc-cache -fv，重启 Kitty 或其他应用&lt;&#x2F;p&gt;
&lt;h2 id=&quot;xiu-fu-zhong-wen-luan-ma-huo-ying-wen-mo-hu&quot;&gt;修复中文乱码或英文模糊&lt;&#x2F;h2&gt;
&lt;p&gt;有时英文用等宽字体，中文却没字体可显示。可以添加中文字体 fallback：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;xml&quot; class=&quot;language-xml &quot;&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&amp;lt;alias&amp;gt;
  &amp;lt;family&amp;gt;serif&amp;lt;&amp;#x2F;family&amp;gt;
  &amp;lt;prefer&amp;gt;
    &amp;lt;family&amp;gt;Noto Serif CJK SC&amp;lt;&amp;#x2F;family&amp;gt;
  &amp;lt;&amp;#x2F;prefer&amp;gt;
&amp;lt;&amp;#x2F;alias&amp;gt;
&amp;lt;alias&amp;gt;
  &amp;lt;family&amp;gt;sans-serif&amp;lt;&amp;#x2F;family&amp;gt;
  &amp;lt;prefer&amp;gt;
    &amp;lt;family&amp;gt;Noto Sans CJK SC&amp;lt;&amp;#x2F;family&amp;gt;
  &amp;lt;&amp;#x2F;prefer&amp;gt;
&amp;lt;&amp;#x2F;alias&amp;gt;
&amp;lt;alias&amp;gt;
  &amp;lt;family&amp;gt;monospace&amp;lt;&amp;#x2F;family&amp;gt;
  &amp;lt;prefer&amp;gt;
    &amp;lt;family&amp;gt;JetBrains Mono&amp;lt;&amp;#x2F;family&amp;gt;
    &amp;lt;family&amp;gt;Noto Sans Mono CJK SC&amp;lt;&amp;#x2F;family&amp;gt;
  &amp;lt;&amp;#x2F;prefer&amp;gt;
&amp;lt;&amp;#x2F;alias&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;安装中文字体（如 Noto CJK）：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt install fonts-noto-cjk
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;diao-shi-ji-qiao&quot;&gt;调试技巧&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;查看字体缓存状态 &lt;code&gt;fc-cache -s&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;检查某个字体是否被扫描 &lt;code&gt;fc-list&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;查看配置加载顺序 &lt;code&gt;fc-match -v monospace&lt;&#x2F;code&gt; （看输出中的 pattern）&lt;&#x2F;li&gt;
&lt;li&gt;强制重建所有缓存 &lt;code&gt;fc-cache -fv ~&#x2F;.local&#x2F;share&#x2F;fonts&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;zui-jia-shi-jian&quot;&gt;最佳实践&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;安装字体
&lt;ul&gt;
&lt;li&gt;放入 ~&#x2F;.local&#x2F;share&#x2F;fonts&#x2F;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;配置字体
&lt;ul&gt;
&lt;li&gt;使用 ~&#x2F;.config&#x2F;fontconfig&#x2F;fonts.conf&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;修改默认等宽字体
&lt;ul&gt;
&lt;li&gt;在 fonts.conf 中设置 monospace 别名&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;刷新配置
&lt;ul&gt;
&lt;li&gt;fc-cache -fv&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;验证结果
&lt;ul&gt;
&lt;li&gt;fc-match monospace&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;wan-zheng-shi-li-pei-zhi-wen-jian&quot;&gt;完整示例配置文件&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;xml&quot; class=&quot;language-xml &quot;&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&amp;lt;!-- ~&amp;#x2F;.config&amp;#x2F;fontconfig&amp;#x2F;fonts.conf --&amp;gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;
&amp;lt;!DOCTYPE fontconfig SYSTEM &amp;quot;fonts.dtd&amp;quot;&amp;gt;
&amp;lt;fontconfig&amp;gt;

  &amp;lt;!-- 设置 monospace 默认字体 --&amp;gt;
  &amp;lt;alias&amp;gt;
    &amp;lt;family&amp;gt;monospace&amp;lt;&amp;#x2F;family&amp;gt;
    &amp;lt;prefer&amp;gt;
      &amp;lt;family&amp;gt;JetBrains Mono&amp;lt;&amp;#x2F;family&amp;gt;
      &amp;lt;family&amp;gt;Fira Code&amp;lt;&amp;#x2F;family&amp;gt;
      &amp;lt;family&amp;gt;DejaVu Sans Mono&amp;lt;&amp;#x2F;family&amp;gt;
    &amp;lt;&amp;#x2F;prefer&amp;gt;
  &amp;lt;&amp;#x2F;alias&amp;gt;

  &amp;lt;!-- 渲染优化 --&amp;gt;
  &amp;lt;match target=&amp;quot;font&amp;quot;&amp;gt;
    &amp;lt;edit name=&amp;quot;antialias&amp;quot; mode=&amp;quot;assign&amp;quot;&amp;gt;&amp;lt;bool&amp;gt;true&amp;lt;&amp;#x2F;bool&amp;gt;&amp;lt;&amp;#x2F;edit&amp;gt;
    &amp;lt;edit name=&amp;quot;hinting&amp;quot; mode=&amp;quot;assign&amp;quot;&amp;gt;&amp;lt;bool&amp;gt;true&amp;lt;&amp;#x2F;bool&amp;gt;&amp;lt;&amp;#x2F;edit&amp;gt;
    &amp;lt;edit name=&amp;quot;hintstyle&amp;quot; mode=&amp;quot;assign&amp;quot;&amp;gt;&amp;lt;const&amp;gt;hintslight&amp;lt;&amp;#x2F;const&amp;gt;&amp;lt;&amp;#x2F;edit&amp;gt;
    &amp;lt;edit name=&amp;quot;rgba&amp;quot; mode=&amp;quot;assign&amp;quot;&amp;gt;&amp;lt;const&amp;gt;rgb&amp;lt;&amp;#x2F;const&amp;gt;&amp;lt;&amp;#x2F;edit&amp;gt;
    &amp;lt;edit name=&amp;quot;lcdfilter&amp;quot; mode=&amp;quot;assign&amp;quot;&amp;gt;&amp;lt;const&amp;gt;lcddefault&amp;lt;&amp;#x2F;const&amp;gt;&amp;lt;&amp;#x2F;edit&amp;gt;
  &amp;lt;&amp;#x2F;match&amp;gt;

&amp;lt;&amp;#x2F;fontconfig&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>linux 字体配置</title>
        <published>2025-08-14T12:39:02+08:00</published>
        <updated>2025-08-14T12:39:02+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/08/linux 字体配置/"/>
        <id>https://vercel.juzhong.xyz/2025/08/linux 字体配置/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/08/linux 字体配置/">&lt;h1 id=&quot;zi-ti-pei-zhi-zhong-she-ji-dao-de-ji-ge-ming-cheng&quot;&gt;字体配置中涉及到的几个名称&lt;&#x2F;h1&gt;
&lt;p&gt;字体的几个“名字”：别被搞混了&lt;&#x2F;p&gt;
&lt;p&gt;一个字体在系统中可能有多个“名字”，它们分别是：&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;名称类型&lt;&#x2F;th&gt;&lt;th&gt;实例&lt;&#x2F;th&gt;&lt;th&gt;说明&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;字体文件名&lt;&#x2F;td&gt;&lt;td&gt;JetBrainsMono-Regular.ttf&lt;&#x2F;td&gt;&lt;td&gt;文件系统中的名字， 不用于配置&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;字体族名（Family）&lt;&#x2F;td&gt;&lt;td&gt;JetBrains Mono&lt;&#x2F;td&gt;&lt;td&gt;最重要的名字，用于 fc-match 和 Kitty 配置&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;字体样式名（Style）&lt;&#x2F;td&gt;&lt;td&gt;Regular , Bold , Italic&lt;&#x2F;td&gt;&lt;td&gt;区分粗体、斜体等&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;完整字体名（Full Name）&lt;&#x2F;td&gt;&lt;td&gt;JetBrains Mono Regular&lt;&#x2F;td&gt;&lt;td&gt;族名 + 样式，一般也不用于配置&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;yong-fc-list-kan-kan-shi-ji-shu-chu&quot;&gt;用 fc-list 看看实际输出&lt;&#x2F;h2&gt;
&lt;p&gt;先安装对应的字体&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt install fonts-jetbrains-mono
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;使用fc-list 查看&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;fc-list | grep -i &amp;quot;jetbrains&amp;quot;
fc-list | grep -i &amp;quot;notosansmono&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;输出可能类似：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text &quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;&amp;#x2F;usr&amp;#x2F;share&amp;#x2F;fonts&amp;#x2F;JetBrainsMono&amp;#x2F;JetBrainsMono-Regular.ttf: JetBrains Mono:style=Regular
&amp;#x2F;usr&amp;#x2F;share&amp;#x2F;fonts&amp;#x2F;JetBrainsMono&amp;#x2F;JetBrainsMono-Bold.ttf: JetBrains Mono:style=Bold
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;解读：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;路径：&#x2F;usr&#x2F;share&#x2F;fonts&#x2F;...&#x2F;JetBrainsMono-Regular.ttf → 这是文件名&lt;&#x2F;li&gt;
&lt;li&gt;第一个名字：JetBrains Mono → 这是字体族名（Family） ✅（你要用的）&lt;&#x2F;li&gt;
&lt;li&gt;style=Regular → 这是字体样式&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;✅ 所以你应该在 Kitty 中使用 font_family JetBrains Mono，而不是 JetBrainsMono-Regular.ttf&lt;&#x2F;p&gt;
&lt;h2 id=&quot;fc-match-yong-shen-me-ming-zi-yong-zi-ti-zu-ming&quot;&gt;fc-match 用什么名字？用“字体族名”&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;fc-match &amp;quot;JetBrains Mono&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;✅ 正确：使用 族名（JetBrains Mono）&lt;&#x2F;li&gt;
&lt;li&gt;❌ 错误：使用文件名（JetBrainsMono-Regular.ttf）或完整名（JetBrains Mono Regular）
输出示例：&lt;&#x2F;li&gt;
&lt;li&gt;JetBrainsMono-Regular.ttf: &quot;JetBrains Mono&quot; &quot;Regular&quot;&lt;&#x2F;li&gt;
&lt;li&gt;这说明匹配成功。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;shi-yong-fontconfiggong-ju&quot;&gt;使用fontconfig工具&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;apt install fontconfig
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;fang-fa-1-yong-fc-list-ti-qu-zu-ming-tui-jian&quot;&gt;方法 1：用 fc-list 提取族名（推荐）&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 列出所有 JetBrains 字体的族名
fc-list : family | grep -i jetbrains
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;输出：&lt;&#x2F;li&gt;
&lt;li&gt;JetBrains Mono&lt;&#x2F;li&gt;
&lt;li&gt;→ 你就用 JetBrains Mono 作为 font_family&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;fang-fa-2-yong-fc-match-yan-zheng-shi-fou-neng-pi-pei&quot;&gt;方法 2：用 fc-match 验证是否能匹配&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;fc-match &amp;quot;JetBrains Mono&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;如果返回 .ttf 文件路径，说明名字正确。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;fang-fa-3-cha-kan-zi-ti-xiang-xi-xin-xi-gao-ji&quot;&gt;方法 3：查看字体详细信息（高级）&lt;&#x2F;h2&gt;
&lt;p&gt;使用 fc-query 查看某个字体文件的元数据：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;fc-query &amp;#x2F;usr&amp;#x2F;share&amp;#x2F;fonts&amp;#x2F;JetBrainsMono&amp;#x2F;JetBrainsMono-Regular.ttf | grep -i family
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;输出：&lt;&#x2F;li&gt;
&lt;li&gt;family: &quot;JetBrains Mono&quot;&lt;&#x2F;li&gt;
&lt;li&gt;familylang: &quot;en&quot;&lt;&#x2F;li&gt;
&lt;li&gt;→ 所以族名是 JetBrains Mono&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;no-entry-sign-chang-jian-cuo-wu-yong-fa-bu-yao-zhe-yang-zuo&quot;&gt;🚫 常见错误用法（不要这样做）&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;font_family JetBrainsMono-Regular.ttf&lt;&#x2F;li&gt;
&lt;li&gt;font_family JetBrains Mono Regular&lt;&#x2F;li&gt;
&lt;li&gt;font_family &#x2F;usr&#x2F;share&#x2F;fonts&#x2F;...&#x2F;ttf&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;te-shu-qing-kuang-nerd-fonts-bu-ding-zi-ti&quot;&gt;特殊情况：Nerd Fonts 补丁字体&lt;&#x2F;h1&gt;
&lt;p&gt;Nerd Fonts 给字体加了图标支持，通常会修改族名。&lt;&#x2F;p&gt;
&lt;p&gt;例如：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;fc-list | grep -i &amp;quot;nerd&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;输出：&lt;&#x2F;li&gt;
&lt;li&gt;... FiraCode Nerd Font:style=Regular&lt;&#x2F;li&gt;
&lt;li&gt;... JetBrainsMono Nerd Font:style=Medium&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;white-check-mark-zheng-que-pei-zhi&quot;&gt;✅ 正确配置：&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;font_family FiraCode Nerd Font&lt;&#x2F;li&gt;
&lt;li&gt;注意：空格和大小写都要一致！&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;shi-yong-ming-ling-su-cha-biao&quot;&gt;实用命令速查表&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;fc-list
# 格式：文件路径: 家族名, 完整名:style=样式
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 1. 列出所有字体族名（只显示 family）
fc-list : family
# 2. 搜索包含 &amp;quot;mono&amp;quot; 的字体族
fc-list : family | grep -i mono
# 3. 搜索 JetBrains 相关字体
fc-list : family | grep -i jetbrains
# 4. 验证某个字体是否可用
fc-match &amp;quot;Fira Code&amp;quot;
fc-match &amp;quot;JetBrains Mono&amp;quot;
# 5. 刷新字体缓存（安装新字体后）
fc-cache -fv
# 6
fc-list : family style
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;nei-bu-yuan-shu-ju-ming-cheng&quot;&gt;内部元数据名称&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;fc-scan &amp;#x2F;usr&amp;#x2F;share&amp;#x2F;fonts&amp;#x2F;truetype&amp;#x2F;jetbrains-mono&amp;#x2F;JetBrainsMono-Regular.ttf
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;fc-match-monospace-de-han-yi&quot;&gt;fc-match monospace 的含义&lt;&#x2F;h1&gt;
&lt;p&gt;monospace 是 fontconfig 定义的逻辑字体分类名&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;隐式属性匹配‌&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;monospace是Fontconfig通过spacing属性自动识别的分类，而非字体元数据中的显式字段。当字体满足spacing=100（等宽）时，系统会将其归入monospace类别，但该标签不会出现在fc-list的原始输出中56。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;‌验证方法‌&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;通过以下命令可查看字体的等宽属性：&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;fc-list :spacing=100  # 列出所有等宽字体
fc-list : family spacing | grep -B1 &amp;quot;100&amp;quot;  # 显示家族名和间距属性
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;mermaid flowchart&quot; class=&quot;language-mermaid flowchart &quot;&gt;&lt;code class=&quot;language-mermaid flowchart&quot; data-lang=&quot;mermaid flowchart&quot;&gt;graph LR
A[应用程序请求&amp;lt;br&amp;gt;“monospace”字体] --&amp;gt; B[fontconfig 规则引擎]
B --&amp;gt; C{匹配规则库&amp;lt;br&amp;gt;&amp;#x2F;etc&amp;#x2F;fonts&amp;#x2F;conf.d}
C --&amp;gt; D[物理字体文件]
D --&amp;gt; E[返回实际字体路径]
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;fc-match -s monospace | head -n5
fc-match monospace |head -n1 
# 查看完整的字体属性
fc-query &amp;#x2F;usr&amp;#x2F;share&amp;#x2F;fonts&amp;#x2F;opentype&amp;#x2F;noto&amp;#x2F;NotoSansCJK-Regular.ttc | grep -E &amp;#x27;family|style&amp;#x27;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;wei-shen-me-zhe-yang-she-ji&quot;&gt;为什么这样设计？&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;抽象层价值：
&lt;ul&gt;
&lt;li&gt;应用程序只需请求 &quot;monospace&quot;，不需知道具体字体&lt;&#x2F;li&gt;
&lt;li&gt;系统管理员可统一修改所有应用的等宽字体&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;多语言支持：&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;xml&quot; class=&quot;language-xml &quot;&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&amp;lt;!-- 针对中文的 monospace 优化 --&amp;gt;
&amp;lt;alias&amp;gt;
  &amp;lt;family&amp;gt;monospace&amp;lt;&amp;#x2F;family&amp;gt;
  &amp;lt;prefer&amp;gt;
    &amp;lt;family&amp;gt;Noto Sans Mono CJK SC&amp;lt;&amp;#x2F;family&amp;gt;
  &amp;lt;&amp;#x2F;prefer&amp;gt;
&amp;lt;&amp;#x2F;alias&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;字体回退机制：
当首选字体缺失字符时，自动回退到备选字体&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;qi-ta-zhu-yao-de-luo-ji-zi-ti-fen-lei-ming&quot;&gt;其他主要的逻辑字体分类名&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;serif（衬线体）
&lt;ul&gt;
&lt;li&gt;特征：字符末端带有装饰性衬线（如Times New Roman、宋体）。&lt;&#x2F;li&gt;
&lt;li&gt;用途：正文印刷、传统排版，提升长文本可读性13。&lt;&#x2F;li&gt;
&lt;li&gt;示例物理字体：
&lt;ul&gt;
&lt;li&gt;Linux: DejaVu Serif, Liberation Serif&lt;&#x2F;li&gt;
&lt;li&gt;Windows: Times New Roman&lt;&#x2F;li&gt;
&lt;li&gt;macOS: Georgia&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;sans-serif（无衬线体）
&lt;ul&gt;
&lt;li&gt;特征：无衬线，线条简洁（如Arial、微软雅黑）。&lt;&#x2F;li&gt;
&lt;li&gt;用途：屏幕显示、现代UI设计，适合标题和短文本134。&lt;&#x2F;li&gt;
&lt;li&gt;示例物理字体：
&lt;ul&gt;
&lt;li&gt;Linux: DejaVu Sans, Noto Sans&lt;&#x2F;li&gt;
&lt;li&gt;Windows: Arial&lt;&#x2F;li&gt;
&lt;li&gt;macOS: Helvetica&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;cursive（手写体）
&lt;ul&gt;
&lt;li&gt;特征：模拟手写风格，笔画连贯。&lt;&#x2F;li&gt;
&lt;li&gt;用途：艺术设计、个性化标题，不适用于长文本34。&lt;&#x2F;li&gt;
&lt;li&gt;示例物理字体：Comic Sans MS, Brush Script MT&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;fantasy（装饰体）
&lt;ul&gt;
&lt;li&gt;特征：高度装饰性，风格多变（如海报字体）。&lt;&#x2F;li&gt;
&lt;li&gt;用途：海报、LOGO设计，强调视觉冲击34。&lt;&#x2F;li&gt;
&lt;li&gt;示例物理字体：Impact, Papyrus&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;symbol（符号字体）
&lt;ul&gt;
&lt;li&gt;特征：包含特殊符号而非文字（如数学符号、图标）。&lt;&#x2F;li&gt;
&lt;li&gt;用途：数学公式、技术文档中的符号渲染13。&lt;&#x2F;li&gt;
&lt;li&gt;示例物理字体：Webdings, Symbol&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;si-yuan-zi-ti&quot;&gt;思源字体&lt;&#x2F;h1&gt;
&lt;p&gt;思源黑体，英文名为Source Han Sans，Google 称之为Noto Sans CJK，是一款由Adobe 和Google 共同开发的开源字体家族。它支持简体中文、繁体中文、日文和韩文，并且有多种字重，旨在为多语言环境提供一致的视觉体验。&lt;&#x2F;p&gt;
&lt;p&gt;思源字体和宋体、黑体的区别在于，思源字体是一个字体家族，包含了思源黑体和思源宋体，而宋体和黑体是两种常见的字体类型，各自都有不同的特点和应用场景。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zhu-yao-qu-bie&quot;&gt;主要区别&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;衬线:这是最主要的区别。宋体有衬线，黑体没有衬线.&lt;&#x2F;li&gt;
&lt;li&gt;风格:宋体更传统，黑体更现代.&lt;&#x2F;li&gt;
&lt;li&gt;应用场景:宋体常用于正文，黑体常用于标题和界面.&lt;&#x2F;li&gt;
&lt;li&gt;思源字体:思源字体家族提供了多种字重和对多种语言的支持，可以满足更广泛的需求.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;ju-ti-han-yi-ru-xia&quot;&gt;具体含义如下：&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;思源:
&lt;ul&gt;
&lt;li&gt;“思源”一词出自成语“饮水思源”，寓意对字体来源的尊重和对设计者的感谢。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;黑体:
&lt;ul&gt;
&lt;li&gt;指字体风格，是一种无衬线字体，特点是字形简洁、现代，笔画粗细均匀，易于阅读。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Source Han Sans:
&lt;ul&gt;
&lt;li&gt;Adobe 公司对该字体的英文名称，属于Adobe 的Source 字体家族。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Noto Sans CJK:
&lt;ul&gt;
&lt;li&gt;Google 公司对该字体的名称，属于Google 的Noto 字体家族。“CJK”代表中文（Chinese）、日文（Japanese）和韩文（Korean），表示该字体支持这三种语言的统一表意文字。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;总而言之，思源黑体&#x2F;Source Han Sans&#x2F;Noto Sans CJK 是一款由Adobe 和Google 合作开发的开源字体，以“饮水思源”命名，支持多种语言，具有简洁现代的设计风格，广泛应用于网页设计、印刷品、软件界面等领域。&lt;&#x2F;p&gt;
&lt;h1 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;lbqaq.top&#x2F;p&#x2F;linux-font&#x2F;&quot;&gt;字体配置&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>linux 终端崩溃排查</title>
        <published>2025-08-14T10:09:21+08:00</published>
        <updated>2025-08-14T10:09:21+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/08/linux 终端崩溃排查/"/>
        <id>https://vercel.juzhong.xyz/2025/08/linux 终端崩溃排查/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/08/linux 终端崩溃排查/">&lt;h1 id=&quot;xian-xiang&quot;&gt;现象&lt;&#x2F;h1&gt;
&lt;p&gt;第一次发生崩溃是在使用Ctrl+R 进行历史命令搜索时发生，
按下&lt;code&gt;Ctrl+R&lt;&#x2F;code&gt;后， 1秒内终端就直接退出了&lt;&#x2F;p&gt;
&lt;h1 id=&quot;pai-cha-guo-cheng&quot;&gt;排查过程&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;zhong-zhi-zhong-duan&quot;&gt;重置终端&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 重置gnome-terminal配置
dconf reset -f &amp;#x2F;org&amp;#x2F;gnome&amp;#x2F;terminal&amp;#x2F;
# 或完全删除配置
rm -rf ~&amp;#x2F;.config&amp;#x2F;gnome-terminal&amp;#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;jian-cha-ri-zhi&quot;&gt;检查日志&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;journalctl -xe | grep -i terminal
dmesg | grep -i error
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;chang-shi-qi-ta-zhong-duan&quot;&gt;尝试其他终端&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;首次使用tilix时，发现正常了&lt;&#x2F;li&gt;
&lt;li&gt;但是这只是表象 ORZ&lt;&#x2F;li&gt;
&lt;li&gt;用了一天之后，又发生了同样的异常&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;apt install tilix
tilix
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;huai-yi-fzf&quot;&gt;怀疑fzf&lt;&#x2F;h2&gt;
&lt;p&gt;首先 Ctrl + R 绑定的程序是fzf&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;bindkey | grep -Ei &amp;#x27;\^r&amp;#x27;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;直接运行fzf发现就会发生崩溃&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;wei-shen-me-xin-an-zhuang-de-zhong-duan-bu-hui-beng-kui-ni&quot;&gt;为什么新安装的终端不会崩溃呢？&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;使用strace发现fzf发生了141退出吗，&lt;&#x2F;li&gt;
&lt;li&gt;搜索后发现是sigpipe导致的:  &lt;code&gt;sig = errno - 128 = 141 - 128 = 13&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;即退出码141对应信号13（SIGPIPE）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;strace -f -o fzf.log fzf
strace -f -e trace=pipe,write,socket -o debug.log fzf
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;怀疑是结果过大导致的&lt;&#x2F;li&gt;
&lt;li&gt;最后缩小范围，发现候选行数超过一定行数fzf就会报错&lt;&#x2F;li&gt;
&lt;li&gt;但是这个值会发生变化&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;yes | head -n 46149 | fzf
seq 50000 | fzf
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;huan-zhong-duan-mo-ni-qi&quot;&gt;换终端模拟器&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;apt install kitty&lt;&#x2F;li&gt;
&lt;li&gt;apt install alacritty&lt;&#x2F;li&gt;
&lt;li&gt;apt install tilix #（也基于 VTE，但版本有时会稍微稳定些）&lt;&#x2F;li&gt;
&lt;li&gt;用 tmux 作为缓冲&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;seq 1000000 | fzf
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;我切换了kitty终端，发现是正常的， 怀疑的确是VTE的bug导致的&lt;&#x2F;p&gt;
&lt;h2 id=&quot;wei-shen-me-kitty-alacritty-zheng-chang&quot;&gt;为什么 kitty &#x2F; alacritty 正常？&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;终端&lt;&#x2F;th&gt;&lt;th&gt;渲染引擎&lt;&#x2F;th&gt;&lt;th&gt;特点&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;kitty&lt;&#x2F;td&gt;&lt;td&gt;自研 GPU 加速&lt;&#x2F;td&gt;&lt;td&gt;高性能，专为大输出优化&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;alacritty&lt;&#x2F;td&gt;&lt;td&gt;GPU 加速（OpenGL）&lt;&#x2F;td&gt;&lt;td&gt;极致性能，Rust 编写&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;gnome-terminal &#x2F; tilix&lt;&#x2F;td&gt;&lt;td&gt;VTE（CPU 渲染）&lt;&#x2F;td&gt;&lt;td&gt;功能完整但性能较弱&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;👉 kitty 和 alacritty 使用现代渲染架构，能更高效处理 fzf 的快速滚动和高密度输出。&lt;&#x2F;p&gt;
&lt;h1 id=&quot;jie-jue-fang-an&quot;&gt;解决方案&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;xu-shi-yong-kitty-huo-alacritty-tui-jian&quot;&gt;续使用 kitty 或 alacritty（推荐）&lt;&#x2F;h2&gt;
&lt;p&gt;这是最稳定、长期有效的方案：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 安装 kitty
sudo apt install kitty
# 或安装 alacritty
sudo apt install alacritty
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;💡 推荐 kitty：功能丰富、文档完善、对 fzf&#x2F;tmux 支持极佳。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sheng-ji-vte-dao-0-76-feng-xian-jiao-gao&quot;&gt;升级 VTE 到 0.76+（风险较高）&lt;&#x2F;h2&gt;
&lt;p&gt;Ubuntu 24.04 默认未提供新版 VTE，但您可以：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;从 Debian 测试源或第三方 PPA 安装&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 添加提供新版 VTE 的 PPA（需谨慎）
# 例如：https:&amp;#x2F;&amp;#x2F;launchpad.net&amp;#x2F;~gnome-team&amp;#x2F;+archive&amp;#x2F;ubuntu&amp;#x2F;gnome3
sudo add-apt-repository ppa:gnome-team&amp;#x2F;gnome3
sudo apt update
sudo apt install libvte-2.91-dev libvte-2.91-0
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;shen-me-shi-vte&quot;&gt;什么是 VTE？&lt;&#x2F;h3&gt;
&lt;p&gt;VTE 是 GNOME Terminal、Tilix、MATE Terminal 等使用的底层终端控件库（libvte）
Ubuntu 24.04 默认带的是 VTE 0.74.x，这个版本在 Gitlab issue 里已经有 “ncurses 程序在大数据输入下崩溃” 的 bug 报告，可以试试更新到 0.76+ 或从源码编译新版本。
该版本在处理高吞吐量、快速连续的 ANSI&#x2F;VT100 控制序列输出时，存在缓冲区管理缺陷&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>tcpdump 抓包sing-box流量</title>
        <published>2025-08-13T16:03:07+08:00</published>
        <updated>2025-08-13T16:03:07+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/08/learn/tcpdump 抓包sing-box流量/"/>
        <id>https://vercel.juzhong.xyz/2025/08/learn/tcpdump 抓包sing-box流量/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/08/learn/tcpdump 抓包sing-box流量/">&lt;h1 id=&quot;shi-yong-de-sing-boxdai-ma&quot;&gt;使用的sing-box代码&lt;&#x2F;h1&gt;
&lt;p&gt;下载并编译&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git clone git@github.com:moxuetianya&amp;#x2F;sing-box.git
cd sing-box
go build -v .&amp;#x2F;cmd&amp;#x2F;sing-box&amp;#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;qi-dong-sing-box-vless-jie-dian&quot;&gt;启动sing-box vless 节点&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;.&amp;#x2F;sing-box run -c release&amp;#x2F;config&amp;#x2F;vless-config-client.json 
.&amp;#x2F;sing-box run -c release&amp;#x2F;config&amp;#x2F;vless-config.json 
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;jin-yong-ipv6&quot;&gt;禁用ipv6&lt;&#x2F;h1&gt;
&lt;p&gt;发现本地的网络出口不支持ipv6
直接使用上面的命令启动后， 代理访问目的服务可能使用ipv6地址&lt;&#x2F;p&gt;
&lt;p&gt;如 www.baidu.com, 使用了ipv6地址, 但是本地网络提供商没有提供ipv6服务，导致超时报错&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;curl -X5 -x socks5:&amp;#x2F;&amp;#x2F;127.0.0.1:1080 www.baidu.com
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;粗暴点，直接禁用接口的ipv6&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1
curl -X5 -x socks5:&amp;#x2F;&amp;#x2F;127.0.0.1:1080 www.baidu.com
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;zhua-bao&quot;&gt;抓包&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo tcpdump -i lo port 50000 -w &amp;#x2F;tmp&amp;#x2F;vless.pcap -nnvv
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>linxu DNS systemd-resolved</title>
        <published>2025-08-13T11:37:01+08:00</published>
        <updated>2025-08-13T11:37:01+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/08/linxu DNS systemd-resolved/"/>
        <id>https://vercel.juzhong.xyz/2025/08/linxu DNS systemd-resolved/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/08/linxu DNS systemd-resolved/">&lt;h1 id=&quot;systemd-resolved-huo-qu-shang-you-dns-de-tu-jing&quot;&gt;systemd-resolved 获取上游 DNS 的途径&lt;&#x2F;h1&gt;
&lt;p&gt;systemd-resolved 不会依赖 &#x2F;etc&#x2F;resolv.conf 获取上游 DNS（因为那是它给应用程序提供的入口）。它通过更底层的、按网络接口（Link）独立配置 的方式获取上游 DNS：&lt;&#x2F;p&gt;
&lt;h2 id=&quot;wang-luo-guan-li-qi-pei-zhi-zhu-yao-lai-yuan&quot;&gt;网络管理器配置（主要来源）:&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;systemd-networkd： 如果使用 systemd-networkd 管理网络，会在网络配置文件（如 &#x2F;etc&#x2F;systemd&#x2F;network&#x2F;80-wired.network）中通过 DNS= 选项指定：&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;ini&quot; class=&quot;language-ini &quot;&gt;&lt;code class=&quot;language-ini&quot; data-lang=&quot;ini&quot;&gt;[Network]
DNS=192.168.1.1 8.8.8.8
DNS=1.1.1.1
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;NetworkManager： 如果使用 GNOME&#x2F;KDE 等桌面环境的 NetworkManager：
&lt;ul&gt;
&lt;li&gt;它会自动从 DHCP 服务器获取 DNS 信息。&lt;&#x2F;li&gt;
&lt;li&gt;或通过 GUI&#x2F;nmcli 手动配置的 DNS 服务器（如 nmcli con mod eth0 ipv4.dns &quot;192.168.1.1 8.8.8.8&quot;）。&lt;&#x2F;li&gt;
&lt;li&gt;NetworkManager 会将这些配置通过 D-Bus 实时推送给 systemd-resolved。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;systemd-resolved-quan-ju-pei-zhi-wen-jian-etc-systemd-resolved-conf&quot;&gt;systemd-resolved 全局配置文件 (&#x2F;etc&#x2F;systemd&#x2F;resolved.conf):&lt;&#x2F;h2&gt;
&lt;p&gt;可以作为备用或全局覆盖，使用 DNS= 选项：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;ini&quot; class=&quot;language-ini &quot;&gt;&lt;code class=&quot;language-ini&quot; data-lang=&quot;ini&quot;&gt;[Resolve]
DNS=9.9.9.9 2620:fe::fe # 例如 Quad9 DNS
FallbackDNS=8.8.8.8 2001:4860:4860::8888 # 备用 Google DNS
Domains=~example.com # 搜索域
#DNSSEC=yes # 可选 DNSSEC 配置
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;重要： 接口特定配置（来自 systemd-networkd 或 NetworkManager）优先级高于 全局 resolved.conf 中的配置。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;dhcp-ke-hu-duan-ji-cheng&quot;&gt;DHCP 客户端集成:&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;当网络接口通过 DHCP 获取 IP 地址时，DHCP 服务器通常会同时提供 DNS 服务器地址。&lt;&#x2F;li&gt;
&lt;li&gt;systemd-networkd 或 NetworkManager 的 DHCP 客户端模块会自动捕获这些 DNS 信息，并将其作为该接口的 DNS 配置提供给 systemd-resolved。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;vpn-huo-te-shu-wang-luo-jie-kou&quot;&gt;VPN 或特殊网络接口:&lt;&#x2F;h2&gt;
&lt;p&gt;当连接 VPN（如 OpenVPN, WireGuard）或使用特殊接口（如 PPPoE）时：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;VPN 客户端或接口管理器会动态添加其特定的 DNS 服务器地址到 systemd-resolved 中（通常通过 D-Bus API）。&lt;&#x2F;li&gt;
&lt;li&gt;systemd-resolved 知道这些 DNS 服务器仅适用于通过该 VPN&#x2F;接口路由的流量。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;linux-dnscha-xun-ru-he-dao-da-zhen-zheng-de-shang-you-dns&quot;&gt;linux dns查询如何到达真正的上游 DNS？&lt;&#x2F;h1&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;应用程序发起查询： 浏览器等 App 请求 www.example.com。&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;查询发送到 stub： 根据 &#x2F;etc&#x2F;resolv.conf (指向 127.0.0.53)，查询被发送到本机 systemd-resolved 服务。&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;systemd-resolved 处理：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;检查本地缓存（如有缓存且有效，直接返回结果）。&lt;&#x2F;li&gt;
&lt;li&gt;检查是否属于 LLMNR&#x2F;mDNS 域名（如 .local），如果是则在本地链路处理。&lt;&#x2F;li&gt;
&lt;li&gt;判断查询应使用哪个网络接口的上游 DNS (基于源接口、路由策略、域名后缀匹配)。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;转发到上游 DNS： systemd-resolved 将查询转发给为该接口&#x2F;域配置的真正上游 DNS 服务器（如 192.168.1.1 或 9.9.9.9）。&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;支持协议：传统 UDP&#x2F;TCP DNS，或加密的 DNS-over-TLS (DoT) &#x2F; DNS-over-HTTPS (DoH)（需配置）。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;接收并处理响应：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;接收上游 DNS 返回的响应。&lt;&#x2F;li&gt;
&lt;li&gt;可选进行 DNSSEC 验证（若配置）。&lt;&#x2F;li&gt;
&lt;li&gt;将响应结果缓存（根据记录的 TTL）。&lt;&#x2F;li&gt;
&lt;li&gt;将最终结果返回给发起查询的应用程序。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>使用tshark进行pcap和pcapng的转换</title>
        <published>2025-08-12T18:53:51+08:00</published>
        <updated>2025-08-12T18:53:51+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/08/pcap和pcapng的转换/"/>
        <id>https://vercel.juzhong.xyz/2025/08/pcap和pcapng的转换/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/08/pcap和pcapng的转换/">&lt;h1 id=&quot;tshark-jian-jie&quot;&gt;tshark 简介&lt;&#x2F;h1&gt;
&lt;p&gt;tshark就是wireshark的命令行之一。WireShark的功能基本都有，还能组合grep&#x2F;awk等编程处理分析抓包文件。&lt;&#x2F;p&gt;
&lt;p&gt;TShark是一个网络分析工具。它能帮你在实时网络中捕获数据包，或是从预先保存好的捕获文件中读取数据包，或是打印出这些数据包的解码形式到标准输出，再或是把数据包写入到一个文件中。TShark的本地捕获文件格式是pcapng格式，这种pcapng格式也被wireshark和多种其他工具使用。&lt;&#x2F;p&gt;
&lt;p&gt;Wireshark除了能够手动的分析报文之外，还额外的提供了几个命令行工具，方便开发者日常的报文处理需求，比如批量的合并以及编辑报文。这几个命令都是安装wireshark之后能够直接使用的，同时有的有对应的wireshark GUI 的操作。这些命令分别有tshark、tcpdump、capinfos、dumpcap、text2cap、editcap、reordercap、rawshark、mergecap、pcapfix(需单独安装)。&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;tshark：基于终端的Wireshark&lt;&#x2F;li&gt;
&lt;li&gt;tcpdump：使用“tcpdump”捕获以便使用Wireshark查看&lt;&#x2F;li&gt;
&lt;li&gt;dumpcap：捕获“dumpcap”以便使用Wireshark查看&lt;&#x2F;li&gt;
&lt;li&gt;capinfos：打印有关捕获文件的信息&lt;&#x2F;li&gt;
&lt;li&gt;rawshark：转储和分析网络流量。&lt;&#x2F;li&gt;
&lt;li&gt;editcap：编辑捕获文件&lt;&#x2F;li&gt;
&lt;li&gt;mergecap：将多个捕获文件合并为一个&lt;&#x2F;li&gt;
&lt;li&gt;text2pcap：将ASCII hexdumps转换为网络捕获&lt;&#x2F;li&gt;
&lt;li&gt;reordercap：重新排序捕获文件&lt;&#x2F;li&gt;
&lt;li&gt;pcapfix: 修复pcap文件&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;pcap&quot;&gt;pcap&lt;&#x2F;h1&gt;
&lt;p&gt;Wireshark默认的存储方式是pcap格式，最新版本的wireshark默认存储方式是pcapng。ng是next generation 的缩写，pcap和pcapng格式文件有是存在一定的差异。&lt;&#x2F;p&gt;
&lt;p&gt;pcap报文文件结构示意图 https:&#x2F;&#x2F;img1.kiosk007.top&#x2F;static&#x2F;images&#x2F;tshark&#x2F;pcap_file_format.png&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Global Header是整个文件的文件头，包含文件格式标识，pcap格式版本号等文件指示信息。&lt;&#x2F;li&gt;
&lt;li&gt;Packet Header是每一片数据报文的头部信息，这些信息都是在形成pcap 报文的过程中由抓包软件wireshark添加的额外信息，例如报文捕获时间等。&lt;&#x2F;li&gt;
&lt;li&gt;Packet Data是抓取通信过程中的实际数据，包括协议数据和内容数据。&lt;&#x2F;li&gt;
&lt;li&gt;Wireshark 中对 Global Header 的定义&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;c&quot; class=&quot;language-c &quot;&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;typedef struct pcap_hdr_s {
    guint32 magic_number;   &amp;#x2F;* magic number *&amp;#x2F;
    guint16 version_major;  &amp;#x2F;* major version number *&amp;#x2F;
    guint16 version_minor;  &amp;#x2F;* minor version number *&amp;#x2F;
    gint32  thiszone;       &amp;#x2F;* GMT to local correction *&amp;#x2F;
    guint32 sigfigs;        &amp;#x2F;* accuracy of timestamps *&amp;#x2F;
    guint32 snaplen;        &amp;#x2F;* max length of captured packets, in octets *&amp;#x2F;
    guint32 network;        &amp;#x2F;* data link type *&amp;#x2F;
} pcap_hdr_t;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Wireshark 中对 Packet Header 的定义&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;c&quot; class=&quot;language-c &quot;&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;typedef struct pcaprec_hdr_s {
    guint32 ts_sec;         &amp;#x2F;* timestamp seconds *&amp;#x2F;
    guint32 ts_usec;        &amp;#x2F;* timestamp microseconds *&amp;#x2F;
    guint32 incl_len;       &amp;#x2F;* number of octets of packet saved in file *&amp;#x2F;
    guint32 orig_len;       &amp;#x2F;* actual length of packet *&amp;#x2F;
} pcaprec_hdr_t;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;tshark-zhuan-huan-pcapng-wei-pcap&quot;&gt;tshark 转换pcapng 为pcap&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;tshark -F pcap -r origin.pcapng -w output.pcap
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;tshark-zhong-de-chang-yong-can-shu&quot;&gt;tshark 中的常用参数&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;-o ${key:value} : 配置首选项中的settings, 一般可配置显示时间戳、是否相关seq number，或者TLS、WPA 解密等。
&lt;img src=&quot;https:&#x2F;&#x2F;vercel.juzhong.xyz&#x2F;2025&#x2F;08&#x2F;pcap%E5%92%8Cpcapng%E7%9A%84%E8%BD%AC%E6%8D%A2&#x2F;2025-08-13-09-43-10.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;li&gt;
&lt;li&gt;-z ${statistics} : 集各种类型的统计信息, 这里面有一些信息是很有用的，如专家信息、时序统计飞行中的报文、时序丢包都需要这个参数
&lt;img src=&quot;https:&#x2F;&#x2F;vercel.juzhong.xyz&#x2F;2025&#x2F;08&#x2F;pcap%E5%92%8Cpcapng%E7%9A%84%E8%BD%AC%E6%8D%A2&#x2F;2025-08-13-09-45-04.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;其他参数介绍&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text &quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;# 抓包接口类
-i 设置抓包的网络接口，不设置则默认为第一个非自环接口。
-D 列出当前存在的网络接口。在不了解OS所控制的网络设备时，一般先用“tshark -D”查看网络接口的编号以供-i参数使用。
-f 设定抓包过滤表达式（capture filter expression）。抓包过滤表达式的写法雷同于tcpdump
-s 设置每个抓包的大小，默认为65535，多于这个大小的数据将不会被程序记入内存、写入文件
-p 设置网络接口以非混合模式工作，即只关心和本机有关的流量

# 停止抓包参数
-c 抓取的packet数，在处理一定数量的packet后，停止抓取，程序退出。
-a 设置tshark抓包停止向文件书写的条件，事实上是tshark在正常启动之后停止工作并返回的条件。条件写为test:value的形式，如“-a duration:5”表示tshark启动后在5秒内抓包然后停止；“-a filesize:10”表示tshark在输出文件达到10kB后停止；“-a files:n”表示tshark在写满n个文件后停止。

# 处理类
-R 设置读取（显示）过滤表达式（read filter expression）。不符合此表达式的流量同样不会被写入文件。
-n 禁止所有地址名字解析（默认为允许所有）。
-N 启用某一层的地址名字解析。“m”代表MAC层，“n”代表网络层，“t”代表传输层，“C”代表当前异步DNS查找。如果-n和-N参数同时存在，-n将被忽略。如果-n和-N参数都不写，则默认打开所有地址名字解析。
-d 将指定的数据按有关协议解包输出。如要将tcp 8888端口的流量按http解包，应该写为“-d tcp.port==8888,http”。注意选择子和解包协议之间不能留空格。

# 输出类
-w 设置raw数据的输出文件。这个参数不设置，tshark将会把解码结果输出到stdout。“-w-”表示把raw输出到stdout。如果要把解码结果输出到文件，使用重定向“&amp;gt;”而不要-w参数。
-F 设置输出raw数据的格式，默认为libpcap。“tshark -F”会列出所有支持的raw格式。
-V 设置将解码结果的细节输出，否则解码结果仅显示一个packet一行的summary。
-x 设置在解码输出结果中，每个packet后面以HEX dump的方式显示具体数据。
-T 设置解码结果输出的格式，包括text,ps,psml和pdml，默认为text。
-E: -E &amp;lt;fieldsoption&amp;gt;=&amp;lt;value&amp;gt;如果-T fields选项指定，使用-E来设置一些属性，比如
　　　　header=y|n
　　　　separator=&amp;#x2F;t|&amp;#x2F;s|&amp;lt;char&amp;gt;
　　　　occurrence=f|l|a
　　　　aggregator=,|&amp;#x2F;s|&amp;lt;char&amp;gt;
-t 设置解码结果的时间格式。“ad”表示带日期的绝对时间，“a”表示不带日期的绝对时间，“r”表示从第一个包到现在的相对时间，“d”表示两个相邻包之间的增量时间（delta）。
-S 在向raw文件输出的同时，将解码结果打印到控制台。
-l 在处理每个包时即时刷新输出。
-X 扩展项。
-q 设置安静的stdout输出（例如做统计时）
-z 设置统计参数。

# 其他
-h 显示命令行帮助。
-v 显示tshark的版本信息。
-o 重载选项
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;tshark-da-yin-pcap&quot;&gt;tshark 打印pcap&lt;&#x2F;h1&gt;
&lt;p&gt;我们通过tcpdump或者wireshark抓到 pcap 文件，接下来就可以利用 tshark 这个强大的命令行工具进行抓包。其中 -o的几个选项可以指定 ssl 解密（需要sslkeylog），-T 指定输出格式，-e 指定都需要输出哪些字段（字段列表参考 https:&#x2F;&#x2F;www.wireshark.org&#x2F;docs&#x2F;dfref&#x2F;）。输出是将每个Package中指定的字段输出。&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;tshark -o ssl.keylog_file:.&amp;#x2F;sslkeylog.txt \
-o &amp;quot;ssl.desegment_ssl_records: TRUE&amp;quot; \
-o &amp;quot;ssl.desegment_ssl_application_data: TRUE&amp;quot; \
-e ssl.handshake.ciphersuite \  
-e tcp.analysis.zero_window \
-e http.host \
-e dns.time \
-e tcp.flags.urg \
-e http.request.line \
-e dns.qry.name \
-e ip.version \
-e tcp.analysis.window_full \
-e ipv6.dst \
-e http.request.version \
-e udp.dstport \
-e dns.flags.response \
.... \
-T json -r &amp;quot;.&amp;#x2F;capturedump.pcap&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;其他样例&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&amp;#x2F;&amp;#x2F;打印http协议流相关信息
tshark -s 512 -i eth0 -n -f &amp;#x27;tcp dst port 80&amp;#x27; -Y &amp;#x27;http.host and http.request.uri&amp;#x27; -T fields -e http.host -e http.request.uri -l
&amp;#x2F;&amp;#x2F;实时打印当前mysql查询语句
tshark -s 512 -i eth0 -n -f &amp;#x27;tcp dst port 3306&amp;#x27; -Y &amp;#x27;mysql.query&amp;#x27; -T fields -e mysql.query
&amp;#x2F;&amp;#x2F;解析MySQL协议
tshark -r .&amp;#x2F;mysql-compress.cap -o tcp.calculate_timestamps:true \
-T fields -e mysql.caps.cp -e frame.number \
-e frame.time_epoch  -e frame.time_delta_displayed  \
-e ip.src -e tcp.srcport -e tcp.dstport -e ip.dst \
-e tcp.time_delta -e frame.time_delta_displayed \
-e tcp.stream -e tcp.len -e mysql.query
&amp;#x2F;&amp;#x2F;抓取详细SQL语句, 快速确认client发过来的具体SQL内容：
sudo tshark -i any -f &amp;#x27;port 3306&amp;#x27; -s 0 -l -w - |strings
sudo tshark -i eth0 -d tcp.port==3306,mysql -T fields -e mysql.query &amp;#x27;port 3306&amp;#x27;
dfaf
sudo tshark -i eth0 -Y &amp;quot;ip.addr==11.163.182.137&amp;quot; -d tcp.port==3306,mysql -T fields -e mysql.query &amp;#x27;port 3306&amp;#x27;
sudo tshark -i eth0 -Y &amp;quot;tcp.srcport==62877&amp;quot; -d tcp.port==3001,mysql -T fields -e tcp.srcport -e mysql.query &amp;#x27;port 3001&amp;#x27;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;cha-kan-qing-qiu-mu-biao-xin-xi&quot;&gt;查看请求目标信息&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;tshark -r wechat.pcap -o &amp;#x27;gui.column.format:&amp;quot;Source Net Addr&amp;quot;,&amp;quot;%uns&amp;quot;,&amp;quot;Dest Net Addr&amp;quot;, &amp;quot;%und&amp;quot;&amp;#x27; -Y &amp;quot;ip&amp;quot; | sort | uniq
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;cha-kan-diu-bao-dai-kuan-tun-tu-yan-chi&quot;&gt;查看丢包、带宽、吞吐、延迟&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&amp;#x2F;&amp;#x2F; 统计 ip 情况
tshark -r wechat.pcap -q -z conv,ip

&amp;#x2F;&amp;#x2F; 跟踪一条流打印 16进制数据
tshark -r wechat.pcap -q -z &amp;quot;follow,tcp,hex,0&amp;quot; 
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;ji-suan-diu-bao-qing-kuang&quot;&gt;计算丢包情况&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;tshark -r wechat.pcap -q \
 -z io,stat,1,&amp;quot;COUNT(tcp.analysis.retransmission) tcp.analysis.retransmission&amp;quot;,&amp;quot;COUNT(tcp.analysis.fast_retransmission) tcp.analysis.fast_retransmission&amp;quot;,&amp;quot;COUNT(tcp.analysis.duplicate_ack) tcp.analysis.duplicate_ack&amp;quot;,&amp;quot;COUNT(tcp.analysis.lost_segment) tcp.analysis.lost_segment&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;ji-suan-shang-xing-dai-kuan&quot;&gt;计算上行带宽&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;tshark -o tcp.desegment_tcp_streams:TRUE -n \
  -q -r  .&amp;#x2F;wechat.pcap \
  -z io,stat,99999999,&amp;quot;BYTES()(ip.src!=10.0.0.0&amp;#x2F;8 and ip.src!=172.16.0.0&amp;#x2F;12 and ip.src!=192.168.0.0&amp;#x2F;16)&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;ji-suan-tcp-rtt&quot;&gt;计算 TCP RTT&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;tshark -o tcp.desegment_tcp_streams:TRUE -n \
  -q -r  .&amp;#x2F;wechat.pcap  -z \
  io,stat,99999999,&amp;quot;AVG(tcp.analysis.ack_rtt)tcp.analysis.ack_rtt&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;fen-xi-tcp-stream-id-wei-0-de-chuan-shu-dai-kuan&quot;&gt;分析 tcp.stream id 为 0 的传输带宽&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;tshark -o tcp.desegment_tcp_streams:FALSE -n \
  -q -r wechat.pcapng -z io,stat,1,&amp;quot;BYTES()tcp.stream==0&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;kiosk007.top&#x2F;post&#x2F;%E7%8E%A9%E8%BD%AC-tshark-%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%B7%A5%E5%85%B7&#x2F;&quot;&gt;玩转tshark命令行工具&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>dns报文格式</title>
        <published>2025-08-12T15:11:42+08:00</published>
        <updated>2025-08-12T15:11:42+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/08/dns报文格式/"/>
        <id>https://vercel.juzhong.xyz/2025/08/dns报文格式/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/08/dns报文格式/">&lt;h1 id=&quot;dnsbao-wen-ge-shi&quot;&gt;DNS报文格式&lt;&#x2F;h1&gt;
&lt;p&gt;经过前面学习，我们知道查询一个域名，需要与 DNS 服务器进行通信。那么，DNS 通信过程大概是怎样的呢？&lt;&#x2F;p&gt;
&lt;p&gt;DNS 是一个典型的 Client-Server 应用，客户端发起域名查询请求，服务端对请求进行应答：&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;vercel.juzhong.xyz&#x2F;2025&#x2F;08&#x2F;dns%E6%8A%A5%E6%96%87%E6%A0%BC%E5%BC%8F&#x2F;assets&#x2F;network-asset-ba987b1fa1b0168df88331eee7bfa7e058a4cfb6-20250812133907-y57418z.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;DNS 一般采用 UDP 作为传输层协议（ TCP 亦可），端口号是 53 。请求报文和应答报文均作为数据，搭载在 UDP 数据报中进行传输：&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;vercel.juzhong.xyz&#x2F;2025&#x2F;08&#x2F;dns%E6%8A%A5%E6%96%87%E6%A0%BC%E5%BC%8F&#x2F;assets&#x2F;network-asset-4e9f63a16c60af3fc49a951154a2f3d2c0f21f98-20250812133908-fajlv1b.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;很显然，DNS 请求报文和应答报文均需要满足一定的格式，才能被通信双方所理解。这就是 DNS 协议负责的范畴，它位于传输层之上，属于 &lt;strong&gt;应用层&lt;&#x2F;strong&gt; 协议。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bao-wen-ge-shi&quot;&gt;报文格式&lt;&#x2F;h2&gt;
&lt;p&gt;DNS 报文分为 &lt;strong&gt;请求&lt;&#x2F;strong&gt; 和 &lt;strong&gt;应答&lt;&#x2F;strong&gt; 两种，结构是类似的，大致分为五部分：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;头部（ &lt;em&gt;header&lt;&#x2F;em&gt; ），描述报文类型，以及其下 4 个小节的情况；&lt;&#x2F;li&gt;
&lt;li&gt;问题节（ &lt;em&gt;question&lt;&#x2F;em&gt; ），保存查询问题；&lt;&#x2F;li&gt;
&lt;li&gt;答案节（ &lt;em&gt;answer&lt;&#x2F;em&gt; ），保存问题答案，也就是查询结果；&lt;&#x2F;li&gt;
&lt;li&gt;授权信息节（ &lt;em&gt;authority&lt;&#x2F;em&gt; ），保存授权信息；&lt;&#x2F;li&gt;
&lt;li&gt;附加信息节（ &lt;em&gt;additional&lt;&#x2F;em&gt; ），保存附加信息；&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote&gt;
&lt;p&gt;也有不少文献将 DNS 请求称为 DNS ​&lt;strong&gt;查询&lt;&#x2F;strong&gt;​（ query ），两者是一个意思。&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;vercel.juzhong.xyz&#x2F;2025&#x2F;08&#x2F;dns%E6%8A%A5%E6%96%87%E6%A0%BC%E5%BC%8F&#x2F;assets&#x2F;network-asset-bb5146dfd61519aebc02722d4e62acaa1aba94e0-20250812133909-zzh3tol.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;其中，头部是固定的，共 12 字节；其他节不固定，记录数可多可少，数目保存在头部中。头部分为 6 个字段：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;​&lt;strong&gt;标识&lt;&#x2F;strong&gt;​（ &lt;em&gt;identifier&lt;&#x2F;em&gt; ），一个 16 位的 ID ，在应答中原样返回，以此匹配请求和应答；&lt;&#x2F;li&gt;
&lt;li&gt;​&lt;strong&gt;标志&lt;&#x2F;strong&gt;​（ &lt;em&gt;flags&lt;&#x2F;em&gt; ），一些标志位，共 16 位；&lt;&#x2F;li&gt;
&lt;li&gt;​&lt;strong&gt;问题记录数&lt;&#x2F;strong&gt;​（ &lt;em&gt;question count&lt;&#x2F;em&gt; ），一个 16 位整数，表示问题节中的记录个数；&lt;&#x2F;li&gt;
&lt;li&gt;​&lt;strong&gt;答案记录数&lt;&#x2F;strong&gt;​（ &lt;em&gt;answer count&lt;&#x2F;em&gt; ），一个 16 位整数，表示答案节中的记录个数；&lt;&#x2F;li&gt;
&lt;li&gt;​&lt;strong&gt;授权信息记录数&lt;&#x2F;strong&gt;​（ &lt;em&gt;authority record count&lt;&#x2F;em&gt; ），一个 16 位整数，表示授权信息节中的记录个数；&lt;&#x2F;li&gt;
&lt;li&gt;​&lt;strong&gt;附加信息记录数&lt;&#x2F;strong&gt;​（ &lt;em&gt;additional record count&lt;&#x2F;em&gt; ），一个 16 位整数，表示附加信息节中的记录个数；&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;最后，我们来解释一下标志字段中的各个标志位：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;QR 位标记报文是一个查询请求，还是查询应答；&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;0 表示查询请求；&lt;&#x2F;li&gt;
&lt;li&gt;1 表示查询应答；&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;​&lt;strong&gt;操作码&lt;&#x2F;strong&gt;​（ &lt;em&gt;opcode&lt;&#x2F;em&gt; ）占 4 位，表示操作类型：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;0 代表标准查询；&lt;&#x2F;li&gt;
&lt;li&gt;1 代表反向查询；&lt;&#x2F;li&gt;
&lt;li&gt;2 代表服务器状态请求；&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;AA 位表示 ​&lt;strong&gt;权威回答&lt;&#x2F;strong&gt;​（ &lt;em&gt;authoritative answer&lt;&#x2F;em&gt; ），意味着当前查询结果是由域名的权威服务器给出的；&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;TC 位表示 ​&lt;strong&gt;截短&lt;&#x2F;strong&gt;​（ &lt;em&gt;truncated&lt;&#x2F;em&gt; ），使用 UDP 时，如果应答超过 512 字节，只返回前 512 个字节；&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;RD 位表示 &lt;strong&gt;期望递归&lt;&#x2F;strong&gt; （ &lt;em&gt;recursion desired&lt;&#x2F;em&gt; ），在请求中设置，并在应答中返回；&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;该位为 1 时，服务器必须处理这个请求：如果服务器没有授权回答，它必须替客户端请求其他 DNS 服务器，这也是所谓的 &lt;strong&gt;递归查询&lt;&#x2F;strong&gt; ；&lt;&#x2F;li&gt;
&lt;li&gt;该位为 0 时，如果服务器没有授权回答，它就返回一个能够处理该查询的服务器列表给客户端，由客户端自己进行 &lt;strong&gt;迭代查询&lt;&#x2F;strong&gt; ；&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;RA 位表示可递归（ &lt;em&gt;recursion available&lt;&#x2F;em&gt; ），如果服务器支持递归查询，就会在应答中设置该位，以告知客户端；&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;保留位，这 3 位目前未用，留作未来扩展；&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;​&lt;strong&gt;响应码&lt;&#x2F;strong&gt;​（ &lt;em&gt;response code&lt;&#x2F;em&gt; ）占 4 位，表示请求结果，常见的值包括：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;0 表示没有差错；&lt;&#x2F;li&gt;
&lt;li&gt;3 表示名字差错，该差错由权威服务器返回，表示待查询的域名不存在；&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;wen-ti-ji-lu&quot;&gt;问题记录&lt;&#x2F;h2&gt;
&lt;p&gt;客户端查询域名时，需要向服务端发送请求报文；待查询域名作为问题记录，保存在问题节中。&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;vercel.juzhong.xyz&#x2F;2025&#x2F;08&#x2F;dns%E6%8A%A5%E6%96%87%E6%A0%BC%E5%BC%8F&#x2F;assets&#x2F;network-asset-4e3499436f3827644b71c9e392e2e5462cad6402-20250812133909-zdov2bk.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;问题节支持保存多条问题记录，记录条数则保存在 DNS 头部中的问题记录数字段。这意味着，DNS 协议单个请求能够同时查询多个域名，虽然通常只查询一个。&lt;&#x2F;p&gt;
&lt;p&gt;一个问题记录由 3 个字段组成：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;​&lt;strong&gt;待查询域名&lt;&#x2F;strong&gt;​（ Name ），这个字段长度不固定，由具体域名决定；&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;​&lt;strong&gt;查询类型&lt;&#x2F;strong&gt;​（ Type ），域名除了关联 IP 地址，还可以关联其他信息，常见类型包括（下节详细介绍）：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;1 表示 A 记录，即 IP 地址；&lt;&#x2F;li&gt;
&lt;li&gt;28 表示 AAAA 记录，即 IPv6 地址；&lt;&#x2F;li&gt;
&lt;li&gt;etc&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;类&lt;&#x2F;strong&gt; （ Class ）通常为 1 ，表示 TCP&#x2F;IP 互联网地址；&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;最后，我们回过头来考察域名字段，它的长度是不固定的。域名按 &lt;code&gt;.&lt;&#x2F;code&gt;​ 切分成若干部分，再依次保存。每个部分由一个前导计数字节开头，记录当前部分的字符数。&lt;&#x2F;p&gt;
&lt;p&gt;以域名 &lt;code&gt;fasionchan.com.&lt;&#x2F;code&gt;​ 为例，以 &lt;code&gt;.&lt;&#x2F;code&gt;​ 切分成 3 个部分，&lt;code&gt;fasionchan&lt;&#x2F;code&gt;​ 、&lt;code&gt;com&lt;&#x2F;code&gt;​ 以及空字符串  。请注意，空字符串  代表根域。因此，待查询域名字段依次为：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;一个前导字节保存整数 10 ，然后 10 个字节保存 &lt;code&gt;fasionchan&lt;&#x2F;code&gt;​ 部分（二级域）；&lt;&#x2F;li&gt;
&lt;li&gt;一个前导字节保存整数 3 ，然后 3 个字节保存 &lt;code&gt;com&lt;&#x2F;code&gt;​ 部分（一级域）；&lt;&#x2F;li&gt;
&lt;li&gt;一个前导字节保存整数 0 ，然后 0 个字节保存 &lt;code&gt; &lt;&#x2F;code&gt;​ 部分（根域）；&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;由此可见，每一级域名的长度理论上可以支持多达 255 个字符。&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;查询类型&lt;&#x2F;th&gt;&lt;th&gt;名称代码&lt;&#x2F;th&gt;&lt;th&gt;描述&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;A&lt;&#x2F;td&gt;&lt;td&gt;IPv4地址&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;NS&lt;&#x2F;td&gt;&lt;td&gt;名称服务器&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;CNAME&lt;&#x2F;td&gt;&lt;td&gt;规范名称&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;15&lt;&#x2F;td&gt;&lt;td&gt;MX&lt;&#x2F;td&gt;&lt;td&gt;电子邮件交互&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;16&lt;&#x2F;td&gt;&lt;td&gt;TXT&lt;&#x2F;td&gt;&lt;td&gt;文本信息&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;28&lt;&#x2F;td&gt;&lt;td&gt;AAAA&lt;&#x2F;td&gt;&lt;td&gt;IPv6地址&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;查询类型这里先不展开，下一小节会详细介绍。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zi-yuan-ji-lu&quot;&gt;资源记录&lt;&#x2F;h2&gt;
&lt;p&gt;服务端处理查询请求后，需要向客户端发送应答报文；域名查询结果作为资源记录，保存在答案以及其后两节中。&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;vercel.juzhong.xyz&#x2F;2025&#x2F;08&#x2F;dns%E6%8A%A5%E6%96%87%E6%A0%BC%E5%BC%8F&#x2F;assets&#x2F;network-asset-d9cdce4af72ec74a5795f1215be063c59253b883-20250812133910-ti3aoer.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;答案节、授权信息节和附加信息节均由一条或多条资源记录组成，记录数目保存在头部中的对应字段，不再赘述。&lt;&#x2F;p&gt;
&lt;p&gt;资源记录结构和问题记录非常相似，它总共有 6 个字段，前 3 个和问题记录完全一样：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;​&lt;strong&gt;被查询域名&lt;&#x2F;strong&gt;​（ Name ），与问题记录相同；&lt;&#x2F;li&gt;
&lt;li&gt;​&lt;strong&gt;查询类型&lt;&#x2F;strong&gt;​（ Type ），与问题记录相同；&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;类&lt;&#x2F;strong&gt; （ Class ），与问题记录相同；&lt;&#x2F;li&gt;
&lt;li&gt;​&lt;strong&gt;有效期&lt;&#x2F;strong&gt;​（ TTL ），域名记录一般不会频繁改动，所以在有效期内可以将结果缓存起来，降低请求频率；&lt;&#x2F;li&gt;
&lt;li&gt;​&lt;strong&gt;数据长度&lt;&#x2F;strong&gt;​（ Resource Data Length ），即查询结果的长度；&lt;&#x2F;li&gt;
&lt;li&gt;​&lt;strong&gt;数据&lt;&#x2F;strong&gt;​（ Resource Data ），即查询结果；&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;如果查询类型是 A 记录，那查询结果就是一个 IP 地址，保存于资源记录中的数据字段；而数据长度字段值为 4 ，因为 IP 地址的长度为 32 位，折合 4 字节。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bao-wen-shi-li&quot;&gt;报文实例&lt;&#x2F;h2&gt;
&lt;p&gt;我们以 &lt;code&gt;test.fasionchan.com&lt;&#x2F;code&gt;​ 这个域名为例，来讲解 DNS 查询请求报文和应答报文。&lt;&#x2F;p&gt;
&lt;p&gt;执行 dig 命令即可查询该域名：&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;dig test.fasionchan.com
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;我们对查询 &lt;code&gt;test.fasionchan.com&lt;&#x2F;code&gt;​ 的一次通信过程进行抓包，结果保存在 &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;coding-fans&#x2F;netcode&#x2F;blob&#x2F;master&#x2F;pcap&#x2F;dns-resolve.pcap&quot;&gt;Github&lt;&#x2F;a&gt; 上，以供参考。童鞋们可以将抓包结果下载到本地，并用 WireShark 打开，并结合讲解进行分析。&lt;&#x2F;p&gt;
&lt;h3 id=&quot;qing-qiu-bao-wen&quot;&gt;请求报文&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;vercel.juzhong.xyz&#x2F;2025&#x2F;08&#x2F;dns%E6%8A%A5%E6%96%87%E6%A0%BC%E5%BC%8F&#x2F;assets&#x2F;network-asset-47d303ddf3f009f21c2311fa6380d530ef7647be-20250812133910-jqdtbeb.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;抓包结果请求报文只有头部、问题节和附加节，图解假设没有附加节。&lt;&#x2F;p&gt;
&lt;p&gt;先看头部，问题记录数为 1 ，其他记录数都是 0 。这意味着，请求报文只有问题节，而且问题节中只有一条问题记录，只查询一个域名。头部中的标志位分别如下：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;QR=0 ，表示该报文是一个请求报文；&lt;&#x2F;li&gt;
&lt;li&gt;操作码为 0 ，表示这个 DNS 请求是一个标准请求；&lt;&#x2F;li&gt;
&lt;li&gt;TC=0 ，表示请求报文没有被截短；&lt;&#x2F;li&gt;
&lt;li&gt;RD=1 ，表示客户端希望服务器可以执行递归查询；&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;问题记录我们已经很熟悉了，不再赘述：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Type=1 ，表示客户端希望查询 A 记录，即与域名关联的 IP 地址；&lt;&#x2F;li&gt;
&lt;li&gt;Class=1 ，代表 TCP&#x2F;IP 互联网；&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;ying-da-bao-wen&quot;&gt;应答报文&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;vercel.juzhong.xyz&#x2F;2025&#x2F;08&#x2F;dns%E6%8A%A5%E6%96%87%E6%A0%BC%E5%BC%8F&#x2F;assets&#x2F;network-asset-8d0bc56b7cc6375c38d9ae45907f4bb330a674a7-20250812133910-p4oredg.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;抓包结果应答报文只有头部、问题节和答案节。其中，问题节中的问题记录与请求报文一样，图中就不展开了。&lt;&#x2F;p&gt;
&lt;p&gt;先看头部，问题记录数为 1 ，答案记录数也是 1 ，其他记录数都是 0 。这意味着，应答报文只有问题节和答案节，而且它们各自只有一条记录。头部中的标志位分别如下：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;QR=1 ，表示该报文是一个应答报文；&lt;&#x2F;li&gt;
&lt;li&gt;操作码为 0 ，表示这个 DNS 请求是一个标准请求；&lt;&#x2F;li&gt;
&lt;li&gt;AA=0 ，表示结果不是由域名的权威服务器返回的，因为查询对象是本地的 DNS 缓存服务器（如果是向权威服务器发起查询，它返回的应答报文 AA=1 ）；&lt;&#x2F;li&gt;
&lt;li&gt;TC=0 ，表示应答报文没有被截短；&lt;&#x2F;li&gt;
&lt;li&gt;RD=1 ，与请求报文保持一致，略；&lt;&#x2F;li&gt;
&lt;li&gt;RA=1 ，表示服务端支持递归查询；&lt;&#x2F;li&gt;
&lt;li&gt;响应码为 0 ，表示查询成功，没有出错；&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;答案节中的资源记录就是查询结果，前 3 个字段与问题记录一样，不再赘述。&lt;&#x2F;p&gt;
&lt;p&gt;TTL 字段是一个整数，表示有效期，单位是秒。例子中的查询结果，有效期是752秒，即 12 分 32 秒。也就是说，查询结果从现在开始算，12分32秒内均有效，无须重新请求。&lt;&#x2F;p&gt;
&lt;p&gt;查询结果是一个 IP 地址，长度为 4 个字节，保存在资源数据字段中。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;yu-ming-ya-suo&quot;&gt;域名压缩&lt;&#x2F;h2&gt;
&lt;p&gt;我们注意到，应答报文中，会将请求报文中的问题记录原样返回。由于问题记录和资源记录都会保存域名，这意味着域名会被重复保存，而报文尺寸是有限的！&lt;&#x2F;p&gt;
&lt;p&gt;为了节约报文空间，有必要解决域名重复保存问题，这也是所谓的信息压缩。具体做法如下：&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;vercel.juzhong.xyz&#x2F;2025&#x2F;08&#x2F;dns%E6%8A%A5%E6%96%87%E6%A0%BC%E5%BC%8F&#x2F;assets&#x2F;network-asset-cc3443b23ce09285fa308acd14b0a2ad3b5e120f-20250812133910-n7m6acb.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;域名在报文中第二次出现时，只用两个字节来保存。第一个字节最高两位都是 &lt;code&gt;1&lt;&#x2F;code&gt;​ ，余下部分和第二个字节组合在一起，表示域名第一次出现时在报文中的偏移量。通过这个偏移量，就可以找到对应的域名。&lt;&#x2F;p&gt;
&lt;p&gt;由此一来，原来需要 21 个字节来保存的域名，现在只需区区两个字节即可搞定，数据量大大降低！&lt;&#x2F;p&gt;
&lt;p&gt;实际上，域名压缩机制还可以针对域名的某个部分进行。举个例子，假设一个请求报文同时查询两个域名：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;​&lt;code&gt;fasionchan.com&lt;&#x2F;code&gt;​&lt;&#x2F;li&gt;
&lt;li&gt;​&lt;code&gt;test.fasionchan.com&lt;&#x2F;code&gt;​&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;请求报文中包含两个问题记录，分别对应域名 &lt;code&gt;fasionchan.com&lt;&#x2F;code&gt;​ 和 &lt;code&gt;test.fasionchan.com&lt;&#x2F;code&gt;​ 。这两个域名都有一个公共后缀 &lt;code&gt;fasionchan.com&lt;&#x2F;code&gt;​ ，无须重复保存。&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;vercel.juzhong.xyz&#x2F;2025&#x2F;08&#x2F;dns%E6%8A%A5%E6%96%87%E6%A0%BC%E5%BC%8F&#x2F;assets&#x2F;network-asset-ceafe083c60abfa6a0b4882eff59007761dc10bc-20250812133911-0zhti5v.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;如上图，第二个域名只需保存 &lt;code&gt;test&lt;&#x2F;code&gt;​ 部分，然后接两个字节特殊的压缩字节，指向第一个问题记录中的 &lt;code&gt;fasionchan.com&lt;&#x2F;code&gt;​ 。如果两条问题记录顺序颠倒，结果也是类似的，留待童鞋们自行思考。&lt;&#x2F;p&gt;
&lt;h1 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h1&gt;
&lt;p&gt;此文档是一个拷贝&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;fasionchan.com&#x2F;network&#x2F;dns&#x2F;packet-format&#x2F;&quot;&gt;dns格式解析&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>gdb调试信息分离</title>
        <published>2025-08-12T10:19:42+08:00</published>
        <updated>2025-08-12T10:19:42+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/08/gdb调试信息分离/"/>
        <id>https://vercel.juzhong.xyz/2025/08/gdb调试信息分离/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/08/gdb调试信息分离/">&lt;h1 id=&quot;diao-shi-xin-xi-fen-chi&quot;&gt;调试信息分离&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;gdbde-diao-shi-xin-xi-fen-chi-ji-zhi&quot;&gt;GDB的调试信息分离机制&lt;&#x2F;h2&gt;
&lt;p&gt;GDB 允许程序的调试信息和可执行文件分离。当可执行程序出现问题时，GDB 会自动查找和加载调试信息。&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;这种机制的实现原理是，GDB 通过两种方式来指定独立调试信息文件：&lt;&#x2F;li&gt;
&lt;li&gt;一种是可执行文件包含一个调试链接，它会指定独立调试信息文件的名称；&lt;&#x2F;li&gt;
&lt;li&gt;另一种是可执行文件包含一个构建标识符，它是一个唯一的位串，在相应的调试信息文件中也包含这个位串?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;diao-shi-lian-jie-xiang-jie&quot;&gt;调试链接详解&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;调试链接包含两个关键信息：&lt;&#x2F;li&gt;
&lt;li&gt;调试信息文件的名称和 CRC 校验和。
调试信息文件的名称通常为executable.debug，其中executable是相应的可执行文件的名称，不带有前导的目录名，方便查找。
CRC 校验和的目的是为了验证可执行程序和调试文件是否匹配。&lt;&#x2F;li&gt;
&lt;li&gt;在生成调试链接时，会将调试信息文件的名称和 CRC 校验和添加到可执行文件中&lt;&#x2F;li&gt;
&lt;li&gt;当 GDB 调试时，会根据这些信息来查找和加载调试信息。
&lt;ul&gt;
&lt;li&gt;例如，在编译生成release with debug info时，它包含调试信息，然后把它进行调试信息分离，生成一个可执行程序（用a代替）和调试信息文件（用b代替）。&lt;&#x2F;li&gt;
&lt;li&gt;接下来把调试链接做出来，就是在可执行程序a当中，加上一个链接，这个链接信息包含调试信息文件b的名字和 CRC 校验和 。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;yi-redis-wei-li-de-diao-shi-liu-cheng&quot;&gt;以 Redis 为例的调试流程&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;bian-yi-dai-diao-shi-xin-xi-de-ke-zhi-xing-wen-jian&quot;&gt;编译带调试信息的可执行文件&lt;&#x2F;h2&gt;
&lt;p&gt;在编译 Redis 时，我们可以使用-O2或-O3优化选项来优化代码，提高运行效率，同时使用-g选项添加调试信息，-DENDEBUG用于禁用断言（在 Release 版本中通常会禁用断言以提高性能）。&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;make CFLAGS=&amp;quot;-O2 -g -DENDEBUG&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;这样就会生成一个包含调试信息的 Redis 可执行程序，虽然文件大小可能会有所增加，但为后续的调试提供了便利。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zhuan-cun-diao-shi-xin-xi&quot;&gt;转存调试信息&lt;&#x2F;h2&gt;
&lt;p&gt;我们使用objcopy工具将调试信息转存到一个新的文件中。命令如下：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;objcopy --only-keep-debug .&amp;#x2F;src&amp;#x2F;redis-server redis-server.debug
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;这条命令会把.&#x2F;src&#x2F;redis-server中的调试信息提取出来，保存到redis-server.debug文件中。&lt;&#x2F;p&gt;
&lt;p&gt;此时，redis-server.debug装满调试信息，里面包含了变量名、函数名、行号等重要信息。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;qu-chu-ke-zhi-xing-cheng-xu-diao-shi-xin-xi&quot;&gt;去除可执行程序调试信息&lt;&#x2F;h2&gt;
&lt;p&gt;为了得到一个 “干净” 的、不包含调试信息的可执行程序，我们使用strip命令：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;strip .&amp;#x2F;src&amp;#x2F;redis-server -o redis-server
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;经过这一步，redis-server就变成了一个体积更小、运行效率更高的裸可执行程序， 但缺少了调试所需的信息。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tian-jia-diao-shi-lian-jie&quot;&gt;添加调试链接&lt;&#x2F;h2&gt;
&lt;p&gt;最后，我们要为这个裸可执行程序添加调试链接，让它能够找到对应的调试信息文件。使用objcopy命令：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;objcopy --add-gnu-debuglink=redis-server.debug redis-server
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;这条命令会在redis-server中添加一个调试链接，链接到redis-server.debug文件。&lt;&#x2F;p&gt;
&lt;p&gt;此时，redis-server虽然不包含调试信息，但它知道从哪里获取调试信息，为后续的调试做好了准备。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;yong-gdb-diao-shi&quot;&gt;用 GDB 调试&lt;&#x2F;h2&gt;
&lt;p&gt;现在，我们就可以使用 GDB 来调试这个带有调试链接的可执行程序了。&lt;&#x2F;p&gt;
&lt;p&gt;启动 GDB 并加载redis-server：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;gdb redis-server
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;GDB 会自动根据调试链接找到redis-server.debug文件，并加载其中的调试信息。&lt;&#x2F;p&gt;
&lt;p&gt;在 GDB 中，我们可以使用各种调试命令，如设置断点（break）、查看变量值（print）、单步执行（step）等，从而定位和解决程序中的问题。例如，我们可以在某个函数处设置断点，查看程序执行到该点时变量的值，分析程序的执行逻辑是否正确。&lt;&#x2F;p&gt;
&lt;h1 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;mp.weixin.qq.com&#x2F;s&#x2F;kQcDSKG40vWJP4cUvyfgMA&quot;&gt;gdb调试&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>linux wps字体错误修复</title>
        <published>2025-08-11T18:49:58+08:00</published>
        <updated>2025-08-11T18:49:58+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/08/linux wps字体错误修复/"/>
        <id>https://vercel.juzhong.xyz/2025/08/linux wps字体错误修复/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/08/linux wps字体错误修复/">&lt;p&gt;linux 系统中使用wps时， 出现缺失字体的告警&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text &quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;Linux 系统缺失字体：Symbol､Wingdings､Wingdings 2､Wingdings 3､Webdings､MT Extra,WPS无法正确地显示某些符号(公式)！
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2025-08-11-18-53-25.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;cong-windows-xi-tong-ti-qu&quot;&gt;‌从 Windows 系统提取‌&lt;&#x2F;h1&gt;
&lt;p&gt;复制 Windows 系统 C:\Windows\Fonts 目录下的对应字体文件（后缀为 .ttf 或 .ttc）&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text &quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;symbol.ttf  
wingding.ttf  
wingdng2.ttf  (对应 Wingdings 2)  
wingdng3.ttf  (对应 Wingdings 3)  
webdings.ttf  
mtextra.ttf   (对应 MT Extra)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;xia-zai-yu-da-bao-zi-ti-bao-wu-windows-xi-tong-shi&quot;&gt;‌下载预打包字体包（无 Windows 系统时）&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git clone -b windows10 https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;uinv&amp;#x2F;windows-fonts.git &amp;#x2F;tmp&amp;#x2F;usr&amp;#x2F;share&amp;#x2F;fonts&amp;#x2F;windows10-fonts
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;geng-xin-zi-ti-huan-cun&quot;&gt;更新字体缓存&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo mkfontscale    # 生成字体索引
sudo mkfontdir      # 创建字体目录信息
sudo fc-cache -fv   # 强制更新缓存
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;ban-quan-ti-shi&quot;&gt;‌版权提示‌&lt;&#x2F;h1&gt;
&lt;p&gt;Wingdings、MT Extra 等为微软版权字体，仅限个人非商业使用&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>linux ibus输入法chrome输出重复bug</title>
        <published>2025-08-11T16:18:17+08:00</published>
        <updated>2025-08-11T16:18:17+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/08/linux ibus输入法chrome输出重复bug/"/>
        <id>https://vercel.juzhong.xyz/2025/08/linux ibus输入法chrome输出重复bug/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/08/linux ibus输入法chrome输出重复bug/">&lt;h1 id=&quot;ibusshu-ru-fa-yi-chang-xian-xiang&quot;&gt;ibus输入法异常: 现象&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;输入 【weisheme】 后出现重复的【为什么为什么】&lt;&#x2F;li&gt;
&lt;li&gt;其中一个是候选词， 应该是ibus在输出后，没有正确清理候选词导致的？
&lt;img src=&quot;&#x2F;images&#x2F;2025-08-11-16-25-49.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;jie-jue-fang-an&quot;&gt;解决方案&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2025-08-11-16-22-33.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>linux 显示管理器配置</title>
        <published>2025-08-11T14:04:21+08:00</published>
        <updated>2025-08-11T14:04:21+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/08/linux 显示管理器配置/"/>
        <id>https://vercel.juzhong.xyz/2025/08/linux 显示管理器配置/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/08/linux 显示管理器配置/">&lt;h1 id=&quot;cha-kan-dang-qian-de-xian-shi-guan-li-qi&quot;&gt;查看当前的显示管理器&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;echo $XDG_SESSION_TYPE
echo $XDG_CURRENT_DESKTOP
systemctl status display-manager.service
ps -A | grep -E &amp;#x27;(gdm|lightdm|sddm|xdm|lxdm)&amp;#x27;
systemctl --property FragmentPath show display-manager
find &amp;#x2F;etc&amp;#x2F;systemd -name &amp;#x27;display-manager.*&amp;#x27;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;zhong-xin-pei-zhi-xian-shi-guan-li-qi&quot;&gt;重新配置显示管理器&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt install lightdm
sudo dpkg-reconfigure lightdm
sudo systemctl restart display-manager

sudo dpkg-reconfigure gdm3 -f noninteractive
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;cha-kan-lightdm-zhong-de-an-zhuang-jiao-ben&quot;&gt;查看lightdm 中的安装脚本&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;apt download lightdm
ar x lightdm
tar xvf control.tar.xz

dpkg-deb -R lightdm_1.26.0-8_amd64.deb lightdm-files
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;shi-ji-zhi-xing-de-cao-zuo&quot;&gt;实际执行的操作&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo update-alternatives --install &amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;java java &amp;#x2F;opt&amp;#x2F;java 2000
# 这里的数字 2000 是优先级值，数值越高，优先级越高，默认情况下会选择具有最高优先级的备选项
ls &amp;#x2F;var&amp;#x2F;lib&amp;#x2F;alternatives&amp;#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;xiu-fu-cong-kdeqie-huan-dao-gnomehou-zi-ti-da-xiao-mei-you-hui-fu-de-bug&quot;&gt;修复从kde切换到gnome后字体大小没有恢复的bug&lt;&#x2F;h1&gt;
&lt;pre&gt;&lt;code&gt;sudo apt update
sudo apt install gnome-tweaks
gnome-tweaks

# 如果还是没有恢复， 可以使用下面的命令强制reset
dconf reset -f &amp;#x2F;org&amp;#x2F;gnome&amp;#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>fcitx键盘布局 键盘-汉语 的作用</title>
        <published>2025-08-08T13:37:52+08:00</published>
        <updated>2025-08-08T13:37:52+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/08/fcitx键盘布局 键盘-汉语 的作用/"/>
        <id>https://vercel.juzhong.xyz/2025/08/fcitx键盘布局 键盘-汉语 的作用/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/08/fcitx键盘布局 键盘-汉语 的作用/">&lt;p&gt;在fcitx（或 fcitx5-configtool）的配置中看到的 “键盘-汉语” 和 “拼音”，虽然都与中文输入有关，但它们的定位和功能完全不同。我们来逐一解释：&lt;&#x2F;p&gt;
&lt;h1 id=&quot;bulb-wei-shen-me-jian-pan-yi-yu-hui-chu-xian-zai-fcitx-pei-zhi-li&quot;&gt;💡 为什么“键盘-汉语”会出现在 Fcitx 配置里？&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;因为 Fcitx&#x2F;Fcitx5 里，“输入法”概念包含两类：&lt;&#x2F;li&gt;
&lt;li&gt;系统键盘布局（来自 XKB &#x2F; libxkbcommon）&lt;&#x2F;li&gt;
&lt;li&gt;输入法引擎（来自 Fcitx 模块，比如拼音、rime、mozc）&lt;&#x2F;li&gt;
&lt;li&gt;它们在配置界面是统一管理的，所以“键盘-汉语”会和“拼音”一起出现在输入法列表中。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;abc-yi-pin-yin-zhen-zheng-de-zhong-wen-shu-ru-fa-yin-qing&quot;&gt;🔤 一、“拼音” —— 真正的中文输入法引擎&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;white-check-mark-shi-shen-me&quot;&gt;✅ 是什么？&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;“拼音”（Pinyin）是 fcitx 的一个输入法引擎（Input Method Engine）。&lt;&#x2F;li&gt;
&lt;li&gt;它允许你使用 汉语拼音（如 wo ai ni）输入汉字（如“我爱你”）。&lt;&#x2F;li&gt;
&lt;li&gt;它会显示候选词、支持词库、智能联想、模糊音等高级功能。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;white-check-mark-gong-neng-te-dian&quot;&gt;✅ 功能特点：&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;输入拼音 → 候选汉字&lt;&#x2F;li&gt;
&lt;li&gt;支持简体&#x2F;繁体切换&lt;&#x2F;li&gt;
&lt;li&gt;可配置词库、用户词、模糊音（如 z&#x2F;zh 不分）&lt;&#x2F;li&gt;
&lt;li&gt;是你日常“打字”用的输入法&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;white-check-mark-shi-li&quot;&gt;✅ 示例：&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;输入：ni hao&lt;&#x2F;li&gt;
&lt;li&gt;候选：你好&lt;&#x2F;li&gt;
&lt;li&gt;👉 这才是你真正用来“输入中文”的工具。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;keyboard-er-jian-pan-yi-yu-jian-pan-bu-ju-bu-shi-shu-ru-fa&quot;&gt;⌨️ 二、“键盘-汉语” —— 键盘布局，不是输入法&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;shi-shen-me&quot;&gt;❓ 是什么？&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;“键盘-汉语”（有时也叫 chinese 或 zh 布局）并不是一个“输入法”，而是一种 键盘布局（Keyboard Layout）。&lt;&#x2F;li&gt;
&lt;li&gt;它的作用是：改变键盘上某些键的输出字符，尤其是标点符号。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;white-check-mark-ta-zuo-liao-shen-me&quot;&gt;✅ 它做了什么？&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;当你启用“键盘-汉语”布局时，不启动任何输入法引擎，但键盘会输出一些中文常用符号，例如：&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;按键&lt;&#x2F;th&gt;&lt;th&gt;英文布局输出&lt;&#x2F;th&gt;&lt;th&gt;键盘-汉语布局输出&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;,&lt;&#x2F;td&gt;&lt;td&gt;,&lt;&#x2F;td&gt;&lt;td&gt;，（中文逗号）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;.&lt;&#x2F;td&gt;&lt;td&gt;.&lt;&#x2F;td&gt;&lt;td&gt;。（中文句号）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;;&lt;&#x2F;td&gt;&lt;td&gt;;&lt;&#x2F;td&gt;&lt;td&gt;；（中文分号）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;:&lt;&#x2F;td&gt;&lt;td&gt;:&lt;&#x2F;td&gt;&lt;td&gt;：（中文冒号）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;?&lt;&#x2F;td&gt;&lt;td&gt;?&lt;&#x2F;td&gt;&lt;td&gt;？（中文问号）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;!&lt;&#x2F;td&gt;&lt;td&gt;!&lt;&#x2F;td&gt;&lt;td&gt;！（中文感叹号）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;⚠️ 注意：它不会帮你输入汉字，只是把标点换成中文全角符号。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;white-check-mark-shi-yong-chang-jing&quot;&gt;✅ 使用场景：&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;你正在写中文文档，想快速输入中文标点&lt;&#x2F;li&gt;
&lt;li&gt;你不希望频繁切换输入法，但又需要中文标点&lt;&#x2F;li&gt;
&lt;li&gt;你使用英文输入法为主，但希望标点“中文化”&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;vs-san-dui-bi-zong-jie&quot;&gt;🆚 三、对比总结&lt;&#x2F;h1&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;项目&lt;&#x2F;th&gt;&lt;th&gt;拼音&lt;&#x2F;th&gt;&lt;th&gt;键盘-汉语&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;类型&lt;&#x2F;td&gt;&lt;td&gt;输入法引擎&lt;&#x2F;td&gt;&lt;td&gt;键盘布局&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;是否能输入汉字&lt;&#x2F;td&gt;&lt;td&gt;✅ 能（通过拼音转换）&lt;&#x2F;td&gt;&lt;td&gt;❌ 不能&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;是否需要切换输入法&lt;&#x2F;td&gt;&lt;td&gt;✅ 需要（如 Ctrl+Space）&lt;&#x2F;td&gt;&lt;td&gt;❌ 不需要（始终生效）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;主要功能&lt;&#x2F;td&gt;&lt;td&gt;拼音 → 汉字&lt;&#x2F;td&gt;&lt;td&gt;英文标点 → 中文标点&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;适合人群&lt;&#x2F;td&gt;&lt;td&gt;所有中文用户&lt;&#x2F;td&gt;&lt;td&gt;希望快速输入中文标点的用户&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;在 fcitx 中的位置&lt;&#x2F;td&gt;&lt;td&gt;输入法列表（+号添加）&lt;&#x2F;td&gt;&lt;td&gt;键盘布局选项（系统级）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h1 id=&quot;jigsaw-si-chang-jian-wu-jie-cheng-qing&quot;&gt;🧩 四、常见误解澄清&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;x-wu-jie-1-jian-pan-yi-yu-shi-yi-chong-shu-ru-fa&quot;&gt;❌ 误解1：“键盘-汉语”是一种输入法？&lt;&#x2F;h2&gt;
&lt;p&gt;错误。它只是一个键盘布局，不会进行“拼音到汉字”的转换。它只是改变了某些按键的输出字符。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;x-wu-jie-2-wo-jia-liao-jian-pan-yi-yu-jiu-neng-da-zhong-wen-liao&quot;&gt;❌ 误解2：我加了“键盘-汉语”就能打中文了？&lt;&#x2F;h2&gt;
&lt;p&gt;不能。你仍然需要“拼音”或其他中文输入法引擎才能输入汉字。&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;✅ 正确用法组合：&lt;&#x2F;li&gt;
&lt;li&gt;✅ 方案1（推荐）：使用“拼音”输入法 → 自动输入汉字 + 中文标点&lt;&#x2F;li&gt;
&lt;li&gt;✅ 方案2：使用英文输入法 + “键盘-汉语”布局 → 手动输入汉字（复制粘贴），但标点自动中文化&lt;&#x2F;li&gt;
&lt;li&gt;✅ 方案3：英文输入法 + 手动切换中文标点（不推荐）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;tools-wu-ru-he-pei-zhi&quot;&gt;🛠️ 五、如何配置？&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;1-tian-jia-pin-yin-shu-ru-fa&quot;&gt;1. 添加“拼音”输入法&lt;&#x2F;h2&gt;
&lt;p&gt;在 fcitx5-configtool 中：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;点击「+」添加输入法&lt;&#x2F;li&gt;
&lt;li&gt;搜索 Pinyin 或 Chinese (Pinyin)&lt;&#x2F;li&gt;
&lt;li&gt;添加后，按 Ctrl+Space 切换中英文&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;2-qi-yong-jian-pan-yi-yu-bu-ju-ke-xuan&quot;&gt;2. 启用“键盘-汉语”布局（可选）&lt;&#x2F;h2&gt;
&lt;p&gt;在 GNOME 设置中：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Settings → Keyboard → Input Sources&lt;&#x2F;li&gt;
&lt;li&gt;点击「+」添加 Chinese → Chinese (Legacy)&lt;&#x2F;li&gt;
&lt;li&gt;或在终端运行：&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;gsettings set org.gnome.desktop.input-sources sources &amp;quot;[(&amp;#x27;xkb&amp;#x27;, &amp;#x27;us&amp;#x27;), (&amp;#x27;xkb&amp;#x27;, &amp;#x27;zh&amp;#x27;)]&amp;quot;`
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;这样即使不启用 fcitx，某些标点也会变成中文。&lt;&#x2F;p&gt;
&lt;h1 id=&quot;white-check-mark-zong-jie&quot;&gt;✅ 总结&lt;&#x2F;h1&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;名称&lt;&#x2F;th&gt;&lt;th&gt;是输入法吗？&lt;&#x2F;th&gt;&lt;th&gt;能输入汉字吗？&lt;&#x2F;th&gt;&lt;th&gt;用途&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;拼音&lt;&#x2F;td&gt;&lt;td&gt;✅ 是&lt;&#x2F;td&gt;&lt;td&gt;✅ 能&lt;&#x2F;td&gt;&lt;td&gt;用拼音打汉字&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;键盘-汉语&lt;&#x2F;td&gt;&lt;td&gt;❌ 不是&lt;&#x2F;td&gt;&lt;td&gt;❌ 不能&lt;&#x2F;td&gt;&lt;td&gt;把 , . ; : ? ! 变成中文标点&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;dart-jian-yi&quot;&gt;🎯 建议：&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;日常使用请添加 “拼音” 作为主要中文输入法。&lt;&#x2F;li&gt;
&lt;li&gt;“键盘-汉语”可作为辅助，但大多数情况下不需要单独启用，因为“拼音”输入法已经内置了中文标点支持。&lt;&#x2F;li&gt;
&lt;li&gt;如果你只是想正常打中文，“加一个‘拼音’就够了” ✅&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>fcitx拼音配置</title>
        <published>2025-08-08T12:03:48+08:00</published>
        <updated>2025-08-08T12:03:48+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/08/fcitx拼音配置/"/>
        <id>https://vercel.juzhong.xyz/2025/08/fcitx拼音配置/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/08/fcitx拼音配置/">&lt;h1 id=&quot;fcitx-flexible-input-method-framework-ji-xiao-qi-e-shu-ru-fa&quot;&gt;Fcitx (Flexible Input Method Framework) ── 即小企鹅输入法&lt;&#x2F;h1&gt;
&lt;h1 id=&quot;an-zhuang-fcitx5shu-ru-fa-kuang-jia&quot;&gt;安装fcitx5输入法框架&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt install fcitx5 \
    fcitx5-chinese-addons \
    fcitx5-frontend-gtk4 fcitx5-frontend-gtk3 fcitx5-frontend-gtk2 \
    fcitx5-frontend-qt5

sudo apt install fcitx5-config-qt fcitx5-frontend-qt6 fcitx5-module-xorg
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;an-zhuang-zhong-wen-ci-ku&quot;&gt;安装中文词库&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 下载词库文件
wget https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;felixonmars&amp;#x2F;fcitx5-pinyin-zhwiki&amp;#x2F;releases&amp;#x2F;download&amp;#x2F;0.2.4&amp;#x2F;zhwiki-20220416.dict
# 创建存储目录
mkdir -p ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;fcitx5&amp;#x2F;pinyin&amp;#x2F;dictionaries&amp;#x2F;
# 移动词库文件至该目录
mv zhwiki-20220416.dict ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;fcitx5&amp;#x2F;pinyin&amp;#x2F;dictionaries&amp;#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;pei-zhi-shu-ru-fa&quot;&gt;配置输入法&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;im-config
im-config -n fcitx5

cat &amp;lt;&amp;lt;EOF &amp;gt; ~&amp;#x2F;.pam_environment
XMODIFIERS=@im=fcitx
GTK_IM_MODULE=fcitx
QT_IM_MODULE=fcitx
INPUT_METHOD=fcitx
EOF

fcitx5-configtool

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;cha-kan-gnomede-input-sources&quot;&gt;查看gnome的input-sources&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;gsettings get org.gnome.desktop.input-sources sources
gsettings set org.gnome.desktop.input-sources sources &amp;quot;[(&amp;#x27;xkb&amp;#x27;, &amp;#x27;us&amp;#x27;), (&amp;#x27;xkb&amp;#x27;, &amp;#x27;zh&amp;#x27;)]&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;zhu-ti-pei-zhi&quot;&gt;主题配置&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;mkdir -p ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;fcitx5&amp;#x2F;themes
git clone https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;hosxy&amp;#x2F;Fcitx5-Material-Color.git ~&amp;#x2F;.local&amp;#x2F;share&amp;#x2F;fcitx5&amp;#x2F;themes&amp;#x2F;Material-Colokkr
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;chang-jian-cuo-wu&quot;&gt;常见错误&lt;&#x2F;h1&gt;
&lt;p&gt;修复系统托盘显示异常&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt install gnome-shell-extension-appindicator
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;thep0y&#x2F;fcitx5-themes-canGdlelight.git&quot;&gt;主题&lt;&#x2F;a&gt;
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;zhuanlan.zhihu.com&#x2F;p&#x2F;582899001&quot;&gt;fctix5配置&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>linux字体渲染过程</title>
        <published>2025-08-08T00:39:43+08:00</published>
        <updated>2025-08-08T00:39:43+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/08/linux字体渲染过程/"/>
        <id>https://vercel.juzhong.xyz/2025/08/linux字体渲染过程/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/08/linux字体渲染过程/">&lt;p&gt;电脑在显示文字时选择字体并进行渲染的过程涉及多个步骤和技术，这些过程确保了文本能够以清晰、美观的方式呈现在屏幕上。以下是这一过程的基本概述：&lt;&#x2F;p&gt;
&lt;h1 id=&quot;zi-ti-xuan-ze&quot;&gt;字体选择&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;应用程序请求：当一个应用程序需要显示文本时，它会首先根据设计或用户设置指定一种或多种字体。这可能包括首选字体、次选字体等，形成一个优先级列表。&lt;&#x2F;li&gt;
&lt;li&gt;系统字体配置：操作系统维护着一个字体管理系统，该系统负责跟踪已安装的字体及其特性（如样式、权重、宽度等）。当应用请求特定字体时，操作系统会检查其字体库中是否有匹配项。&lt;&#x2F;li&gt;
&lt;li&gt;字体回退机制：如果首选字体不可用，操作系统将按照预定义的规则自动选择其他字体作为替代，这个过程称为字体回退或字体链。例如，如果请求的是“Arial”，但系统中没有安装Arial，可能会回退到相似的sans-serif字体如“Helvetica”或“DejaVu Sans”。&lt;&#x2F;li&gt;
&lt;li&gt;国际化支持：对于多语言文本，系统还会考虑字符集和语言脚本，选择支持所需字符的语言专用字体或包含广泛字符集的通用字体。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;ju-ti-liu-cheng&quot;&gt;具体流程&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;步骤1：确定文本的编码和语言
&lt;ul&gt;
&lt;li&gt;系统首先识别文本的 字符编码（如UTF-8）和 语言属性（如中文、阿拉伯文）。&lt;&#x2F;li&gt;
&lt;li&gt;例如：汉字 你（Unicode码位 U+4F60） vs. 拉丁字母 A（U+0041）。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;步骤2：匹配字体列表
&lt;ul&gt;
&lt;li&gt;应用程序或系统会按优先级检查以下来源：
&lt;ul&gt;
&lt;li&gt;应用指定字体（如CSS中定义的 font-family: &quot;Noto Sans CJK SC&quot;）。&lt;&#x2F;li&gt;
&lt;li&gt;系统默认字体（如Windows的微软雅黑、macOS的苹方、Linux的Noto Sans CJK）。&lt;&#x2F;li&gt;
&lt;li&gt;字体回退链（Fallback Chain）：&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;如果首选字体缺少当前字符，系统会依次尝试其他字体（例如：中文→日文→通用符号字体）。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;步骤3：选择最佳字体
&lt;ul&gt;
&lt;li&gt;通过 字体匹配算法 确定最终字体，考虑因素包括：
&lt;ul&gt;
&lt;li&gt;字符覆盖：字体是否包含该字符（如CJK字体优先匹配汉字）。&lt;&#x2F;li&gt;
&lt;li&gt;语言区域：系统语言设置可能影响选择（如简体中文环境优先选择SC版字体）。&lt;&#x2F;li&gt;
&lt;li&gt;样式匹配：粗体、斜体等属性是否可用。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;zi-ti-xuan-ran&quot;&gt;字体渲染&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;栅格化：一旦选择了合适的字体文件，下一步是将矢量轮廓转换为适合屏幕分辨率的位图图像，这一过程叫做栅格化。高质量的字体渲染引擎（如FreeType）可以执行抗锯齿处理和平滑边缘的技术来改善可读性。&lt;&#x2F;li&gt;
&lt;li&gt;子像素渲染：为了进一步提高清晰度，特别是对于LCD显示器，可以采用子像素渲染技术（如ClearType）。这种方法利用了每个像素由红、绿、蓝三个子像素组成的事实，通过对每个子像素单独控制来增强细节表现力。&lt;&#x2F;li&gt;
&lt;li&gt;布局与定位：完成栅格化后，接下来是确定每个字符的确切位置。这涉及到计算行间距、字距调整（kerning）、连字（ligatures）等因素，确保文本不仅清晰而且排版美观。&lt;&#x2F;li&gt;
&lt;li&gt;显示输出：最后，经过上述所有步骤处理后的位图被发送到图形硬件，并最终显示在屏幕上。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;ju-ti-liu-cheng-1&quot;&gt;具体流程&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;步骤1：字形定位（Glyph Lookup）
&lt;ul&gt;
&lt;li&gt;从选定的字体文件中找到对应字符的 字形数据（Glyph），即字符的图形描述（通常是矢量轮廓）。&lt;&#x2F;li&gt;
&lt;li&gt;例如：你 的字形可能存储在字体文件的 cmap（字符映射表）中。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;步骤2：文本整形（Text Shaping）
&lt;ul&gt;
&lt;li&gt;复杂脚本（如阿拉伯文、印度文）需要额外处理：
&lt;ul&gt;
&lt;li&gt;连字（Ligatures）：如 fi 合并为单一字形。&lt;&#x2F;li&gt;
&lt;li&gt;字形替换：同一字符在不同位置显示不同形状（如阿拉伯字母的孤立形、词中形）。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;工具：HarfBuzz（开源文本整形引擎，被Linux&#x2F;macOS&#x2F;浏览器广泛使用）。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;步骤3：栅格化（Rasterization）
&lt;ul&gt;
&lt;li&gt;将矢量字形转换为屏幕上的 像素图形，关键技术和优化：
&lt;ul&gt;
&lt;li&gt;抗锯齿（AA）：通过灰度过渡平滑边缘（如Freetype库的 subpixel rendering）。&lt;&#x2F;li&gt;
&lt;li&gt;亚像素渲染：利用LCD屏幕的RGB子像素提高清晰度（如Windows的ClearType）。&lt;&#x2F;li&gt;
&lt;li&gt;HiDPI适配：在高分辨率屏幕下缩放矢量轮廓后渲染。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;步骤4：合成与输出
&lt;ul&gt;
&lt;li&gt;渲染后的字形与其他元素（如图片、背景）合成最终图像，交给显示驱动输出到屏幕。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;整个流程中，字体选择和渲染的质量直接影响到用户体验，尤其是在长时间阅读或处理大量文本的情况下。因此，现代操作系统和浏览器都投入了大量的努力优化字体管理和渲染算法，以提供最佳的视觉效果。&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>linux 使用命令行查看dvd信息</title>
        <published>2025-08-06T23:53:43+08:00</published>
        <updated>2025-08-06T23:53:43+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/08/linux 使用命令行查看dvd信息/"/>
        <id>https://vercel.juzhong.xyz/2025/08/linux 使用命令行查看dvd信息/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/08/linux 使用命令行查看dvd信息/">&lt;h1 id=&quot;cha-kan-guang-pan-xin-xi&quot;&gt;查看光盘信息&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;wodim dev=&amp;#x2F;dev&amp;#x2F;sr0 -atip
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;she-bei-ji-ben-xin-xi&quot;&gt;设备基本信息&lt;&#x2F;h2&gt;
&lt;p&gt;*Device type : Removable CD-ROM
*设备类型为 可移动的 CD-ROM 驱动器（实际支持多种光盘类型，如 DVD&#x2F;CD）。
*Version : 0
*SCSI&#x2F;ATAPI 命令集的版本号（0 表示基础版本，无特殊功能）。
*Response Format: 2
*ATIP（Absolute Time in Pre-groove）数据的响应格式为 第2版（标准 DVD&#x2F;CD 信息格式）。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;she-bei-neng-li-capabilities&quot;&gt;设备能力（Capabilities）&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Vendor_info : &#x27;HL-DT-ST&#x27;&lt;&#x2F;li&gt;
&lt;li&gt;光驱的制造商是 HL-DT-ST（即 LG 旗下的光存储品牌）。&lt;&#x2F;li&gt;
&lt;li&gt;Identification : &#x27;DVDRAM GT30N&#x27;&lt;&#x2F;li&gt;
&lt;li&gt;设备型号为 DVDRAM GT30N（一款支持 DVD-RAM 的刻录机）。&lt;&#x2F;li&gt;
&lt;li&gt;Revision : &#x27;NH02&#x27;&lt;&#x2F;li&gt;
&lt;li&gt;固件版本号为 NH02（厂商内部定义的固件版本）。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;she-bei-qu-dong-yu-mo-shi&quot;&gt;设备驱动与模式&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Device seems to be: Generic mmc2 DVD-R&#x2F;DVD-RW.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;系统识别此设备为 通用 MMC-2 标准的 DVD-R&#x2F;DVD-RW 驱动器（支持 DVD-R 和 DVD-RW 刻录）。&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Using generic SCSI-3&#x2F;mmc DVD-R(W) driver (mmc_mdvd).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;当前使用的驱动是 通用 SCSI-3&#x2F;MMC 标准驱动（mmc_mdvd 是 Linux 内核模块）。&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Driver flags : SWABAUDIO BURNFREE&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;驱动支持的标志：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;SWABAUDIO：表示驱动支持音频数据的字节序转换（Swap Audio Bytes），确保音频 CD 播放时左右声道正确。&lt;&#x2F;li&gt;
&lt;li&gt;BURNFREE：一种缓冲区欠载保护技术（类似 JustLink、PowerBurn），防止因系统延迟导致刻录失败。当数据流暂时中断时，自动暂停并恢复，避免刻录失败。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Supported modes: PACKET SAO&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;支持的刻录模式：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;PACKET：支持分组刻录（Packet Writing），允许像 U 盘一样小块写入数据（常用于 UDF 文件系统）。&lt;&#x2F;li&gt;
&lt;li&gt;SAO（Session At Once）：支持“一次会话”刻录模式，适合一次性写完一个完整会话（如 ISO 镜像）。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;⚠️ 注意：这里没有显示 TAO（Track at Once）或 DAO（Disk at Once），但大多数现代驱动器其实也支持这些模式，只是未在此列出。&lt;&#x2F;p&gt;
&lt;h1 id=&quot;cha-kan-guang-pan-mu-lu-jie-gou-toc&quot;&gt;查看光盘目录结构（TOC）&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;wodim -v dev=&amp;#x2F;dev&amp;#x2F;sr0 -toc
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;cha-kan-guang-pan-xin-xi-1&quot;&gt;查看光盘信息&lt;&#x2F;h1&gt;
&lt;p&gt;安装工具&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt install wodim xorriso genisoimage blkid util-linux
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;udevadm&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 查看光驱设备详细信息（厂商、型号、序列号等）
udevadm info --query=all --name=&amp;#x2F;dev&amp;#x2F;sr0 | grep -i &amp;#x27;id\|modalias\|vendor\|model&amp;#x27;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;wodim&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 查看光盘 TOC（Table of Contents）——适用于已写入数据的光盘
wodim -v dev=&amp;#x2F;dev&amp;#x2F;sr0 -toc
# 查看 CD-R&amp;#x2F;RW 光盘的 ATIP 信息（必须插入 CD-R 空盘）
wodim -atip dev=&amp;#x2F;dev&amp;#x2F;sr0
# 查看光驱基本信息
wodim -v dev=&amp;#x2F;dev&amp;#x2F;sr0 -scanbus
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;xorriso&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 查看光盘基本信息（文件系统、卷名、创建时间等）
xorriso -indev &amp;#x2F;dev&amp;#x2F;sr0 -report_el_torito as mkisofs -o &amp;#x2F;dev&amp;#x2F;null
# 显示光盘的完整结构（会话、轨道、文件系统）
xorriso -indev &amp;#x2F;dev&amp;#x2F;sr0 -list_delimiter &amp;quot;\n&amp;quot; -l -tree
# 查看是否支持多会话
xorriso -indev &amp;#x2F;dev&amp;#x2F;sr0 -info
# 提取光盘的卷标（Volume ID）
xorriso -indev &amp;#x2F;dev&amp;#x2F;sr0 -volume_date all_file_dates
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;dvd+rw-mediainfo &amp;#x2F;dev&amp;#x2F;sr0
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;isoinfo&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 列出光盘根目录内容
isoinfo -i &amp;#x2F;dev&amp;#x2F;sr0 -l
# 显示光盘卷信息（卷名、系统标识、创建时间等）
isoinfo -d -i &amp;#x2F;dev&amp;#x2F;sr0
# 提取光盘的卷标（Volume ID）
isoinfo -i &amp;#x2F;dev&amp;#x2F;sr0 -J -x &amp;#x27;&amp;#x2F;LABEL.TXT&amp;#x27;  # 假设文件存在
isoinfo -f -i &amp;#x2F;dev&amp;#x2F;sr0  # 列出文件
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;blkid&#x2F;lsblk&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 查看光盘文件系统类型（ISO9660、UDF、none 等）
blkid &amp;#x2F;dev&amp;#x2F;sr0
# 查看设备挂载状态和大小
lsblk -f &amp;#x2F;dev&amp;#x2F;sr0
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt install udftools
udfinfo &amp;#x2F;dev&amp;#x2F;sr0
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>linux dvd刻录工具介绍</title>
        <published>2025-08-06T23:18:44+08:00</published>
        <updated>2025-08-06T23:18:44+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/08/linux dvd刻录工具介绍/"/>
        <id>https://vercel.juzhong.xyz/2025/08/linux dvd刻录工具介绍/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/08/linux dvd刻录工具介绍/">&lt;p&gt;在 Linux 系统中，有多个功能类似 ImgBurn 的光盘刻录工具，支持光盘写入、镜像制作、光盘擦除等功能，且多数是开源免费的。以下是几款常用工具及特点：&lt;&#x2F;p&gt;
&lt;h1 id=&quot;brasero-tui-jian-xin-shou&quot;&gt;Brasero（推荐新手）&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;特点：GNOME 桌面环境默认的刻录工具，界面简洁直观，操作类似 ImgBurn 的基础功能，支持多会话写入、光盘镜像制作 &#x2F; 刻录、光盘复制等。&lt;&#x2F;li&gt;
&lt;li&gt;支持格式：ISO、CUE&#x2F;BIN、NRG 等常见镜像格式，以及数据光盘、音频 CD、视频 DVD 刻录。&lt;&#x2F;li&gt;
&lt;li&gt;优势：对新手友好，自动检测光驱和光盘状态，支持 “封闭光盘”（Finalize）选项。&lt;&#x2F;li&gt;
&lt;li&gt;安装：&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;Ubuntu&amp;#x2F;Debian：sudo apt install brasero
Fedora：sudo dnf install brasero
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;k3b-gong-neng-quan-mian-tui-jian-jin-jie-yong-hu&quot;&gt;K3b（功能全面，推荐进阶用户）&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;特点：KDE 桌面环境的经典刻录工具，功能接近 ImgBurn 的专业级，支持多段写入、光盘擦除（针对可擦写光盘）、镜像校验、蓝光刻录等高级功能。&lt;&#x2F;li&gt;
&lt;li&gt;支持格式：几乎所有主流镜像格式（ISO、BIN&#x2F;CUE、MDS、NRG 等），还能直接刻录视频 DVD、音频 CD 及数据光盘。&lt;&#x2F;li&gt;
&lt;li&gt;优势：可手动控制刻录速度、会话管理（关闭 &#x2F; 开放会话），适合需要精细操作的场景（如封闭光盘、多段写入）。&lt;&#x2F;li&gt;
&lt;li&gt;安装：&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;Ubuntu&amp;#x2F;Debian：sudo apt install k3b
Fedora：sudo dnf install k3b
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;xfburn-qing-liang-xiao-qiao&quot;&gt;Xfburn（轻量小巧）&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;特点：针对轻量桌面（如 Xfce）设计的刻录工具，体积小、启动快，功能精简但够用，支持数据刻录、镜像制作 &#x2F; 写入、光盘擦除。&lt;&#x2F;li&gt;
&lt;li&gt;优势：资源占用低，适合老旧电脑或对界面复杂度有要求的用户。&lt;&#x2F;li&gt;
&lt;li&gt;安装：&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;Ubuntu&amp;#x2F;Debian：sudo apt install xfburn
Fedora：sudo dnf install xfburn
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;wodim-genisoimage-ming-ling-xing-gong-ju-gua-he-jiao-ben-zi-dong-hua&quot;&gt;wodim + genisoimage（命令行工具，适合脚本自动化）&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;特点：如果习惯命令行操作，wodim（光盘写入）和 genisoimage（镜像制作）是 Linux 下的经典组合，功能强大且可集成到脚本中批量处理。&lt;&#x2F;li&gt;
&lt;li&gt;常用命令示例：
&lt;ul&gt;
&lt;li&gt;制作 ISO 镜像：genisoimage -o output.iso &#x2F;path&#x2F;to&#x2F;files
&lt;ul&gt;
&lt;li&gt;刻录 ISO 到光盘：wodim dev=&#x2F;dev&#x2F;sr0 -speed=4 output.iso（&#x2F;dev&#x2F;sr0 为光驱设备名，-speed 指定速度）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;模拟刻录：wodim dev=&#x2F;dev&#x2F;sr0 -v -eject speed=4 input.iso
&lt;ul&gt;
&lt;li&gt;封闭光盘：wodim dev=&#x2F;dev&#x2F;sr0 -finalize&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;安装：&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;Ubuntu&amp;#x2F;Debian：sudo apt install wodim genisoimage
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;ming-ling-xing-dvdgong-ju-dui-bi&quot;&gt;命令行dvd工具对比&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;mkisofs：创建ISO镜像（现通常被 genisoimage 或 xorriso 替代）。&lt;&#x2F;li&gt;
&lt;li&gt;cdrecord：刻录光盘（Linux中常被 wodim 替代）。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;growisofs&quot;&gt;growisofs&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;专为DVD&#x2F;BD刻录设计的工具，基于 dvd+rw-tools。&lt;&#x2F;li&gt;
&lt;li&gt;直接写入ISO或文件到DVD&#x2F;BD，无需先创建镜像。&lt;&#x2F;li&gt;
&lt;li&gt;支持增量写入（多段刻录）。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 第一次刻录（不关闭）
growisofs -Z &amp;#x2F;dev&amp;#x2F;sr0 -R -J &amp;#x2F;path&amp;#x2F;to&amp;#x2F;data1
growisofs -Z &amp;#x2F;dev&amp;#x2F;sr0=&amp;#x2F;path&amp;#x2F;to&amp;#x2F;files   # 直接刻录文件
# 追加数据（-M 表示 multi-session）
growisofs -M &amp;#x2F;dev&amp;#x2F;sr0 -R -J &amp;#x2F;path&amp;#x2F;to&amp;#x2F;data2
growisofs -M &amp;#x2F;dev&amp;#x2F;sr0=output.iso       # 追加数据
# 最终关闭光盘
dvd+rw-format -close=1 &amp;#x2F;dev&amp;#x2F;sr0
sudo apt install dvd+rw-tools
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;xorriso&quot;&gt;xorriso&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;多功能ISO和光盘操作工具（libisoburn 的一部分），可替代 mkisofs + wodim。&lt;&#x2F;li&gt;
&lt;li&gt;创建&#x2F;修改ISO：支持Rock Ridge、Joliet、UDF。&lt;&#x2F;li&gt;
&lt;li&gt;刻录：直接刻录ISO或文件到光盘。&lt;&#x2F;li&gt;
&lt;li&gt;转换：将ISO转换为其他格式。&lt;&#x2F;li&gt;
&lt;li&gt;引导支持：处理EFI&#x2F;BIOS引导镜像。&lt;&#x2F;li&gt;
&lt;li&gt;单一工具完成全流程，脚本友好。&lt;&#x2F;li&gt;
&lt;li&gt;支持DVD&#x2F;BD和增量刻录。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# 制作ISO
xorriso -outdev output.iso -map &amp;#x2F;path&amp;#x2F;to&amp;#x2F;files &amp;#x2F; -volid &amp;quot;MY_DISC&amp;quot;
# 刻录ISO
xorriso -dev &amp;#x2F;dev&amp;#x2F;sr0 -blank as_needed -speed 4 -map input.iso &amp;#x2F; -- -commit_eject all
sudo apt install xorriso
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;工具&lt;&#x2F;th&gt;&lt;th&gt;主要用途&lt;&#x2F;th&gt;&lt;th&gt;优势&lt;&#x2F;th&gt;&lt;th&gt;劣势&lt;&#x2F;th&gt;&lt;th&gt;适用场景&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;cdrtools&lt;&#x2F;td&gt;&lt;td&gt;光盘刻录套件&lt;&#x2F;td&gt;&lt;td&gt;功能全面&lt;&#x2F;td&gt;&lt;td&gt;维护停滞，部分工具被替代&lt;&#x2F;td&gt;&lt;td&gt;传统脚本兼容性&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;mkisofs&lt;&#x2F;td&gt;&lt;td&gt;创建ISO镜像&lt;&#x2F;td&gt;&lt;td&gt;兼容性好&lt;&#x2F;td&gt;&lt;td&gt;逐渐被替代&lt;&#x2F;td&gt;&lt;td&gt;需与旧脚本兼容时&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;genisoimage&lt;&#x2F;td&gt;&lt;td&gt;创建ISO镜像&lt;&#x2F;td&gt;&lt;td&gt;活跃维护，兼容 mkisofs&lt;&#x2F;td&gt;&lt;td&gt;不支持UDF&lt;&#x2F;td&gt;&lt;td&gt;制作数据ISO&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;wodim&lt;&#x2F;td&gt;&lt;td&gt;刻录CD&#x2F;DVD&lt;&#x2F;td&gt;&lt;td&gt;轻量，替代 cdrecord&lt;&#x2F;td&gt;&lt;td&gt;仅基础刻录功能&lt;&#x2F;td&gt;&lt;td&gt;简单刻录需求&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;growisofs&lt;&#x2F;td&gt;&lt;td&gt;DVD&#x2F;BD刻录&lt;&#x2F;td&gt;&lt;td&gt;直接刻录文件，支持增量&lt;&#x2F;td&gt;&lt;td&gt;仅限DVD&#x2F;BD&lt;&#x2F;td&gt;&lt;td&gt;专业级DVD&#x2F;BD操作&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;xorriso&lt;&#x2F;td&gt;&lt;td&gt;ISO制作+刻录全能工具&lt;&#x2F;td&gt;&lt;td&gt;支持全流程，脚本友好&lt;&#x2F;td&gt;&lt;td&gt;命令行复杂&lt;&#x2F;td&gt;&lt;td&gt;高级用户或自动化任务&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h1 id=&quot;zong-jie&quot;&gt;总结&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;新手或追求简单操作：优先选 Brasero，界面友好且功能满足日常需求。&lt;&#x2F;li&gt;
&lt;li&gt;需要高级功能（如多段写入、蓝光刻录）：选 K3b，功能接近 ImgBurn 的专业级体验。&lt;&#x2F;li&gt;
&lt;li&gt;轻量环境或命令行偏好：Xfburn 或 wodim + genisoimage 更合适。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;这些工具均支持 “封闭光盘”（Finalize）功能，在刻录时可手动勾选相关选项（图形工具）或通过参数（命令行）控制，与 ImgBurn 的核心功能一致。&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>为什么光盘需要进行《封闭光盘》操作</title>
        <published>2025-08-06T23:11:17+08:00</published>
        <updated>2025-08-06T23:11:17+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/08/为什么光盘需要进行封闭光盘操作/"/>
        <id>https://vercel.juzhong.xyz/2025/08/为什么光盘需要进行封闭光盘操作/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/08/为什么光盘需要进行封闭光盘操作/">&lt;p&gt;在光盘刻录中，“封闭光盘”（Finalize）是一个关键操作，直接影响光盘的兼容性和可读写性。以下详细说明如何判断光盘是否已封闭，以及为什么需要封闭光盘：&lt;&#x2F;p&gt;
&lt;h1 id=&quot;ru-he-pan-duan-guang-pan-shi-fou-yi-feng-bi&quot;&gt;如何判断光盘是否已 “封闭”？&lt;&#x2F;h1&gt;
&lt;p&gt;判断光盘是否封闭，可通过设备识别、软件检测或实际测试三种方式，具体方法如下：&lt;&#x2F;p&gt;
&lt;h2 id=&quot;1-tong-guo-cao-zuo-xi-tong-zhi-jie-shi-bie-jian-dan-zhi-guan&quot;&gt;1. 通过操作系统直接识别（简单直观）&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;插入光盘后查看属性&lt;&#x2F;li&gt;
&lt;li&gt;若光盘已封闭：通常会显示 “已使用空间” 和 “可用空间”，但可用空间会显示为 “0”（即使光盘未写满），且无法向光盘中复制新文件（会提示 “介质受写保护” 或 “无法写入”）。&lt;&#x2F;li&gt;
&lt;li&gt;若未封闭：属性中会显示 “可用空间”（即未使用的容量），且在支持写入的设备中可继续追加数据（前提是光盘支持多段写入）。&lt;&#x2F;li&gt;
&lt;li&gt;尝试写入数据测试&lt;&#x2F;li&gt;
&lt;li&gt;向光盘中复制一个小文件，若提示 “无法写入”“介质不可写” 或 “光盘已关闭”，则说明光盘已封闭；若能正常写入，则未封闭。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;2-tong-guo-ke-lu-ruan-jian-jian-ce-zhuan-ye-zhun-que&quot;&gt;2. 通过刻录软件检测（专业准确）&lt;&#x2F;h2&gt;
&lt;p&gt;使用 Nero、ImgBurn、Ashampoo Burning Studio、k3b(linux) 等专业刻录软件，可直接查看光盘状态&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;打开刻录软件，选择 “光盘信息”“查看光盘状态” 或类似功能（不同软件名称可能不同）。&lt;&#x2F;li&gt;
&lt;li&gt;软件会显示光盘的详细信息，包括：
“光盘状态”：明确标注 “已封闭（Finalized）” 或 “未封闭（Unfinalized）”；
“会话状态”：若显示 “最后一个会话已关闭” 或 “无可用会话”，则为已封闭；若显示 “存在开放会话（Open Session）”，则未封闭。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;3-zai-qi-ta-she-bei-shang-ce-shi-jian-rong-xing-shi-ji-yan-zheng&quot;&gt;3. 在其他设备上测试兼容性（实际验证）&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;未封闭的光盘可能存在兼容性问题，可通过跨设备测试判断：&lt;&#x2F;li&gt;
&lt;li&gt;若光盘能在 DVD 播放器、汽车音响、老式光驱 等非电脑设备上正常读取，则大概率已封闭（这些设备通常不支持读取未封闭的光盘）。&lt;&#x2F;li&gt;
&lt;li&gt;若仅能在刻录该光盘的电脑上读取，而在其他设备上提示 “无法识别光盘”“介质错误”，则可能未封闭。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;wei-shen-me-xu-yao-feng-bi-guang-pan&quot;&gt;为什么需要 “封闭光盘”？&lt;&#x2F;h1&gt;
&lt;p&gt;封闭光盘的核心目的是确保光盘在所有设备上的兼容性，并锁定数据防止后续修改，具体原因如下：&lt;&#x2F;p&gt;
&lt;h2 id=&quot;1-bao-zheng-kua-she-bei-jian-rong-xing-zui-he-xin-yuan-yin&quot;&gt;1. 保证跨设备兼容性（最核心原因）&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;光盘的 “未封闭状态” 仅能被刻录时使用的电脑和软件识别，而大多数设备（如 DVD 播放器、电视、车载光驱、其他品牌电脑）无法读取未封闭的光盘。&lt;&#x2F;li&gt;
&lt;li&gt;未封闭的光盘存在 “开放会话”（Open Session），其数据结构不完整，其他设备的光驱无法解析文件系统（如 ISO 9660 或 UDF），会提示 “无效光盘” 或 “无法读取”。&lt;&#x2F;li&gt;
&lt;li&gt;封闭光盘后，光盘的导言区（Lead-in）、数据区和结尾区（Lead-out） 会被完整写入，文件系统结构固定，所有支持该类型光盘的设备都能正常识别。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;2-fang-zhi-hou-xu-xie-ru-bao-hu-shu-ju-wan-zheng-xing&quot;&gt;2. 防止后续写入，保护数据完整性&lt;&#x2F;h2&gt;
&lt;p&gt;封闭光盘后，光盘会被永久锁定，无法再追加任何数据（即使是支持多段写入的光盘）：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;对于一次性写入光盘（如 DVD-R、CD-R）：封闭后彻底终止写入权限，避免误操作导致数据损坏。&lt;&#x2F;li&gt;
&lt;li&gt;对于可擦写光盘（如 DVD-RW）：封闭后同样无法写入，若需再次修改，需先 “解除封闭”（部分软件支持，但操作复杂且可能丢失数据）。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;3-you-hua-guang-pan-du-qu-xiao-lu&quot;&gt;3. 优化光盘读取效率&lt;&#x2F;h2&gt;
&lt;p&gt;未封闭的光盘在读取时，光驱需要额外扫描 “开放会话” 的信息，可能导致读取速度变慢或卡顿；封闭后，数据结构固定，光驱可直接按标准格式快速定位数据，提升读取稳定性。&lt;&#x2F;p&gt;
&lt;h1 id=&quot;te-shu-qing-kuang-na-xie-guang-pan-bu-xu-yao-qiang-zhi-feng-bi&quot;&gt;特殊情况：哪些光盘不需要强制封闭？&lt;&#x2F;h1&gt;
&lt;p&gt;并非所有光盘都必须立即封闭，以下场景可暂时不封闭：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;需要分多次写入的一次性光盘（如 DVD-R 多段写入）：首次写入时选择 “不封闭”，可后续追加数据，但需注意每次写入会占用额外的 “会话开销”（约几十 MB），且最终必须封闭才能在其他设备上读取。&lt;&#x2F;li&gt;
&lt;li&gt;可擦写光盘（DVD-RW&#x2F;DVD+RW）：若需反复修改内容，可暂时不封闭，随时追加或擦除数据；但长期保存或跨设备使用时，仍建议封闭以确保兼容性。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;zong-jie&quot;&gt;总结&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;判断光盘是否封闭：通过操作系统属性查看可用空间、刻录软件检测状态，或跨设备测试兼容性即可确认。&lt;&#x2F;li&gt;
&lt;li&gt;封闭光盘的核心作用：确保光盘能在所有设备上正常读取（兼容性），锁定数据防止误修改，并优化读取效率。&lt;&#x2F;li&gt;
&lt;li&gt;对于需要长期保存或跨设备使用的光盘，必须封闭；若需临时追加数据，可暂时不封闭，但需在最终使用前完成封闭操作。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>为什么光盘刻录要区分视频 音频和数据？</title>
        <published>2025-08-05T12:31:31+08:00</published>
        <updated>2025-08-05T12:31:31+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/08/为什么光盘刻录要区分视频 音频和数据？/"/>
        <id>https://vercel.juzhong.xyz/2025/08/为什么光盘刻录要区分视频 音频和数据？/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/08/为什么光盘刻录要区分视频 音频和数据？/">&lt;p&gt;区分视频、音频和数据光盘，主要源于技术标准、设备兼容性以及应用场景的本质差异&lt;&#x2F;p&gt;
&lt;h1 id=&quot;ji-shu-biao-zhun-yu-cun-chu-jie-gou-chai-yi&quot;&gt;技术标准与存储结构差异&lt;&#x2F;h1&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;‌数据光盘‌&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;‌文件系统‌：采用通用格式（如ISO 9660、UDF），直接存储原始文件（文档&#x2F;图片&#x2F;程序）。&lt;&#x2F;li&gt;
&lt;li&gt;‌读取方式‌：需依赖操作系统或特定软件解析文件系统，兼容性强但无专用优化。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;‌视频光盘（VCD&#x2F;DVD）‌&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;‌编码规范‌：
&lt;ul&gt;
&lt;li&gt;‌VCD‌：强制使用MPEG-1压缩，固定码率1.5Mbps，音频为MP2。&lt;&#x2F;li&gt;
&lt;li&gt;‌DVD‌：采用MPEG-2编码，支持多声道音频（AC3&#x2F;DTS）及交互菜单。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;‌文件结构‌：
&lt;ul&gt;
&lt;li&gt;视频文件必须命名为 VIDEO_TS（DVD）或 MPEGAV（VCD）等标准目录。&lt;&#x2F;li&gt;
&lt;li&gt;包含辅助文件（如 .IFO 导航信息）确保播放器识别。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;‌音频光盘（CD-DA）‌&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;物理格式‌：音频流以连续扇区存储，无文件系统（区别于数据CD）。&lt;&#x2F;li&gt;
&lt;li&gt;‌纠错机制‌：采用CIRC编码，优先保证音质连续性而非数据完整性。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;💡 ‌关键区别‌：视频&#x2F;音频光盘是 ‌“封闭式格式”‌，需严格遵循行业标准；数据光盘是 ‌“开放式存储”‌，无内容限制。&lt;&#x2F;p&gt;
&lt;h1 id=&quot;she-bei-jian-rong-xing-xu-qiu&quot;&gt;设备兼容性需求&lt;&#x2F;h1&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;设备类型&lt;&#x2F;th&gt;&lt;th&gt;支持的光盘格式&lt;&#x2F;th&gt;&lt;th&gt;限制说明&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;‌家用DVD机‌&lt;&#x2F;td&gt;&lt;td&gt;仅识别标准DVD&#x2F;VCD视频结构&lt;&#x2F;td&gt;&lt;td&gt;无法播放数据光盘内的MP4文件&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;‌车载CD播放器‌&lt;&#x2F;td&gt;&lt;td&gt;仅支持CD-DA音频光盘&lt;&#x2F;td&gt;&lt;td&gt;忽略数据CD中的MP3文件&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;‌蓝光播放器‌&lt;&#x2F;td&gt;&lt;td&gt;兼容BD-Video，部分支持数据BD&lt;&#x2F;td&gt;&lt;td&gt;需手动切换文件浏览模式&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;‌电脑光驱‌&lt;&#x2F;td&gt;&lt;td&gt;全格式兼容&lt;&#x2F;td&gt;&lt;td&gt;依赖软件解码（如VLC）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;⚠️ 若格式错误：
视频光盘刻录为数据格式 → DVD播放器报 ‌“无碟”或“格式不支持”‌
数据光盘放入CD播放器 → 播放 ‌刺耳噪声‌（误读二进制为音频）&lt;&#x2F;p&gt;
&lt;h1 id=&quot;yong-hu-ti-yan-yu-gong-neng-you-hua&quot;&gt;用户体验与功能优化&lt;&#x2F;h1&gt;
&lt;p&gt;‌视频&#x2F;音频光盘的专属功能‌&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;‌DVD菜单导航‌：依赖标准视频格式生成交互界面7。&lt;&#x2F;li&gt;
&lt;li&gt;‌CD音轨索引‌：支持歌曲快进&#x2F;切换（数据CD无法实现）。&lt;&#x2F;li&gt;
&lt;li&gt;‌播放稳定性‌：专用纠错算法降低卡顿&#x2F;跳帧风险。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;‌存储效率差异‌
‌同容量光盘‌：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;存储视频时长：DVD-Video &amp;gt; 数据光盘（因专用压缩优化）。&lt;&#x2F;li&gt;
&lt;li&gt;示例：单层DVD存MPEG-2视频约120分钟，存原始数据仅90分钟。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;xing-ye-gui-fan-yu-ban-quan-bao-hu&quot;&gt;行业规范与版权保护&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;‌版权控制需求‌
影视DVD常包含 ‌区域码‌（Region Code）及 ‌内容加扰系统‌（CSS）。
音乐CD采用 ‌CD-Text‌ 元数据保护，数据光盘无此类机制8。&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;‌生产标准化‌
工厂压盘必须遵循 ‌“红皮书”‌（CD-DA）、‌“白皮书”‌（VCD）等规范。
数据光盘无统一内容标准，仅需符合物理层刻录要求4。&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;zong-jie-qu-fen-gen-yuan-zai-yu-chang-jing-qu-dong-ji-shu-fen-hua&quot;&gt;总结：区分根源在于‌场景驱动技术分化‌&lt;&#x2F;h1&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;类型&lt;&#x2F;th&gt;&lt;th&gt;核心目标&lt;&#x2F;th&gt;&lt;th&gt;技术实现&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;数据&lt;&#x2F;td&gt;&lt;td&gt;通用存储&lt;&#x2F;td&gt;&lt;td&gt;开放文件系统+无编码限制&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;视频&lt;&#x2F;td&gt;&lt;td&gt;流畅播放+设备兼容&lt;&#x2F;td&gt;&lt;td&gt;强制编码标准+专用目录结构&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;音频&lt;&#x2F;td&gt;&lt;td&gt;高保真音质+播放便捷&lt;&#x2F;td&gt;&lt;td&gt;物理层流式存储+纠错优化&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;随着流媒体普及，光盘格式区分的重要性下降，但在专业存档、影视发行等领域仍是刚需。&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>linux dvd刻录</title>
        <published>2025-08-05T12:20:00+08:00</published>
        <updated>2025-08-05T12:20:00+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/08/linux dvd刻录/"/>
        <id>https://vercel.juzhong.xyz/2025/08/linux dvd刻录/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/08/linux dvd刻录/">&lt;h1 id=&quot;debian-ubuntu-shang-shi-yong-brasero-ke-lu-guang-pan&quot;&gt;Debian&#x2F;Ubuntu 上使用 Brasero 刻录光盘&lt;&#x2F;h1&gt;
&lt;p&gt;在 Ubuntu 系统中，Brasero 是一个非常方便的光盘刻录工具。无论是创建数据光盘、音频光盘还是刻录光盘镜像文件，Brasero 都能轻松胜任。本文将介绍如何在 Ubuntu 上安装和使用 Brasero 进行光盘刻录。&lt;&#x2F;p&gt;
&lt;h1 id=&quot;an-zhuang-brasero&quot;&gt;安装 Brasero&lt;&#x2F;h1&gt;
&lt;p&gt;在大多数 Ubuntu 版本中，Brasero 已经包含在默认的软件源中。你可以通过以下步骤安装 Brasero：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt update
sudo apt install brasero
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;shi-yong-brasero-ke-lu-shu-ju-guang-pan&quot;&gt;使用 Brasero 刻录数据光盘&lt;&#x2F;h1&gt;
&lt;p&gt;启动 Brasero：安装完成后，你可以在应用程序菜单中找到 Brasero，点击打开它。&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;创建新项目：
在 Brasero 主界面，选择“数据光盘”选项。
在新窗口中，点击“+”按钮添加你想要刻录的文件和文件夹。&lt;&#x2F;li&gt;
&lt;li&gt;配置刻录设置：
在窗口底部，你可以选择光盘的刻录速度。默认速度通常是安全且可靠的选择。
确保你的光驱中已经插入了一张空白光盘。&lt;&#x2F;li&gt;
&lt;li&gt;开始刻录：
检查确认所有文件和设置无误后，点击“刻录”按钮。
刻录过程可能需要几分钟时间，取决于数据量和刻录速度。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2025-08-05-12-43-06.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>docker 开启ipv6网络支持</title>
        <published>2025-08-05T09:12:46+08:00</published>
        <updated>2025-08-05T09:12:46+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/08/docker 开启ipv6网络支持/"/>
        <id>https://vercel.juzhong.xyz/2025/08/docker 开启ipv6网络支持/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/08/docker 开启ipv6网络支持/">&lt;p&gt;Docker 默认是不开启 IPv6 支持的，这里介绍如何开启 Docker 桥接网络 IPv6 支持，具体操作仅供参考，建议以官方文档为准。&lt;&#x2F;p&gt;
&lt;p&gt;通过查看主机命令方式获取的 ipv6 地址输出如下：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text &quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;6: eth0:  mtu 9000 
    inet6 2607:f0d0:1102:11::4&amp;#x2F;64 scope global 
       valid_lft forever preferred_lft forever
    inet6 fe80::230:48ff:fe33:bc33&amp;#x2F;64 scope link 
       valid_lft forever preferred_lft forever
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;其中inet6 2607:f0d0:1102:11::4&#x2F;64 scope global这行指示的IPv6地址是我们需要的目标地址，注意这里的是公网IP，也就是后面scope global指示的，大家注意到后续还有一个fe80 开头的 IPv6 地址，这个后面没有 global，也就是通常意义内网 IPv6&lt;&#x2F;p&gt;
&lt;h1 id=&quot;ipv6-di-zhi-duan-hua-fen&quot;&gt;IPv6 地址段划分&lt;&#x2F;h1&gt;
&lt;p&gt;Docker 可以配置多个虚拟网络，对于 IPv4 来说通过形如 172.17.0.1&#x2F;16、172.18.0.1&#x2F;16、172.19.0.1&#x2F;16 这样内网私有IP地址段配置多个 IPv4 虚拟网段，那么同样的道理 IPv6 也建议划分多个段&lt;&#x2F;p&gt;
&lt;p&gt;比如刚才的 IPv6 地址划分为 4 个网段如下：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text &quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;2607:f0d0:1102:11::&amp;#x2F;66
2607:f0d0:1102:11:4000::&amp;#x2F;66
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;pei-zhi-mo-ren-docker-ipv6&quot;&gt;配置默认 Docker IPv6&lt;&#x2F;h1&gt;
&lt;p&gt;编辑 Docker 配置文件&#x2F;etc&#x2F;docker&#x2F;daemon.json，如果该文件不存在，请手动建立。配置文件内容如下，如果你已有的配置文件缺少相应的配置项，添加上即可，没有必要完全覆盖内容。&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;json&quot; class=&quot;language-json &quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;{
  &amp;quot;experimental&amp;quot;: true,
  &amp;quot;ipv6&amp;quot;: true,
  &amp;quot;ip6tables&amp;quot;: true,
  &amp;quot;fixed-cidr-v6&amp;quot;: &amp;quot;2607:f0d0:1002:51::&amp;#x2F;66&amp;quot;
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;这里ip6tables是指由 Docker 自动配置 IPv6 的防火墙规则，如果你希望自己手动配置，请改为 false 或者移除此项，否则容器将无法连接 IPv6 网络；fixed-cidr-v6 则是我们划分的子网段的第一个，这里仅作示例请读者根据实际情况修改。&lt;&#x2F;p&gt;
&lt;p&gt;完成配置后请使用systemctl restart docker重启docker服务生效。完成此步后 Docker 算是完成对于 IPv6 的支持了。&lt;&#x2F;p&gt;
&lt;h1 id=&quot;pei-zhi-docker-compose-de-ipv6-zhi-chi&quot;&gt;配置 Docker Compose 的 IPv6 支持&lt;&#x2F;h1&gt;
&lt;p&gt;Docker Compose 的配置文件内容关于 IPv6 部分重点是网络节配置，如果另外配置网络的话，必须选择与默认daemon.json不同的 IPv6 子网段，例如：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;yaml&quot; class=&quot;language-yaml &quot;&gt;&lt;code class=&quot;language-yaml&quot; data-lang=&quot;yaml&quot;&gt;networks:
  example:
    enable_ipv6: true
    driver: bridge
    driver_opts:
      com.docker.network.enable_ipv6: &amp;quot;true&amp;quot;
    ipam:
      config:
       - subnet: 172.23.0.0&amp;#x2F;16
       - subnet: &amp;quot;2607:f0d0:1002:51:4000::&amp;#x2F;66&amp;quot;
         gateway:2607:f0d0:1002:51:4000::1
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;这里example网络我们通过配置开启IPv6支持，其中网络段配置IPv4是172.23.0.0&#x2F;16，IPv6选用余下的第二个网段2607:f0d0:1002:51:4000::&#x2F;66注意这里不能和daemon.json配置的 IPv6 网段一样。这里的 IP 配置同样是一个示例，读者请根据实际情况进行修改。&lt;&#x2F;p&gt;
&lt;h1 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;zhuanlan.zhihu.com&#x2F;p&#x2F;400379696&quot;&gt;docker ipv6网络配置&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>输入法输出的是unicode吗</title>
        <published>2025-08-01T19:35:57+08:00</published>
        <updated>2025-08-01T19:35:57+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/08/输入法输出的是unicode吗/"/>
        <id>https://vercel.juzhong.xyz/2025/08/输入法输出的是unicode吗/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/08/输入法输出的是unicode吗/">&lt;p&gt;字符插入到应用程序中的时unicode还是utf8, 还是其他
这是一个非常好的问题！在现代 Linux 桌面环境中（包括 GNOME），当 IBus 将一个中文字符（如“你”）插入到应用程序中时，它传递给应用程序的是 Unicode 码点（code point）的逻辑表示，而底层通信使用的是 UTF-8 编码的字节序列。&lt;&#x2F;p&gt;
&lt;p&gt;下面我们来详细拆解这个过程：&lt;&#x2F;p&gt;
&lt;h1 id=&quot;1-he-xin-gai-nian-qu-fen-unicode-vs-utf-8&quot;&gt;1. 核心概念区分：Unicode vs UTF-8&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;Unicode：是一个字符集（Character Set），它为世界上几乎所有的字符分配一个唯一的数字编号，称为码点（Code Point）。例如：&lt;&#x2F;li&gt;
&lt;li&gt;U+4F60 就是汉字“你”在 Unicode 中的码点。&lt;&#x2F;li&gt;
&lt;li&gt;UTF-8：是一种编码方式（Encoding），用于将 Unicode 码点转换为计算机可以存储和传输的字节序列（bytes）。&lt;&#x2F;li&gt;
&lt;li&gt;U+4F60（“你”）用 UTF-8 编码后，是 3 个字节：0xE4 0xBD 0xA0。
简单说：Unicode 是“身份ID”，UTF-8 是“身份证上的信息如何印刷（字节格式）”。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;2-ibus-ru-he-chuan-di-zi-fu&quot;&gt;2. IBus 如何传递字符？&lt;&#x2F;h1&gt;
&lt;p&gt;IBus 在设计上遵循现代国际化标准，它与应用程序的通信逻辑上是基于 Unicode 码点的，但物理传输使用 UTF-8。&lt;&#x2F;p&gt;
&lt;p&gt;具体流程如下：&lt;&#x2F;p&gt;
&lt;p&gt;输入法引擎生成字符：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;当你选择“你”这个候选词时，ibus-libpinyin 引擎内部知道这个字符的 Unicode 码点是 U+4F60。&lt;&#x2F;li&gt;
&lt;li&gt;通过 D-Bus 发送 Commit 事件：&lt;&#x2F;li&gt;
&lt;li&gt;IBus 守护进程 (ibus-daemon) 通过 D-Bus 将“提交”指令发送给 ibus-gtk 模块。&lt;&#x2F;li&gt;
&lt;li&gt;D-Bus 协议本身支持字符串类型。当传递文本时，D-Bus 要求字符串必须是 UTF-8 编码的。&lt;&#x2F;li&gt;
&lt;li&gt;因此，U+4F60 会被编码成 UTF-8 字节序列 E4 BD A0，并通过 D-Bus 发送。&lt;&#x2F;li&gt;
&lt;li&gt;GTK 模块接收并处理：&lt;&#x2F;li&gt;
&lt;li&gt;ibus-gtk 模块从 D-Bus 收到这个 UTF-8 编码的字节序列。&lt;&#x2F;li&gt;
&lt;li&gt;GTK 库（如 Pango）内部会将 UTF-8 字节序列解码回 Unicode 码点 U+4F60，并理解这是一个有效的汉字。&lt;&#x2F;li&gt;
&lt;li&gt;插入到应用程序文本缓冲区：&lt;&#x2F;li&gt;
&lt;li&gt;GTK 应用程序（如 gedit）的文本组件（GtkTextView &#x2F; GtkEntry）内部的文本缓冲区（GtkTextBuffer）以 Unicode 码点序列的形式存储文本。&lt;&#x2F;li&gt;
&lt;li&gt;但当这个文本需要保存到文件或通过网络发送时，应用程序通常会将其编码为 UTF-8 字节流写入磁盘或传输。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;3-wei-shen-me-shi-utf-8&quot;&gt;3. 为什么是 UTF-8？&lt;&#x2F;h1&gt;
&lt;p&gt;Linux&#x2F;Unix 传统：POSIX 系统（包括 Linux）长期以来将“字节序列”作为字符串的基本单位。UTF-8 向后兼容 ASCII，是事实上的标准编码。
效率与兼容性：UTF-8 对 ASCII 字符（英文、数字、符号）只需 1 字节，非常高效。同时它能表示所有 Unicode 字符。
D-Bus 规范：D-Bus 明确规定其字符串类型使用 UTF-8 编码。
GTK&#x2F;Qt API：这些工具包的文本处理 API 在接收字符串时，期望的是 UTF-8 编码的 char*（C 语言）或 gchar*。&lt;&#x2F;p&gt;
&lt;h1 id=&quot;white-check-mark-zong-jie&quot;&gt;✅ 总结&lt;&#x2F;h1&gt;
&lt;p&gt;问题	答案&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;IBus 传递给应用程序的是什么？&lt;&#x2F;th&gt;&lt;th&gt;逻辑上是 Unicode 字符（码点），物理上是 UTF-8 编码的字节序列。&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;应用程序内部如何存储？&lt;&#x2F;td&gt;&lt;td&gt;现代应用程序（如 GTK&#x2F;Qt 应用）的文本缓冲区通常以 Unicode 码点序列的形式管理文本。&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;最终存储到文件是什么？&lt;&#x2F;td&gt;&lt;td&gt;绝大多数现代 Linux 应用程序（编辑器、终端等）默认以 UTF-8 编码将文本写入文件。&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;简而言之： 你可以理解为 IBus 告诉应用程序：“请插入一个 Unicode 字符 U+4F60”，而这个“告诉”的过程，是用 UTF-8 这种“语言”说的。应用程序听懂后，就在自己的 Unicode 文本流中加入这个字符，并在需要时用 UTF-8 格式保存。&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>输入法工作原理ibus</title>
        <published>2025-08-01T19:19:26+08:00</published>
        <updated>2025-08-01T19:19:26+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/08/输入法工作原理ibus/"/>
        <id>https://vercel.juzhong.xyz/2025/08/输入法工作原理ibus/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/08/输入法工作原理ibus/">&lt;p&gt;我们来详细拆解一下 IBus（Intelligent Input Bus）在 Linux 系统中，从你按下键盘按键开始，到最终中文文本被输入到应用程序的完整工作流程。&lt;&#x2F;p&gt;
&lt;p&gt;这是一个涉及操作系统内核、X Window System（或 Wayland）、输入法框架（IBus）、输入法引擎（Engine）和前端应用程序的复杂协作过程。&lt;&#x2F;p&gt;
&lt;h1 id=&quot;jigsaw-ibus-de-he-xin-jia-gou&quot;&gt;🧩 IBus 的核心架构&lt;&#x2F;h1&gt;
&lt;p&gt;在深入流程前，先理解 IBus 的关键组件：&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;ibus-daemon (IBus 守护进程)：核心后台服务。它管理所有输入法会话、协调通信，并作为“总线”（Bus）连接各个部分。&lt;&#x2F;li&gt;
&lt;li&gt;Input Method Engine (IME)：具体的输入法逻辑实现，如 ibus-pinyin（拼音）、ibus-libpinyin（智能拼音）、ibus-rime（小狼毫&#x2F;鼠须管）等。它负责将按键序列（如 ni hao）转换为候选词（如 你好）。&lt;&#x2F;li&gt;
&lt;li&gt;IBus Panel：用户界面组件。显示候选词列表、状态图标（中&#x2F;英文）、输入提示等。通常是一个悬浮窗口。&lt;&#x2F;li&gt;
&lt;li&gt;IBus GTK&#x2F;Qt Modules：嵌入在 GTK 或 Qt 应用程序中的模块。它们是应用程序与 IBus 守护进程通信的“桥梁”。&lt;&#x2F;li&gt;
&lt;li&gt;X11&#x2F;Wayland Server：负责接收原始的硬件键盘事件。&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h1 id=&quot;abc-xiang-xi-gong-zuo-liu-cheng-cong-an-jian-dao-wen-ben-shu-ru&quot;&gt;🔤 详细工作流程：从按键到文本输入&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;jie-duan-1-jian-pan-shu-ru-yu-shi-jian-bu-huo&quot;&gt;阶段 1：键盘输入与事件捕获&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;硬件事件：你按下键盘上的 n 键。&lt;&#x2F;li&gt;
&lt;li&gt;内核处理：键盘驱动将物理信号转换为标准的输入事件（EV_KEY），通过 evdev 接口发送给用户空间。&lt;&#x2F;li&gt;
&lt;li&gt;显示服务器接收：X11 Server（或 Wayland Compositor）从内核读取这个事件。此时，它只是一个原始的“keycode”（物理键码）和“keysym”（逻辑符号，如 n）。&lt;&#x2F;li&gt;
&lt;li&gt;事件分发：显示服务器将这个键盘事件发送给当前焦点窗口（即你正在输入的程序，比如 gedit）。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;jie-duan-2-ibus-jie-ru-yu-yu-bian-ji-pre-edit&quot;&gt;阶段 2：IBus 介入与预编辑（Pre-edit）&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;IBus 模块拦截：由于你之前已将 IBus 设置为输入法框架，gedit（GTK 应用）加载了 ibus-gtk 模块。这个模块拦截了显示服务器发来的键盘事件，而不是直接让 gedit 处理。&lt;&#x2F;li&gt;
&lt;li&gt;事件转发给 IBus 守护进程：ibus-gtk 模块将这个键盘事件（n）通过 D-Bus 发送给 ibus-daemon。&lt;&#x2F;li&gt;
&lt;li&gt;守护进程分发给引擎：ibus-daemon 收到事件后，根据当前激活的输入法会话（Session），将其转发给对应的 Input Method Engine（例如 ibus-libpinyin）。&lt;&#x2F;li&gt;
&lt;li&gt;引擎处理与预编辑：
ibus-libpinyin 引擎接收到 n。
它判断当前处于“拼音输入状态”。
引擎将 n 添加到当前的“预编辑文本”（Pre-edit String）中。预编辑文本是用户正在输入但尚未确认的拼音序列。
引擎立即计算可能的候选词（虽然 n 单独一个字母候选词很多，但引擎会开始准备）。
引擎通过 ibus-daemon 将预编辑状态信息（包括预编辑文本 n、文本属性如颜色&#x2F;下划线）发送回 ibus-gtk 模块。&lt;&#x2F;li&gt;
&lt;li&gt;前端显示预编辑：
ibus-gtk 模块收到预编辑信息。
它通知 gedit 在光标位置临时显示预编辑文本 n（通常带下划线或特殊颜色）。
同时，ibus-daemon 通知 IBus Panel 显示候选词列表（可能显示 n 开头的词，如“你”、“那”、“呢”等）。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;jie-duan-3-ji-xu-shu-ru-yu-hou-xuan-ci-sheng-cheng&quot;&gt;阶段 3：继续输入与候选词生成&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;输入 i：你按下 i 键。&lt;&#x2F;li&gt;
&lt;li&gt;重复阶段2流程：
&lt;ul&gt;
&lt;li&gt;事件被 ibus-gtk 拦截。&lt;&#x2F;li&gt;
&lt;li&gt;通过 D-Bus 发送给 ibus-daemon。&lt;&#x2F;li&gt;
&lt;li&gt;转发给 ibus-libpinyin 引擎。&lt;&#x2F;li&gt;
&lt;li&gt;引擎将 i 追加到预编辑文本，现在是 ni。&lt;&#x2F;li&gt;
&lt;li&gt;引擎重新计算候选词（你、呢、泥、拟 等）。&lt;&#x2F;li&gt;
&lt;li&gt;ibus-daemon 将新的预编辑文本 ni 和更新的候选词列表发送给 ibus-gtk 和 IBus Panel。&lt;&#x2F;li&gt;
&lt;li&gt;gedit 更新显示为 ni（带下划线），Panel 更新候选词。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;jie-duan-4-xuan-ci-yu-que-ren-shu-ru-commit&quot;&gt;阶段 4：选词与确认输入（Commit）&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;选择候选词：你按下 空格键 或数字键 1 来选择第一个候选词“你”。&lt;&#x2F;li&gt;
&lt;li&gt;引擎确认文本：
ibus-libpinyin 引擎收到 空格 事件。
它识别为“确认&#x2F;上屏”指令。
引擎将当前选中的候选词 “你” 标记为“已提交文本”（Committed Text）。
引擎清空预编辑状态。
引擎通过 ibus-daemon 向 ibus-gtk 模块发送一个 “Commit” 事件，内容是 Unicode 字符 “你”。&lt;&#x2F;li&gt;
&lt;li&gt;前端接收并显示最终文本：
ibus-gtk 模块收到 “Commit” 事件。
它停止显示预编辑文本。
它将真正的文本 “你” 插入到 gedit 的文本缓冲区中的光标位置。
gedit 正常渲染这个字符，就像你直接按了一个“你”键一样。&lt;&#x2F;li&gt;
&lt;li&gt;状态更新：ibus-daemon 通知 Panel 隐藏候选词列表。输入法回到初始状态，等待下一次输入。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;jie-duan-5-zhi-jie-shu-ru-ying-wen-fu-hao&quot;&gt;阶段 5：直接输入（英文&#x2F;符号）&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;切换到英文：你按下 Shift 键（假设设置为中英文切换键）。&lt;&#x2F;li&gt;
&lt;li&gt;引擎处理切换：
ibus-libpinyin 引擎收到 Shift 事件。
它切换到“英文输入模式”。
引擎向 ibus-daemon 发送一个 “Process Key Event” 指令，意思是“这个键不需要我处理，请原样传递给应用程序”。&lt;&#x2F;li&gt;
&lt;li&gt;事件透传：
ibus-daemon 将“透传”指令告知 ibus-gtk 模块。
ibus-gtk 模块不再拦截后续的键盘事件（如 h, e, l, l, o）。
这些事件直接由 gedit 处理，输入英文 “hello”。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;bar-chart-zong-jie-shu-ju-liu-tu&quot;&gt;📊 总结：数据流图&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text &quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;[键盘] 
  ↓ (硬件事件)
[内核 (evdev)] 
  ↓ 
[X11&amp;#x2F;Wayland Server] 
  ↓ (键盘事件)
[gedit (GTK App)] 
  ↓ (被拦截)
[ibus-gtk 模块] ←→ D-Bus ←→ [ibus-daemon] ←→ [Input Method Engine (e.g., ibus-libpinyin)]
  ↑ (预编辑&amp;#x2F;Commit)        ↑ (管理会话)        ↑ (处理逻辑)
  |                         |                   |
  ↓ (显示预编辑)            ↓ (显示Panel)       ↓ (生成候选词)
[gedit 显示 ni___]     [IBus Panel 显示 候选词]  [引擎内部状态]
  ↑
[用户按 空格]
  ↓
[引擎 Commit &amp;quot;你&amp;quot;]
  ↓
[ibus-gtk 模块]
  ↓ (插入文本)
[gedit 显示 &amp;quot;你&amp;quot;]
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;key-guan-jian-dian&quot;&gt;🔑 关键点&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;拦截与代理：IBus 的核心是“拦截”原始键盘事件，自己处理（预编辑、候选），处理完再把结果“代理”给应用程序。&lt;&#x2F;li&gt;
&lt;li&gt;D-Bus 通信：ibus-daemon 作为中心枢纽，使用 D-Bus 与引擎、Panel、GTK&#x2F;Qt 模块通信。&lt;&#x2F;li&gt;
&lt;li&gt;预编辑 (Pre-edit)：这是输入法能显示带下划线的拼音的关键。&lt;&#x2F;li&gt;
&lt;li&gt;Commit (提交)：这是候选词变成最终文本的关键步骤。&lt;&#x2F;li&gt;
&lt;li&gt;透传 (Pass-through)：在英文模式或某些快捷键下，IBus 会让事件直接到达应用。&lt;&#x2F;li&gt;
&lt;li&gt;理解这个流程，有助于你在配置输入法或排查问题（如候选词不出现、无法输入中文）时，能更精准地定位是哪个环节出了问题（是守护进程没启动？引擎没加载？模块没加载？快捷键冲突？）。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>wireshark插件 解析自定义协议</title>
        <published>2025-07-30T16:34:38+08:00</published>
        <updated>2025-07-30T16:34:38+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/07/wireshark插件 解析自定义协议/"/>
        <id>https://vercel.juzhong.xyz/2025/07/wireshark插件 解析自定义协议/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/07/wireshark插件 解析自定义协议/">&lt;p&gt;Wireshark内置了Lua脚本编写插件，无需配置额外的环境，使用起来吧比较便。&lt;&#x2F;p&gt;
&lt;p&gt;使用Lua编写Wireshark协议解析插件，有几个比较重要的概念:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Dissector,解剖器，用来解析包的类，我们要编写的，也是一个Dissector。&lt;&#x2F;li&gt;
&lt;li&gt;DissectorTable,解析器表是Wireshark中解析器的组织形式，是某一种协议的子解析器的一个列表，其作用是把所有的解析器组织成一种树状结构，便于Wireshark在解析包的时候自动选择对应的解析器。例如TCP协议的子解析器 http, smtp, sip等都被加在了&quot;tcp.port&quot;这个解析器表中，可以根据抓到的包的不同的tcp端口号，自动选择对应的解析器。&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h1 id=&quot;ji-chu&quot;&gt;基础&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;vercel.juzhong.xyz&#x2F;2025&#x2F;07&#x2F;wireshark%E6%8F%92%E4%BB%B6%20%E8%A7%A3%E6%9E%90%E8%87%AA%E5%AE%9A%E4%B9%89%E5%8D%8F%E8%AE%AE&#x2F;2025-07-30-17-28-53.png&quot; alt=&quot;主要接口&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lua&quot; class=&quot;language-lua &quot;&gt;&lt;code class=&quot;language-lua&quot; data-lang=&quot;lua&quot;&gt;-- create a new protocol
local proto_name = &amp;quot;PNASKCP&amp;quot;
local proto_desc = &amp;quot;Private NAS Protocol (KCP)&amp;quot;
local proto_obj = Proto(proto_name, proto_desc)
local proto_port = 5067

--register this dissector add Packet Details
DissectorTable.get(&amp;quot;udp.port&amp;quot;):add(proto_port, proto_obj)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;protofield&quot;&gt;ProtoField&lt;&#x2F;h2&gt;
&lt;p&gt;表示协议字段，一般用于解析字段后往解析树上添加节点。根据字段类型不同，其接口可以分为两大类。
这些接口都会返回一个新的字段对象。方括号内是可选字段，花括号内是可替换的类型字段。&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text &quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;ProtoField.{type}(abbr, [name], [base], [valuestring], [mask], [desc])
·type包括:uint8, uint16, uint24, uint32, uint64, framenum, float, double, string, stringz, bytes, bool, ipv4, ipv6, ether,oid, guid
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;参数&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;abbr 字段的缩写名称（过滤器中使用的字符串）。&lt;&#x2F;li&gt;
&lt;li&gt;name (optional) 字段的实际名称（出现在树中的字符串）。&lt;&#x2F;li&gt;
&lt;li&gt;base (optional) base.DEC，base.HEX或base.OCT，base.DEC_HEX，base.HEX_DEC，base.UNIT_STRING或base.RANGE_STRING。&lt;&#x2F;li&gt;
&lt;li&gt;valuestring (optional) 包含与值对应的文本的表，或包含与值 ({min, max, “string”}) 对应的范围字符串值表的表（如果基数为 ）base.RANGE_STRING，或包含单位名称的表如果 base 是base.UNIT_STRING.&lt;&#x2F;li&gt;
&lt;li&gt;mask (optional) 此字段的整数掩码。&lt;&#x2F;li&gt;
&lt;li&gt;desc (optional) 字段说明。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;lua&quot; class=&quot;language-lua &quot;&gt;&lt;code class=&quot;language-lua&quot; data-lang=&quot;lua&quot;&gt;fields.tlv_value_int16 = ProtoField.uint16(proto_name .. &amp;quot;.tlv_value_int&amp;quot;, &amp;quot;PNAS TLV VALUE&amp;quot;, base.HEX)
fields.uri_ipv4 = ProtoField.ipv4(proto_name .. &amp;quot;.uri_ipv4&amp;quot;, &amp;quot;IP ADDRESS&amp;quot;)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;tvb&quot;&gt;tvb&lt;&#x2F;h2&gt;
&lt;p&gt;Tvb（Testy Virtual Buffer）表示报文缓存，也就是实际的报文数据，可以通过下面介绍的TvbRange从报文数据中解出信息。主要接口有：
&lt;img src=&quot;https:&#x2F;&#x2F;vercel.juzhong.xyz&#x2F;2025&#x2F;07&#x2F;wireshark%E6%8F%92%E4%BB%B6%20%E8%A7%A3%E6%9E%90%E8%87%AA%E5%AE%9A%E4%B9%89%E5%8D%8F%E8%AE%AE&#x2F;2025-07-30-17-31-38.png&quot; alt=&quot;tvb 接口&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lua&quot; class=&quot;language-lua &quot;&gt;&lt;code class=&quot;language-lua&quot; data-lang=&quot;lua&quot;&gt;-- tvb(offset, 4)表示从offset开始之后的4个字节
subtree:add_le(fields.peer_ipaddr, tvb(offset, 4))
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;pinfo&quot;&gt;pinfo&lt;&#x2F;h2&gt;
&lt;p&gt;报文信息(packet information)。主要接口有：
&lt;img src=&quot;https:&#x2F;&#x2F;vercel.juzhong.xyz&#x2F;2025&#x2F;07&#x2F;wireshark%E6%8F%92%E4%BB%B6%20%E8%A7%A3%E6%9E%90%E8%87%AA%E5%AE%9A%E4%B9%89%E5%8D%8F%E8%AE%AE&#x2F;2025-07-30-17-32-48.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lua&quot; class=&quot;language-lua &quot;&gt;&lt;code class=&quot;language-lua&quot; data-lang=&quot;lua&quot;&gt;-- show protocol name
pinfo.cols.protocol = &amp;quot;PNASKCP&amp;quot;
-- show in info
pinfo.cols.info:set(&amp;quot;Private NAS Protocol (CALL_REQUEST)&amp;quot;) 
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;treeitem&quot;&gt;TreeItem&lt;&#x2F;h2&gt;
&lt;p&gt;表示报文解析树中的一个树节点。主要接口有：
&lt;img src=&quot;https:&#x2F;&#x2F;vercel.juzhong.xyz&#x2F;2025&#x2F;07&#x2F;wireshark%E6%8F%92%E4%BB%B6%20%E8%A7%A3%E6%9E%90%E8%87%AA%E5%AE%9A%E4%B9%89%E5%8D%8F%E8%AE%AE&#x2F;2025-07-30-17-33-31.png&quot; alt=&quot;&quot; &#x2F;&gt;
还有注意一下网络字节序的问题，如果是网络字节序需要用add_le添加节点&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lua&quot; class=&quot;language-lua &quot;&gt;&lt;code class=&quot;language-lua&quot; data-lang=&quot;lua&quot;&gt;-- kcp header
local subtree = tree:add(proto_obj, tvb(offset, lmmh_len), &amp;quot;KCP&amp;quot;)	
--conv
subtree:add_le(fields.conv, tvb(offset, 4))
offset = offset + 4
--cmd
subtree:add_le(fields.cmd, tvb(offset, 1))
offset = offset + 1
--frg
subtree:add_le(fields.frg, tvb(offset, 1))
offset = offset + 1
--wnd
subtree:add_le(fields.wnd, tvb(offset, 2))
offset = offset + 2
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;jiao-ben-mo-ban&quot;&gt;脚本模板&lt;&#x2F;h1&gt;
&lt;p&gt;创建编译 packet-demo.lua 文件&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lua&quot; class=&quot;language-lua &quot;&gt;&lt;code class=&quot;language-lua&quot; data-lang=&quot;lua&quot;&gt;do

-- 创建一个新的协议: 协议名称为 fuzz_proto，在Packet Details窗格显示为 Fuzz Custom Protocol
fuzz_protocol = Proto(&amp;quot;fuzz_proto&amp;quot;, &amp;quot;Fuzz Custom Protocol&amp;quot;)

-- 定义协议字段
--[[ 自定义字段
protocol_type(2) -- 自定义协议编号
base_protocol(1) -- 下层协议
connection_index(1) -- 收发状态
round_index(4) -- 本轮次序号
--]]
local f_protocol_type = ProtoField.uint16(&amp;quot;fuzz_proto.protocol_type&amp;quot;, &amp;quot;Custom Protocol ID&amp;quot;, base.DEC)
local f_base_protocol = ProtoField.uint8(&amp;quot;fuzz_proto.base_protocol&amp;quot;, &amp;quot;Base Protocol&amp;quot;, base.DEC)
local f_connection_index = ProtoField.uint8(&amp;quot;fuzz_proto.connection_index&amp;quot;, &amp;quot;Connection ID&amp;quot;, base.DEC)
local f_round_index = ProtoField.uint32(&amp;quot;fuzz_proto.round_index&amp;quot;, &amp;quot;Round Index&amp;quot;, base.DEC)
-- 将字段添加到协议中
fuzz_protocol.fields = { f_protocol_type, f_base_protocol, f_connection_index, f_round_index } 
local data_dis = Dissector.get(&amp;quot;data&amp;quot;)

-- 定义协议的解析函数
function FUZZ_dissector(buffer, pinfo, tree)
    local length = buffer:len()
    -- 确保报文有足够的长度供解析
    if length &amp;lt; 8 then
        return false
    end
    --验证一下identifier这个字段是不是0x12,如果不是的话，认为不是我要解析的packet
    local v_identifier = buffer(0, 1)
    if (v_identifier:uint() ~= 0x12) then 
        return false 
    end
    --取出其他字段的值
    local v_length = buffer(1, 1)
    v_length = tonumber(tostring(v_length),16)
    local v_data = buffer(2,v_length)

    -- 显示协议名称 --在主窗口的 Protocol 字段显示的名称为 XX_Protobuf
    -- pinfo.cols.protocol:set(&amp;quot;XX_Protobuf&amp;quot;)
    pinfo.cols.protocol = &amp;quot;fuzz_proto&amp;quot;

    --现在知道是我的协议了，放心大胆添加Packet Details
    -- 在树形结构中添加Headers
    local subtree = tree:add(fuzz_protocol, buffer(0, 7), &amp;quot;Fuzz Header&amp;quot;)
    -- 解析协议字段并添加到树中
    subtree:add(f_protocol_type, buffer(0, 2))

    local d_base_protocol = buffer(2, 1):uint()
    local d_base_protocol_map = {
        [0] = &amp;quot;UnSet&amp;quot;,
        [1] = &amp;quot;Ethernet&amp;quot;,
        [2] = &amp;quot;IP&amp;quot;,
        [3] = &amp;quot;TCP&amp;quot;,
        [4] = &amp;quot;UDP&amp;quot;,
        [5] = &amp;quot;TLS&amp;quot;,
        [6] = &amp;quot;HTTP&amp;quot;
    }
    local d_base_protocol = d_base_protocol_map[d_base_protocol] or &amp;quot;Unknown&amp;quot;
    subtree:add(f_base_protocol, buffer(2, 1)):append_text(&amp;quot; (&amp;quot; .. d_base_protocol .. &amp;quot;)&amp;quot;)

    local d_connection_index = (buffer(3, 1):uint() &amp;lt; 127) and &amp;quot;Send&amp;quot; or &amp;quot;Receive&amp;quot;
    subtree:add(f_connection_index, buffer(3, 1)):append_text(&amp;quot; (&amp;quot; .. d_connection_index .. &amp;quot;)&amp;quot;)

    -- 本轮次序号, 取值为十六进制，需要将其转换为十进制 
    local d_round_index = string.format(&amp;quot;%d&amp;quot;, buffer(4, 4):uint()) 
    subtree:add(f_round_index, buffer(4, 4)):append_text(&amp;quot; (&amp;quot; .. d_round_index .. &amp;quot;)&amp;quot;) 

    -- 解析下层协议
    local payload = buffer(8, length - 8)
    local subtree_payload = tree:add(fuzz_protocol, payload, &amp;quot;Current Custom Protocol&amp;quot;)
    subtree_payload:add(&amp;quot;Payload&amp;quot;, payload):append_text(&amp;quot; (&amp;quot; .. payload:len() .. &amp;quot; bytes)&amp;quot;)
end

function fuzz_protocol.dissector(buffer, pinfo, tree)
    if FUZZ_dissector(buffer, pinfo, tree) then
        -- valid Fuzz diagram
    else
        -- data这个dissector几乎是必不可少的；当发现不是我的协议时，就应该调用data
        data_dis.call(buffer, pinfo, tree)
    end
end

-- 注册 dissector 到对应的 DLT_USER3 (150)
-- local wtap_encap_table = DissectorTable.get(&amp;quot;wtap_encap&amp;quot;)
-- wtap_encap_table:add(150, fuzz_protocol)
local tcp_encap_table = DissectorTable.get(&amp;quot;tcp.port&amp;quot;)
--因为我们的自定义协议的接受端口是1080，所以这里只需要添加到&amp;quot;tcp.port&amp;quot;这个DissectorTable里即可。
tcp_encap_table:add(1080, fuzz_protocol)
end

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;pei-zhi-luajiao-ben&quot;&gt;配置lua脚本&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;vercel.juzhong.xyz&#x2F;2025&#x2F;07&#x2F;wireshark%E6%8F%92%E4%BB%B6%20%E8%A7%A3%E6%9E%90%E8%87%AA%E5%AE%9A%E4%B9%89%E5%8D%8F%E8%AE%AE&#x2F;2025-07-30-17-11-07.png&quot; alt=&quot;lua脚本位置&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;如图， 在&#x2F;usr&#x2F;share&#x2F;wireshark&#x2F;init.lua文件中，添加：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lua&quot; class=&quot;language-lua &quot;&gt;&lt;code class=&quot;language-lua&quot; data-lang=&quot;lua&quot;&gt;enable_lua = true
dofile(&amp;quot;&amp;#x2F;home&amp;#x2F;peter&amp;#x2F;.config&amp;#x2F;wireshark&amp;#x2F;packet-demo.lua&amp;quot;)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;然后重新启动Wireshark或者点击【分析】-【重新载入Lua插件】，就可以启用你自己的lua插件了。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;xin-ban-ben-wireshark4-2-zhong-de-wei-zhi-you-suo-gai-bian&quot;&gt;新版本wireshark4.2 中的位置有所改变&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;vercel.juzhong.xyz&#x2F;2025&#x2F;07&#x2F;wireshark%E6%8F%92%E4%BB%B6%20%E8%A7%A3%E6%9E%90%E8%87%AA%E5%AE%9A%E4%B9%89%E5%8D%8F%E8%AE%AE&#x2F;2025-08-13-18-58-36.png&quot; alt=&quot;&quot; &#x2F;&gt;
如图 init.lua需要 放置在 &#x2F;usr&#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;wireshark&#x2F;plugins&#x2F;init.lua 位置
并添加&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lua&quot; class=&quot;language-lua &quot;&gt;&lt;code class=&quot;language-lua&quot; data-lang=&quot;lua&quot;&gt;dofile(DATA_DIR..&amp;quot;&amp;#x2F;packet-demo.lua&amp;quot;)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;gao-ji-yi-dian-de-wan-fa&quot;&gt;高级一点的玩法&lt;&#x2F;h1&gt;
&lt;p&gt;如果我们协议的PayLoad里封装的其实是以太网包，能不能让Wireshark在我们的插件执行完之后，继续按照以太网格式解析其他部分呢？&lt;&#x2F;p&gt;
&lt;p&gt;这里，我们重新构造一下需要继续解析的数据，然后获取出一个以太网解析器就继续做下去&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lua&quot; class=&quot;language-lua &quot;&gt;&lt;code class=&quot;language-lua&quot; data-lang=&quot;lua&quot;&gt;local raw_data = buf(8, buf:len() - 8)
Dissector.get(&amp;quot;eth_maybefcs&amp;quot;):call(raw_data:tvb(), pinfo, tree)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;替换上面代码的-- 解析下层协议即可
需要在注意,&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;获取的解析器名称应该是 eth_maybefcs，因为DissectorTable里写的eth，但是提示找不到。 eth_maybefcs，意思是可能带有fcs的eth帧&lt;&#x2F;li&gt;
&lt;li&gt;raw_data需要调用一下tvb()函数，不然会提示你这个是userdata，不能使用。tvb的全称应该是Testy Virtual Buffer，用来存储Packet buffer的，要处理必须先转成这个。&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;调用eth_maybefcs解析器的时候，这些解析器会给协议栏赋值，覆盖掉我们之前写的wfuzz protocol。为了区分，我们可以在上面的代码之后加上：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lua&quot; class=&quot;language-lua &quot;&gt;&lt;code class=&quot;language-lua&quot; data-lang=&quot;lua&quot;&gt;pkt.cols.protocol:append(&amp;quot;-FuzzProtocol&amp;quot;)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;就是不管协议栏被改成了什么，都在后面加上-FuzzProtocol，这样ARP、ICMP等就会变成 ARP-Fuzz、ICMP-Fuzz了，一眼就可以跟那些普通的ARP和ICMP区分出来。&lt;&#x2F;p&gt;
&lt;h1 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.cnblogs.com&#x2F;little-kwy&#x2F;p&#x2F;14888454.html&quot;&gt;wireshark插件开发&lt;&#x2F;a&gt;&lt;&#x2F;br&gt;
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;zhuanlan.zhihu.com&#x2F;p&#x2F;568748288&quot;&gt;自定义协议&lt;&#x2F;a&gt;&lt;&#x2F;br&gt;
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;zhuanlan.zhihu.com&#x2F;p&#x2F;5968603110&quot;&gt;wireshark lua api 协议解析&lt;&#x2F;a&gt;&lt;&#x2F;br&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>手动安装vscode server</title>
        <published>2025-07-28T13:30:36+08:00</published>
        <updated>2025-07-28T13:30:36+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/07/手动安装vscode server/"/>
        <id>https://vercel.juzhong.xyz/2025/07/手动安装vscode server/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/07/手动安装vscode server/">&lt;p&gt;首先需要确认安装的vscode 的版本&lt;&#x2F;p&gt;
&lt;p&gt;查看vscode的版本&lt;&#x2F;p&gt;
&lt;p&gt;Help -&amp;gt; About
&lt;img src=&quot;https:&#x2F;&#x2F;vercel.juzhong.xyz&#x2F;2025&#x2F;07&#x2F;%E6%89%8B%E5%8A%A8%E5%AE%89%E8%A3%85vscode%20server&#x2F;2025-07-28-13-34-17.png&quot; alt=&quot;查看vscode版本&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;vscode server 的安装目录在$HOME&#x2F;.vscode-server中&lt;&#x2F;p&gt;
&lt;p&gt;首先,手动下载vscode server&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git_cid=c306e94f98122556ca081f527b466015e1bc37b0
wget -O vscode-server.tar.gz https:&amp;#x2F;&amp;#x2F;update.code.visualstudio.com&amp;#x2F;commit:${git_cid}&amp;#x2F;server-linux-x64&amp;#x2F;stable
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;解压到目标目录&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;install_path=&amp;quot;${HOME}&amp;#x2F;.vscode-server&amp;#x2F;bin&amp;#x2F;${git_cid}&amp;quot;
mkdir -p ${install_path}
tar -xzf vscode-server.tar.gz -C ${install_path} --strip-components 1
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;可以写成一个可执行脚本后续复用install.sh&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git_cid=&amp;quot;$1&amp;quot;
echo &amp;quot;Installing VSCode Server version: ${git_cid}&amp;quot;
install_path=&amp;quot;${HOME}&amp;#x2F;.vscode-server&amp;#x2F;bin&amp;#x2F;${git_cid}&amp;quot;
pushd &amp;#x2F;tmp
wget -O vscode-server.tar.gz https:&amp;#x2F;&amp;#x2F;update.code.visualstudio.com&amp;#x2F;commit:${git_cid}&amp;#x2F;server-linux-x64&amp;#x2F;stable
mkdir -p ${install_path}
tar -xzf vscode-server.tar.gz -C ${install_path} --strip-components 1
touch ${install_path}&amp;#x2F;0
popd
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>shadowsocks</title>
        <published>2025-07-24T15:33:48+08:00</published>
        <updated>2025-07-24T15:33:48+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/07/learn/shadowsocks/"/>
        <id>https://vercel.juzhong.xyz/2025/07/learn/shadowsocks/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/07/learn/shadowsocks/">&lt;p&gt;学习socks协议中发现有加密版本shadowsocks协议
这里记录一下协议学习的过程&lt;&#x2F;p&gt;
&lt;p&gt;项目参考: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;shadowsocks&#x2F;shadowsocks-rust&quot;&gt;shadowsocks&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;参考配置&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;json&quot; class=&quot;language-json &quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;{
    &amp;quot;server&amp;quot;: &amp;quot;127.0.0.1&amp;quot;,
    &amp;quot;server_port&amp;quot;: 8388,
    &amp;quot;password&amp;quot;: &amp;quot;rwQc8qPXVsRpGx3uW+Y3Lj4Y42yF9Bs0xg1pmx8&amp;#x2F;+bo=&amp;quot;,
    &amp;quot;method&amp;quot;: &amp;quot;aes-256-gcm&amp;quot;,
    &amp;#x2F;&amp;#x2F; ONLY FOR `sslocal`
    &amp;#x2F;&amp;#x2F; Delete these lines if you are running `ssserver` or `ssmanager`
    &amp;quot;local_address&amp;quot;: &amp;quot;127.0.0.1&amp;quot;,
    &amp;quot;local_port&amp;quot;: 1080
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;json&quot; class=&quot;language-json &quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;{
    &amp;quot;servers&amp;quot;: [
        {
            &amp;quot;server&amp;quot;: &amp;quot;127.0.0.1&amp;quot;,
            &amp;quot;server_port&amp;quot;: 8388,
            &amp;quot;password&amp;quot;: &amp;quot;rwQc8qPXVsRpGx3uW+Y3Lj4Y42yF9Bs0xg1pmx8&amp;#x2F;+bo=&amp;quot;,
            &amp;quot;method&amp;quot;: &amp;quot;aes-256-gcm&amp;quot;,
            &amp;quot;timeout&amp;quot;: 7200
        },
        {
            &amp;quot;server&amp;quot;: &amp;quot;127.0.0.1&amp;quot;,
            &amp;quot;server_port&amp;quot;: 8389,
            &amp;quot;password&amp;quot;: &amp;quot;&amp;#x2F;dliNXn5V4jg6vBW4MnC1I8Jljg9x7vSihmk6UZpRBM=&amp;quot;,
            &amp;quot;method&amp;quot;: &amp;quot;chacha20-ietf-poly1305&amp;quot;
        },
        {
            &amp;quot;disabled&amp;quot;: true,
            &amp;quot;server&amp;quot;: &amp;quot;eg.disable.me&amp;quot;,
            &amp;quot;server_port&amp;quot;: 8390,
            &amp;quot;password&amp;quot;: &amp;quot;mGvbWWay8ueP9IHnV5F1uWGN2BRToiVCAWJmWOTLU24=&amp;quot;,
            &amp;quot;method&amp;quot;: &amp;quot;chacha20-ietf-poly1305&amp;quot;
        }
    ],
    &amp;#x2F;&amp;#x2F; ONLY FOR `sslocal`
    &amp;#x2F;&amp;#x2F; Delete these lines if you are running `ssserver` or `ssmanager`
    &amp;quot;local_port&amp;quot;: 1080,
    &amp;quot;local_address&amp;quot;: &amp;quot;127.0.0.1&amp;quot;
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;yaml&quot; class=&quot;language-yaml &quot;&gt;&lt;code class=&quot;language-yaml&quot; data-lang=&quot;yaml&quot;&gt;refresh_rate: 30 seconds
appenders:
  stdout:
    kind: console
    encoder:
      pattern: &amp;quot;{d(%Y-%m-%d %H:%M:%S)} {h({l})} [{M}] - {m}{n}&amp;quot;
      # pattern: &amp;quot;{h({d(%+)(utc)} [{f}:{L}] {l:&amp;lt;6} {M}:{m})}{n}&amp;quot;
root:
  level: info
  appenders:
    - stdout
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;cargo build
RUST_LOG=debug target&amp;#x2F;debug&amp;#x2F;ssserver -c target&amp;#x2F;config.json
RUST_LOG=debug target&amp;#x2F;debug&amp;#x2F;sslocal -c target&amp;#x2F;config.json
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Linux Magic SysRq</title>
        <published>2025-07-24T09:39:55+08:00</published>
        <updated>2025-07-24T09:39:55+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/07/Linux Magic SysRq/"/>
        <id>https://vercel.juzhong.xyz/2025/07/Linux Magic SysRq/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/07/Linux Magic SysRq/">&lt;p&gt;在 Linux 中，Magic SysRq（Magic System Request）键 是一个组合键机制，用于在系统严重故障（如死机、挂起等）时发送低级命令给内核进行恢复或诊断操作。它能在几乎所有情况下（包括部分内核崩溃）执行，如同步磁盘、重启、杀死进程等。&lt;&#x2F;p&gt;
&lt;h1 id=&quot;qian-ti-tiao-jian-jian-cha&quot;&gt;前提条件检查&lt;&#x2F;h1&gt;
&lt;p&gt;内核是否编译支持Magic SysRq
检查当前运行状
0：全部禁用
1：全部启用
其他值（如 176、438）：按位启用（详见附录）&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;zcat &amp;#x2F;proc&amp;#x2F;config.gz | grep CONFIG_MAGIC_SYSRQ
cat &amp;#x2F;boot&amp;#x2F;config-$(uname -r) | grep -i config_magic_sysrq
cat &amp;#x2F;proc&amp;#x2F;sys&amp;#x2F;kernel&amp;#x2F;sysrq
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;fa-xing-ban-magic-sysrqshi-yong-qing-kuang&quot;&gt;发行版Magic SysRq使用情况&lt;&#x2F;h1&gt;
&lt;p&gt;很多Linux发行版中是默认启用的，但具体情况可能会有所不同。例如：&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Debian及其衍生发行版（如Ubuntu）通常默认开启Magic SysRq功能。&lt;&#x2F;li&gt;
&lt;li&gt;Arch Linux及其相关发行版（如Manjaro）则默认情况下不开启Magic SysRq功能，用户需要手动进行配置以启用它。
如果你不确定某个特定的Linux发行版是否默认启用了Magic SysRq，可以通过以下命令来检查当前系统的Magic SysRq状态：&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;cat &amp;#x2F;proc&amp;#x2F;sys&amp;#x2F;kernel&amp;#x2F;sysrq
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;如果输出为1，则表示所有Magic SysRq功能都已启用；如果输出为0，则表示SysRq被禁用。其他数值表示部分功能被启用，具体的数值含义可以参考内核文档或通过搜索引擎查找对应的解释。&lt;&#x2F;p&gt;
&lt;p&gt;要临时启用所有的Magic SysRq功能，可以使用以下命令：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;echo 1 | sudo tee &amp;#x2F;proc&amp;#x2F;sys&amp;#x2F;kernel&amp;#x2F;sysrq
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;对于永久性更改，可以在&#x2F;etc&#x2F;sysctl.conf文件中添加或者修改如下行：&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;kernel.sysrq = 1
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;然后运行sudo sysctl -p使更改生效，或者重启系统。不同的发行版可能有不同的配置文件位置和方法，请根据实际情况调整。&lt;&#x2F;p&gt;
&lt;h1 id=&quot;ru-he-shi-yong-magic-sysrq&quot;&gt;如何使用Magic SysRq&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;jian-pan-zu-he-fang-shi-ben-di-zhong-duan-shi-yong&quot;&gt;键盘组合方式(本地终端使用)&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text &quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;Alt + SysRq + &amp;lt;command_key&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;SysRq 键通常和 Print Screen 是同一个键
在笔记本上可能需要额外按 Fn 键&lt;&#x2F;p&gt;
&lt;p&gt;常见命令键列表（&amp;lt;command_key&amp;gt;）：&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;键&lt;&#x2F;th&gt;&lt;th&gt;功能&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;b&lt;&#x2F;td&gt;&lt;td&gt;立即重启系统（ReBoot）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;o&lt;&#x2F;td&gt;&lt;td&gt;立即关闭系统（pOwer off）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;s&lt;&#x2F;td&gt;&lt;td&gt;立刻将所有挂载的文件系统同步（Sync）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;u&lt;&#x2F;td&gt;&lt;td&gt;立刻将文件系统 remount 为只读（Umount）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;e&lt;&#x2F;td&gt;&lt;td&gt;向所有终端进程发送 SIGTERM（tErminate）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;i&lt;&#x2F;td&gt;&lt;td&gt;向所有终端进程发送 SIGKILL（kIll）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;r&lt;&#x2F;td&gt;&lt;td&gt;将键盘控制权从 X Server 还原到控制台（Raw mode）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;k&lt;&#x2F;td&gt;&lt;td&gt;杀死当前控制台上的所有进程（Kill）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;h&lt;&#x2F;td&gt;&lt;td&gt;显示可用命令帮助（Help）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;tong-guo-proc-sysrq-trigger-fa-song-ming-ling-yuan-cheng-shi-yong&quot;&gt;通过 &#x2F;proc&#x2F;sysrq-trigger 发送命令（远程使用）&lt;&#x2F;h2&gt;
&lt;p&gt;如果你是通过 SSH 或串口登录的，可以使用：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;echo &amp;lt;command_key&amp;gt; | sudo tee &amp;#x2F;proc&amp;#x2F;sysrq-trigger
echo b | sudo tee &amp;#x2F;proc&amp;#x2F;sysrq-trigger   # 立即重启
echo s | sudo tee &amp;#x2F;proc&amp;#x2F;sysrq-trigger   # 同步磁盘

&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;dian-xing-chang-jing-an-quan-zhong-qi-gua-si-xi-tong&quot;&gt;典型场景：安全重启挂死系统&lt;&#x2F;h1&gt;
&lt;p&gt;建议使用“REISUB”组合重启挂住的系统：&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;text&quot; class=&quot;language-text &quot;&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;Alt + SysRq + R
Alt + SysRq + E
Alt + SysRq + I
Alt + SysRq + S
Alt + SysRq + U
Alt + SysRq + B
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;含义如下：&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;步骤&lt;&#x2F;th&gt;&lt;th&gt;含义&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;R&lt;&#x2F;td&gt;&lt;td&gt;恢复键盘控制权&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;E&lt;&#x2F;td&gt;&lt;td&gt;终止所有进程&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;I&lt;&#x2F;td&gt;&lt;td&gt;杀死所有进程&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;S&lt;&#x2F;td&gt;&lt;td&gt;同步磁盘&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;U&lt;&#x2F;td&gt;&lt;td&gt;卸载磁盘（只读）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;B&lt;&#x2F;td&gt;&lt;td&gt;重启系统&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;每按一次组合键后，等1-2秒再继续下一步，确保命令有时间生效。&lt;&#x2F;p&gt;
&lt;h1 id=&quot;fu-lu-sysrq-an-wei-quan-xian-han-yi-dui-ying-proc-sys-kernel-sysrq&quot;&gt;附录：sysrq 按位权限含义（对应 &#x2F;proc&#x2F;sys&#x2F;kernel&#x2F;sysrq）&lt;&#x2F;h1&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;值&lt;&#x2F;th&gt;&lt;th&gt;功能&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;启用所有功能&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;控制进程的信号发送&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;挂载的文件系统 sync&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;立即重启或关机&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;16&lt;&#x2F;td&gt;&lt;td&gt;Dump tasks 信息&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;32&lt;&#x2F;td&gt;&lt;td&gt;设置日志等级&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;64&lt;&#x2F;td&gt;&lt;td&gt;终止进程&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;128&lt;&#x2F;td&gt;&lt;td&gt;Kill 当前控制台进程&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;常见值：
176 = 128 + 32 + 16：允许 kill、日志、重启&lt;&#x2F;p&gt;
&lt;p&gt;438 = 128 + 64 + 8 + 4 + 2 + 32：广泛启用但不包含 r&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;cat &amp;#x2F;proc&amp;#x2F;sys&amp;#x2F;kernel&amp;#x2F;sysrq | xxd -b
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>sing-box协议</title>
        <published>2025-07-19T22:55:57+08:00</published>
        <updated>2025-07-19T22:55:57+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/07/learn/sing-box协议/"/>
        <id>https://vercel.juzhong.xyz/2025/07/learn/sing-box协议/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/07/learn/sing-box协议/">&lt;h1 id=&quot;jian-cha-bing-kai-qi-bbr&quot;&gt;检查并开启BBR&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sysctl net.ipv4.tcp_congestion_control net.core.default_qdisc
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sysctl -w net.ipv4.tcp_congestion_control=bbr
sysctl -w net.core.default_qdisc=fq
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;sing-boxpei-zhi-wen-jian-jie-xi&quot;&gt;sing-box配置文件解析&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;json&quot; class=&quot;language-json &quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;&amp;quot;inbounds&amp;quot;: [
  {
    &amp;quot;tag&amp;quot;:&amp;quot;SS&amp;quot;,
    &amp;quot;type&amp;quot;: &amp;quot;shadowsocks&amp;quot;,
    &amp;quot;listen&amp;quot;: &amp;quot;::&amp;quot;,
    &amp;quot;listen_port&amp;quot;: 80,
    &amp;quot;method&amp;quot;: &amp;quot;2022-blake3-aes-128-gcm&amp;quot;, &amp;#x2F;&amp;#x2F; aes-128-gcm 密钥无限制
    &amp;quot;password&amp;quot;: &amp;quot;hztQCU1ZB8CAuPMVFJiCJw==&amp;quot;, &amp;#x2F;&amp;#x2F; 密钥长度16，sing-box执行 sing-box generate rand --base64 16 生成
    &amp;quot;multiplex&amp;quot;: {
        &amp;quot;enabled&amp;quot;: true
    }
  },
  {
    &amp;quot;tag&amp;quot;:&amp;quot;VLESS-Vision-Reality&amp;quot;,
    &amp;quot;type&amp;quot;:&amp;quot;vless&amp;quot;,
    &amp;quot;listen&amp;quot;:&amp;quot;::&amp;quot;,
    &amp;quot;listen_port&amp;quot;:443,
    &amp;quot;users&amp;quot;:[
        {
            &amp;quot;uuid&amp;quot;:&amp;quot;625a08bb-d372-4f7c-a2d4-6a50ca3393ce&amp;quot;, &amp;#x2F;&amp;#x2F; sing-box执行 sing-box generate uuid 生成
            &amp;quot;flow&amp;quot;:&amp;quot;xtls-rprx-vision&amp;quot;
        }
    ],
    &amp;quot;tls&amp;quot;:{
        &amp;quot;enabled&amp;quot;:true,
        &amp;quot;server_name&amp;quot;:&amp;quot;moe.syaronet.com&amp;quot;,
        &amp;quot;reality&amp;quot;:{
            &amp;quot;enabled&amp;quot;:true,
            &amp;quot;handshake&amp;quot;:{
                &amp;quot;server&amp;quot;:&amp;quot;moe.syaronet.com&amp;quot;, &amp;#x2F;&amp;#x2F; 要求网站支持 TLS 1.3、X25519 与 H2，域名非跳转用
                &amp;quot;server_port&amp;quot;:443
            },
            &amp;quot;private_key&amp;quot;:&amp;quot;mAQVEs96AtDg1V_b2POFVP8n-Uu6hBe0_1Zt-DtRzGE&amp;quot;, &amp;#x2F;&amp;#x2F; 执行 sing-box generate reality-keypair 生成，对应公钥放客户端
            &amp;quot;short_id&amp;quot;:[
                &amp;quot;a118b9425a7e2dc5&amp;quot; &amp;#x2F;&amp;#x2F; 执行 sing-box generate rand 8 --hex 生成
            ]
        }
    },
    &amp;quot;multiplex&amp;quot;:{
        &amp;quot;enabled&amp;quot;:true,
        &amp;quot;padding&amp;quot;:true,
        &amp;quot;brutal&amp;quot;:{
            &amp;quot;enabled&amp;quot;:true,
            &amp;quot;up_mbps&amp;quot;:800,
            &amp;quot;down_mbps&amp;quot;:100
        }
    }
  },
  {
    &amp;quot;tag&amp;quot;: &amp;quot;HYSTERIA2&amp;quot;,
    &amp;quot;type&amp;quot;: &amp;quot;hysteria2&amp;quot;,
    &amp;quot;listen&amp;quot;: &amp;quot;::&amp;quot;,
    &amp;quot;listen_port&amp;quot;: 52021,
    &amp;quot;obfs&amp;quot;: {
      &amp;quot;type&amp;quot;: &amp;quot;salamander&amp;quot;,
      &amp;quot;password&amp;quot;: &amp;quot;71c42203-ee95-44f9-97f2-3fefe254f223&amp;quot; &amp;#x2F;&amp;#x2F; sing-box执行 sing-box generate uuid 生成作为密码即可
    },
    &amp;quot;users&amp;quot;: [
      {
        &amp;quot;password&amp;quot;: &amp;quot;c36d52aa-12b0-420c-a409-02f0410f6ac4&amp;quot; &amp;#x2F;&amp;#x2F; sing-box执行 sing-box generate uuid 生成作为密码即可
      }
    ],
    &amp;quot;tls&amp;quot;: {
      &amp;quot;enabled&amp;quot;: true,
      &amp;quot;alpn&amp;quot;: [
        &amp;quot;h3&amp;quot;
      ],
      &amp;quot;certificate_path&amp;quot;: &amp;quot;&amp;#x2F;etc&amp;#x2F;ssl&amp;#x2F;yu.ykszckj.com&amp;#x2F;yu.ykszckj.com.crt&amp;quot;,
      &amp;quot;key_path&amp;quot;: &amp;quot;&amp;#x2F;etc&amp;#x2F;ssl&amp;#x2F;yu.ykszckj.com&amp;#x2F;yu.ykszckj.com.key&amp;quot;
    }
  }
],
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>开始使用zola博客</title>
        <published>2025-07-19T21:05:11+08:00</published>
        <updated>2025-07-19T21:05:11+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/07/开始使用zola博客/"/>
        <id>https://vercel.juzhong.xyz/2025/07/开始使用zola博客/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/07/开始使用zola博客/">&lt;h1 id=&quot;an-zhuang-zola&quot;&gt;安装zola&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git clone https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;getzola&amp;#x2F;zola.git
cd zola
cargo install --path . --locked
zola --version
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;pei-zhi-bo-ke&quot;&gt;配置博客&lt;&#x2F;h1&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;zola init blog
cd blog
git submodule add https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;salif&amp;#x2F;linkita.git themes&amp;#x2F;linkta
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;toml&quot; class=&quot;language-toml &quot;&gt;&lt;code class=&quot;language-toml&quot; data-lang=&quot;toml&quot;&gt;# The URL the site will be built for
base_url = &amp;quot;https:&amp;#x2F;&amp;#x2F;blog.example.com&amp;quot;

title = &amp;quot;peter的博客&amp;quot;
description = &amp;quot;学海无涯&amp;quot;
default_language = &amp;quot;zh&amp;quot;
generate_rss = true

# Whether to automatically compile all Sass files in the sass directory
compile_sass = false

# theme = &amp;quot;even&amp;quot;
theme = &amp;quot;linkita&amp;quot;

# Whether to do syntax highlighting
# Theme can be customised by setting the `highlight_theme` variable to a theme supported by Zola
highlight_code = true
highlight_theme = &amp;quot;monokai&amp;quot;

# Whether to build a search index to be used later on by a JavaScript library
build_search_index = false

ignored_content = [&amp;quot;*.sw?&amp;quot;]

taxonomies = [
    {name = &amp;quot;categories&amp;quot;, rss = true, paginate_by = 10},
    {name = &amp;quot;tags&amp;quot;, rss = false, paginate_by = 10},
]

[extra]
# Put all your custom variables here

[extra.author]
name = &amp;quot;peter xiaoli&amp;quot;
email = &amp;quot;moxuetianya@gmail.com&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;新建博客脚本&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash new.sh&quot; class=&quot;language-bash new.sh &quot;&gt;&lt;code class=&quot;language-bash new.sh&quot; data-lang=&quot;bash new.sh&quot;&gt;#!&amp;#x2F;bin&amp;#x2F;bash
# Copyright (c) 2025 peterxiaoli&amp;lt;moxuetianya@gmail.com&amp;gt;. All rights reserved.
# Use of this source is governed by General Public License that can be found
# in the LICENSE file.

set -xe
# Create a new article template.

ARTICLE=$1
if [ -z &amp;quot;${ARTICLE}&amp;quot; ]; then
  echo &amp;quot;Usage $0 article-name&amp;quot;
  exit 1
fi
TIMESTAMPE=$(date --rfc-3339=seconds)
FILENAME=&amp;quot;content&amp;#x2F;$(date +%Y-%m-%d)-${ARTICLE}.md&amp;quot;
URL_PATH=&amp;quot;$(date +%Y)&amp;#x2F;$(date +%m)&amp;#x2F;${ARTICLE}&amp;quot;
echo &amp;quot;TIMESTMAP: ${TIMESTAMPE}&amp;quot;
echo &amp;quot;FILENAME: ${FILENAME}&amp;quot;
echo &amp;quot;URL_PATH: ${URL_PATH}&amp;quot;

if [ ! -f &amp;quot;${FILENAME}&amp;quot; ]; then
  cat &amp;gt; &amp;quot;${FILENAME}&amp;quot; &amp;lt;&amp;lt; EOF
+++
title = &amp;quot;${ARTICLE}&amp;quot;
description = &amp;quot;&amp;quot;
date = ${TIMESTAMPE}
path = &amp;quot;${URL_PATH}&amp;quot;
[taxonomies]
categories = []
+++
EOF
fi
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>代码覆盖率</title>
        <published>2025-07-19T20:53:28+08:00</published>
        <updated>2025-07-19T20:53:28+08:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/07/代码覆盖率/"/>
        <id>https://vercel.juzhong.xyz/2025/07/代码覆盖率/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/07/代码覆盖率/">&lt;h1 id=&quot;dai-ma-fu-gai-lu-de-gong-zuo-fang-shi&quot;&gt;代码覆盖率的工作方式&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;source-code-instrumentation-yuan-dai-ma-jian-ce&quot;&gt;source code instrumentation - 源代码检测&lt;&#x2F;h2&gt;
&lt;p&gt;将检测豫剧添加到源代码中， 并使用正常的编译工具链编译代码生成检测的程序。
这是我们常说的茶庄， gcov 属于这一类的代码覆盖率工具&lt;&#x2F;p&gt;
&lt;h2 id=&quot;runtime-instrumentation-yun-xing-shi-shou-ji&quot;&gt;Runtime instrumentation - 运行时收集&lt;&#x2F;h2&gt;
&lt;p&gt;这种方法在代码执行时从运行时环境收集信息以确定覆盖率信息。以我的理解 JaCoCo 和 Coverage 这两个工具的原理属于这一类别。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;intermediate-code-instrumentation-zhong-jian-dai-ma-jian-ce&quot;&gt;Intermediate code instrumentation - 中间代码检测&lt;&#x2F;h2&gt;
&lt;p&gt;通过添加新的字节码来检测编译后的类文件，并生成一个新的检测类。说实话，我 Google 了很多文章并找到确定的说明哪个工具是属于这一类的。&lt;&#x2F;p&gt;
&lt;p&gt;了解这些工具的基本原理，结合现有的测试用例，有助于正确的选择代码覆盖率工具。比如：&lt;&#x2F;p&gt;
&lt;p&gt;产品的源代码只有 E2E（端到端）测试用例，通常只能选择第一类工具，即通过插桩编译出的可执行文件，然后进行测试和结果收集。
产品的源代码有单元测试用例，通常选择第二类工具，即运行时收集。这类工具的执行效率高，易于做持续集成。&lt;&#x2F;p&gt;
&lt;h1 id=&quot;dang-qian-zhu-liu-dai-ma-fu-gai-lu-gong-ju&quot;&gt;当前主流代码覆盖率工具&lt;&#x2F;h1&gt;
&lt;p&gt;代码覆盖率的工具有很多，以下是我用过的不同编程语言的代码覆盖率工具。在选择工具时，力求去选择那些开源、流行（活跃）、好用的工具。&lt;&#x2F;p&gt;
&lt;p&gt;|编程语言 |	代码覆盖率工具 |
| C&#x2F;C++	| Gcov |
|Java |	JaCoCo|
|JavaScript|	Istanbul|
|Python|	Coverage.py|
|Golang	|cover|&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>学习vless协议</title>
        <published>2025-07-19T00:00:00+00:00</published>
        <updated>2025-07-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/2025/07/learn/learn-vless/"/>
        <id>https://vercel.juzhong.xyz/2025/07/learn/learn-vless/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/2025/07/learn/learn-vless/">&lt;p&gt;VLESS数据结构根据开发者的介绍，如下所示。&lt;&#x2F;p&gt;
&lt;h1 id=&quot;qing-qiu-request&quot;&gt;请求 Request&lt;&#x2F;h1&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;1 字节&lt;&#x2F;th&gt;&lt;th&gt;16 字节&lt;&#x2F;th&gt;&lt;th&gt;1 字节&lt;&#x2F;th&gt;&lt;th&gt;M 字节&lt;&#x2F;th&gt;&lt;th&gt;1 字节&lt;&#x2F;th&gt;&lt;th&gt;2 字节&lt;&#x2F;th&gt;&lt;th&gt;1 字节&lt;&#x2F;th&gt;&lt;th&gt;S 字节&lt;&#x2F;th&gt;&lt;th&gt;X 字节&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;协议版本&lt;&#x2F;td&gt;&lt;td&gt;等价UUID&lt;&#x2F;td&gt;&lt;td&gt;附加信息长度M&lt;&#x2F;td&gt;&lt;td&gt;ProtoBuf&lt;&#x2F;td&gt;&lt;td&gt;指令&lt;&#x2F;td&gt;&lt;td&gt;端口&lt;&#x2F;td&gt;&lt;td&gt;地址类型&lt;&#x2F;td&gt;&lt;td&gt;地址&lt;&#x2F;td&gt;&lt;td&gt;请求数据&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h1 id=&quot;xiang-ying-response&quot;&gt;响应 Response&lt;&#x2F;h1&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;1 字节&lt;&#x2F;th&gt;&lt;th&gt;1 字节&lt;&#x2F;th&gt;&lt;th&gt;N 字节&lt;&#x2F;th&gt;&lt;th&gt;Y 字节&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;协议版本，与请求一致&lt;&#x2F;td&gt;&lt;td&gt;附加信息长度 N&lt;&#x2F;td&gt;&lt;td&gt;附加信息 ProtoBuf&lt;&#x2F;td&gt;&lt;td&gt;响应数据&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;相比其他传输协议，VLESS协议更加简洁，能够达到更加高效的数据传输，就以往的经验来说，其主要优势在于：&lt;&#x2F;p&gt;
&lt;p&gt;VLESS协议不依赖于系统时间，在Windows+Linux双系统环境下，可以不再困扰于时区时差；
VLESS协议在传输数据时不会加密数据，配合其他加密传输协议使用时可以达到更高的性能；
允许进行回落，可以将接收到的非代理数据进行转发，无需另外架设转发服务；
VLESS协议在未来可能出现统一的导出格式，方便在各个终端间传递使用。&lt;&#x2F;p&gt;
&lt;h1 id=&quot;pei-zhi-wiresharkcha-jian&quot;&gt;配置wireshark插件&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;linux 中 wireshark 4.2.2版本&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;cp .&amp;#x2F;vless.lua &amp;#x2F;usr&amp;#x2F;share&amp;#x2F;wireshark&amp;#x2F;vless.lua
# or cp .&amp;#x2F;vless.lua ~&amp;#x2F;.config&amp;#x2F;wireshark&amp;#x2F;vless.lua
echo &amp;#x27;dofile(DATA_DIR..&amp;quot;&amp;#x2F;vless.lua&amp;quot;)&amp;#x27; | sudo tee -a &amp;#x2F;usr&amp;#x2F;lib&amp;#x2F;x86_64-linux-gnu&amp;#x2F;wireshark&amp;#x2F;plugins&amp;#x2F;init.lua
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;linux 中 wireshark 4.0.17版本&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;cp .&amp;#x2F;vless.lua &amp;#x2F;usr&amp;#x2F;share&amp;#x2F;wireshark&amp;#x2F;vless.lua
echo &amp;#x27;dofile(DATA_DIR..&amp;quot;&amp;#x2F;vless.lua&amp;quot;)&amp;#x27; | sudo tee -a &amp;#x2F;usr&amp;#x2F;share&amp;#x2F;wireshark&amp;#x2F;init.lua
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;wireshark中【分析】-&amp;gt; 【重新载入lua插件】&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;2025&#x2F;07&#x2F;wireshark%E6%8F%92%E4%BB%B6%20%E8%A7%A3%E6%9E%90%E8%87%AA%E5%AE%9A%E4%B9%89%E5%8D%8F%E8%AE%AE&#x2F;#pei-zhi-luajiao-ben&quot;&gt;wireshark 插件配置&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;code&#x2F;vless.lua?encoding=UTF-8&quot;&gt;vless wireshark插件文件&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.v2fly.org&#x2F;developer&#x2F;protocols&#x2F;vmess.html&quot;&gt;vmess&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;xtls.github.io&#x2F;development&#x2F;protocols&#x2F;vless.html&quot;&gt;vless&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>归档</title>
        <published>2025-07-14T00:00:00+00:00</published>
        <updated>2025-07-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              moxuetianya
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://vercel.juzhong.xyz/archive/"/>
        <id>https://vercel.juzhong.xyz/archive/</id>
        
        <content type="html" xml:base="https://vercel.juzhong.xyz/archive/"></content>
        
    </entry>
</feed>
