<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>XuLog</title>
        <link>https://xulog.com/</link>
        <description>Xu’s Log</description>
        <lastBuildDate>Wed, 11 Feb 2026 09:30:32 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en-US</language>
        <copyright>All rights reserved 2026, XGFan</copyright>
        <item>
            <title><![CDATA[Shairport-Sync in Home Assistant]]></title>
            <link>https://xulog.com/article/shairport-sync-in-home-assistant</link>
            <guid>https://xulog.com/article/shairport-sync-in-home-assistant</guid>
            <pubDate>Tue, 30 Sep 2025 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-27e30f9b5b2280c487b8da671bfecf55"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><h4 class="notion-h notion-h3 notion-h-indent-0 notion-block-27e30f9b5b228046a248c06e96b1f954" data-id="27e30f9b5b228046a248c06e96b1f954"><span><div id="27e30f9b5b228046a248c06e96b1f954" class="notion-header-anchor"></div><a class="notion-hash-link" href="#27e30f9b5b228046a248c06e96b1f954" title="背景"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">背景</span></span></h4><div class="notion-text notion-block-27e30f9b5b2280eb8fafe6bf088b43a7">之前一直是使用一个树莓派5+Shairport-Sync搭配小米的音箱来实现AirPlay，现在树莓派5安装了Home Assistant系统，没有办法<s>简单的</s>直接跑docker了，所以有了如下的折腾。</div><h4 class="notion-h notion-h3 notion-h-indent-0 notion-block-27e30f9b5b228031bb9ae11754ea6ce3" data-id="27e30f9b5b228031bb9ae11754ea6ce3"><span><div id="27e30f9b5b228031bb9ae11754ea6ce3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#27e30f9b5b228031bb9ae11754ea6ce3" title="Add-on"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Add-on</span></span></h4><div class="notion-text notion-block-27e30f9b5b228031aa36ed9b59b2baf9">HA的add-on实际上就是一个docker容器，但是限制非常多，没有办法直接挂载声卡（小米音箱）进去，就算采用<code class="notion-inline-code">full_access:true</code> 也会遇到和<code class="notion-inline-code">hassio_audio</code>抢声卡的问题。所以只能使用ha的audio能力来使用pulse播放音频。</div><h4 class="notion-h notion-h3 notion-h-indent-0 notion-block-27e30f9b5b22801095cec4cbed6e91cd" data-id="27e30f9b5b22801095cec4cbed6e91cd"><span><div id="27e30f9b5b22801095cec4cbed6e91cd" class="notion-header-anchor"></div><a class="notion-hash-link" href="#27e30f9b5b22801095cec4cbed6e91cd" title="Pulse音量调节"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Pulse音量调节</span></span></h4><div class="notion-text notion-block-27e30f9b5b2280ba8760db71f092f95a">小米音箱有自己的音量调节，在裸机上使用<code class="notion-inline-code">shairport-sync</code>的时候，能够通过amixer来联动音量（即按键调节和软件调节的是同一个音量）。但现在通过pulse调节音量就无法与按键联动（即按键调节音量为60%，那软件音量就是在60%当作100%的基础上去调节）。</div><div class="notion-text notion-block-27e30f9b5b2280799798cdd226a48b45">所以，需要在<code class="notion-inline-code">hassio_audio</code>容器内做相应的修改，修改配置文件件 <code class="notion-inline-code">/usr/share/pulseaudio/alsa-mixer/paths/analog-output.conf</code></div><h4 class="notion-h notion-h3 notion-h-indent-0 notion-block-27e30f9b5b22805c967adb9731e797a2" data-id="27e30f9b5b22805c967adb9731e797a2"><span><div id="27e30f9b5b22805c967adb9731e797a2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#27e30f9b5b22805c967adb9731e797a2" title="shairport-sync音量调节"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">shairport-sync音量调节</span></span></h4><div class="notion-text notion-block-27e30f9b5b2280dd9796d4cc8f150479">现在对于shairport来说，音频是从alsa-pulse来播放的，音量调节直接使用容器内唯一的mixer</div><div class="notion-text notion-block-27e30f9b5b2280deb91bc73bf6c80e06">但是这个mixer有一个严重的问题，没有db刻度，导致<code class="notion-inline-code">shairport-sync</code>无法直接调节。</div><div class="notion-text notion-block-27e30f9b5b2280cfa952dce1547af644">想过很多办法，比如fake一个mixer来提供db刻度、修改pulse或者alsa的配置等等，都没有成功。</div><div class="notion-text notion-block-27e30f9b5b22804da071d0630fa6897d">最终选择了修改<code class="notion-inline-code">shairport-sync</code>的<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/XGFan/shairport-sync-ha">源码</a>(包含add-on代码)。</div><h4 class="notion-h notion-h3 notion-h-indent-0 notion-block-27e30f9b5b2280269ab0c070f03b7271" data-id="27e30f9b5b2280269ab0c070f03b7271"><span><div id="27e30f9b5b2280269ab0c070f03b7271" class="notion-header-anchor"></div><a class="notion-hash-link" href="#27e30f9b5b2280269ab0c070f03b7271" title="声卡占用"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">声卡占用</span></span></h4><div class="notion-text notion-block-27e30f9b5b2280799d93c3672f1ec3eb">后面又发现ha的一个问题，小米音箱只要连上ha，就会处于播放状态，led灯一直在闪，而且小爱也很难唤醒。</div><div class="notion-text notion-block-27e30f9b5b22804fbabccb280af9a34f">发现还是<code class="notion-inline-code">hassio_audio</code>的问题，需要加上一个pulse module，在<code class="notion-inline-code">/etc/pulse/system.pa</code>上加入如下片段，使其在不播放的5秒后释放占用。</div><h4 class="notion-h notion-h3 notion-h-indent-0 notion-block-27e30f9b5b2280fda513e242f7bbd16f" data-id="27e30f9b5b2280fda513e242f7bbd16f"><span><div id="27e30f9b5b2280fda513e242f7bbd16f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#27e30f9b5b2280fda513e242f7bbd16f" title="持久化hassio_audio"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">持久化hassio_audio</span></span></h4><div class="notion-text notion-block-27e30f9b5b2280f39f25d06c9c484d67">没有查到好的办法，发现<code class="notion-inline-code"><b>Advanced SSH &amp; Web Terminal</b></code><b> </b>这个add-on支持init脚本（即add-on启动时执行的脚本），就加上了脚本去修改hassio_audio</div><div class="notion-blank notion-block-27e30f9b5b22803ea887c0753fb423a4"> </div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Build SPI image for Radxa Rock 5C]]></title>
            <link>https://xulog.com/article/21d30f9b-5b22-8096-b6e0-c53a943456a3</link>
            <guid>https://xulog.com/article/21d30f9b-5b22-8096-b6e0-c53a943456a3</guid>
            <pubDate>Wed, 25 Jun 2025 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-21d30f9b5b228096b6e0c53a943456a3"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-text notion-block-21d30f9b5b2280e098a3dafbe601fbc5">准确的说，是Rock 5C lite，Armbian提供的U-Boot能解锁核心，GPU，编解码器。但是没有提供SPI Flash的U-Boot，就没办法使用SPI模块，只能用emmc或者TF引导M2硬盘的系统。</div><div class="notion-text notion-block-21d30f9b5b2280a2bad4c22690e8face">虽然我有TF卡/emmc模块，但是前两天我花钱买了SPI flash，必须得用上。</div><div class="notion-text notion-block-21d30f9b5b22800eb1bfff39060e9ffb">刷上Radxa官方的<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://dl.radxa.com/rock5/5c/images/loader/spi/rock-5c-spi-image-20240528.img">SPI image</a>之后，确实能启动，但是CPU变成6核了，编解码器没了，GPU没了。</div><div class="notion-text notion-block-21d30f9b5b2280b68d77dbb7c061a3fb">尝试过很多方案：</div><h4 class="notion-h notion-h3 notion-h-indent-0 notion-block-21d30f9b5b2280098e99fe4d5e7e8d4e" data-id="21d30f9b5b2280098e99fe4d5e7e8d4e"><span><div id="21d30f9b5b2280098e99fe4d5e7e8d4e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#21d30f9b5b2280098e99fe4d5e7e8d4e" title="armbian-install"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">armbian-install</span></span></h4><div class="notion-text notion-block-21d30f9b5b22800c8b3fdf6f952f02c6">采用armbian-install来安装U-Boot到MTD，但是这个脚本实际上是就是去/usr/lib/linux-u-boot-*-rock-5c目录下找spi.img，但是armbian仓库里的这个包并没有附带spi.img</div><h4 class="notion-h notion-h3 notion-h-indent-0 notion-block-21d30f9b5b2280b0871cf77c8bd2d957" data-id="21d30f9b5b2280b0871cf77c8bd2d957"><span><div id="21d30f9b5b2280b0871cf77c8bd2d957" class="notion-header-anchor"></div><a class="notion-hash-link" href="#21d30f9b5b2280b0871cf77c8bd2d957" title="idbloader.img + u-boot.itb"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">idbloader.img + u-boot.itb</span></span></h4><div class="notion-text notion-block-21d30f9b5b2280fa8b50ccba302c2a13">不管是按照AI教的两个文件直接合并，还是按照<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://wiki.radxa.com/Rock5/guide/build-u-boot-on-5b">相关文档查的offset</a>，写入之后都无法启动。</div><h4 class="notion-h notion-h3 notion-h-indent-0 notion-block-21d30f9b5b22801982aed7d44894e9c1" data-id="21d30f9b5b22801982aed7d44894e9c1"><span><div id="21d30f9b5b22801982aed7d44894e9c1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#21d30f9b5b22801982aed7d44894e9c1" title="dump from emmc"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">dump from emmc</span></span></h4><div class="notion-text notion-block-21d30f9b5b2280dbbc22ce93c6ee2894">dump出emmc的前16M内容，写到MTD里面去。依然无法启动。</div><h4 class="notion-h notion-h3 notion-h-indent-0 notion-block-21d30f9b5b22804583bce1a1ec5d4bc7" data-id="21d30f9b5b22804583bce1a1ec5d4bc7"><span><div id="21d30f9b5b22804583bce1a1ec5d4bc7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#21d30f9b5b22804583bce1a1ec5d4bc7" title="最终方案"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">最终方案</span></span></h4><div class="notion-text notion-block-21d30f9b5b22804ab460d5eba09aec9f">最终AI帮我分析，上面刷入的，都是能加载idbloader，但是idbloader不识别spi flash，所有如下的错误信息</div><div class="notion-text notion-block-21d30f9b5b2280af9115f9b0e71550e9">所以，最终成功的方案是，用Radxa的U-Boot包，在写入到MTD之前，用Armbian的u-boot.itb替换掉Radxa的。</div><div class="notion-text notion-block-21d30f9b5b2280a7a595e66c502b06fb">相关连接:
<span class="notion-link-mention"><a href="https://docs.radxa.com/en/rock5/rock5c/low-level-dev/u-boot" target="_blank" rel="noopener noreferrer" class="notion-link-mention-link"><img class="notion-link-mention-icon" src="https://docs.radxa.com/en/img/favicon.ico"/><span class="notion-link-mention-title">U-boot Development | Radxa Docs</span></a><div class="notion-link-mention-preview"><article class="notion-link-mention-card"><img class="notion-link-mention-preview-thumbnail" alt="U-boot Development | Radxa Docs" referrerPolicy="same-origin"/><div class="notion-link-mention-preview-content"><p class="notion-link-mention-preview-title">U-boot Development | Radxa Docs</p><p class="notion-link-mention-preview-description">bsp is a set of tools provided by Radxa to quickly build U-Boot Kernels. It is very easy to build your own U-Boot and Kernel using bsp.</p><div class="notion-link-mention-preview-footer"><img class="notion-link-mention-preview-icon" src="https://docs.radxa.com/en/img/favicon.ico" referrerPolicy="same-origin"/><span class="notion-link-mention-preview-provider"></span></div></div></article></div></span></div><div class="notion-text notion-block-21d30f9b5b2280b79100e32a0b04d464"><span class="notion-link-mention"><a href="https://radxa-repo.github.io/bsp/firmware/setup_sh.html#setupsh-update_spinor-mtd_device" target="_blank" rel="noopener noreferrer" class="notion-link-mention-link"><img class="notion-link-mention-icon" src="https://radxa-repo.github.io/bsp/favicon.svg"/><span class="notion-link-mention-title">setup.sh usage - bsp</span></a><div class="notion-link-mention-preview"><article class="notion-link-mention-card"><img class="notion-link-mention-preview-thumbnail" alt="setup.sh usage - bsp" referrerPolicy="same-origin"/><div class="notion-link-mention-preview-content"><p class="notion-link-mention-preview-title">setup.sh usage - bsp</p><p class="notion-link-mention-preview-description">Under each board&#x27;s directory, there are a few binary blobs, along with a maintenance script called setup.sh, which provides a wrapper for common management tasks.</p><div class="notion-link-mention-preview-footer"><img class="notion-link-mention-preview-icon" src="https://radxa-repo.github.io/bsp/favicon.svg" referrerPolicy="same-origin"/><span class="notion-link-mention-preview-provider"></span></div></div></article></div></span></div><div class="notion-blank notion-block-21d30f9b5b228081b74ccd36efa78b19"> </div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[客户机接入终极方案]]></title>
            <link>https://xulog.com/article/12a30f9b-5b22-8063-985e-f74bf3f938bf</link>
            <guid>https://xulog.com/article/12a30f9b-5b22-8063-985e-f74bf3f938bf</guid>
            <pubDate>Thu, 31 Oct 2024 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-12a30f9b5b228063985ef74bf3f938bf"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-text notion-block-12a30f9b5b22802bb91df1dcaca9c584">最近开始在家办公了，家里桌子很小，如果还是两台电脑中间插根网线的话，桌子会非常乱。</div><div class="notion-text notion-block-12a30f9b5b2280549d05d3d422840769">而且上一个方案有很多小问题：</div><ol start="1" class="notion-list notion-list-numbered notion-block-12a30f9b5b228069bd67fd32a9bf7e1d" style="list-style-type:decimal"><li>Openwrt会经常让直通的USB网卡进入DOWN的状态</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-12a30f9b5b2280ca95c6cad01780fd76" style="list-style-type:decimal"><li>USB网卡有时候直接断开连接，表现是在宿主机和虚拟机都找不到这个设备</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-12a30f9b5b2280db86add43ec83adff6" style="list-style-type:decimal"><li>宿主机Windows偶尔会被客户组策略强制重启</li></ol><div class="notion-text notion-block-12a30f9b5b2280799a43da2965a982ec">问题1可以通过写脚本自动检查来重启网络解决，问题2只能靠物理重新插拔，问题3则无解。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-12a30f9b5b2280fe8329fc1a8aa38340" data-id="12a30f9b5b2280fe8329fc1a8aa38340"><span><div id="12a30f9b5b2280fe8329fc1a8aa38340" class="notion-header-anchor"></div><a class="notion-hash-link" href="#12a30f9b5b2280fe8329fc1a8aa38340" title="设计方案"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">设计方案</span></span></h3><div class="notion-text notion-block-12a30f9b5b22806190a0f7d8ad73a494">首先解决问题3，因为所有问题2可以靠重启解决😂。所以需要一个KVM，廉价解决方案是PiKVM，垃圾佬解决方案是玩客云。</div><div class="notion-text notion-block-12a30f9b5b2280ee96bacd3bbaedd577">用到KVM之后，发现了Linux USB Gadget这个玩意儿，可以模拟网卡。便有了一个大胆的想法，在Bridge这个设备上，模拟出两个USB设备，一个是键鼠，给宿主机Windows使用。一个是USB网卡，直通给虚拟机。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-12a30f9b5b2280e6bd37c399013ac476"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Fe185819e-76b9-458a-8b3b-3f602dc85a0e%2F5e1b0122-3516-4aa2-8b2e-792587a3e985%2Fimage.png?table=block&amp;id=12a30f9b-5b22-80e6-bd37-c399013ac476&amp;t=12a30f9b-5b22-80e6-bd37-c399013ac476&amp;width=707.9921875&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><blockquote class="notion-quote notion-block-12a30f9b5b228040bb6ef8afb66b3616"><div><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://excalidraw.com/#json=bicJFCq-asnFYMveXIDuR,o18QzAxdzmlY-Ub_MG66yA">原图</a></div></blockquote><div class="notion-text notion-block-12a30f9b5b228028b9c4c36ba6401260">然后在Bridge上，将这个USB网卡与Bridge接入的虚拟机网络桥接。然后在路由器上直接将客户网段的网关指向VM的IP。</div><div class="notion-text notion-block-12a30f9b5b22806fbef1cd6a15cb00e1">这样问题2的方案也能快速解决，只需要在Bridge上重置USB Gadget，就能起到物理重新插拔的效果。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-12a30f9b5b228050838de11659afe7f2" data-id="12a30f9b5b228050838de11659afe7f2"><span><div id="12a30f9b5b228050838de11659afe7f2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#12a30f9b5b228050838de11659afe7f2" title="遇到的问题"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">遇到的问题</span></span></h3><ol start="1" class="notion-list notion-list-numbered notion-block-12a30f9b5b228043ab64f310bb0b0656" style="list-style-type:decimal"><li>Linux USB Gadget模拟的是一个多功能设备，并不是多个物理设备，没办法只选择其中一个设备直通，只能全部直通或者不直通。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-12a30f9b5b2280999b05f39824d16ebc" style="list-style-type:decimal"><li>Bridge是要桥接的是一个无线网卡，无线网卡桥接有很多限制，也很复杂（反正就是一通操作，没搞成</li></ol><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-12a30f9b5b2280b9840fcaa31b56df91" data-id="12a30f9b5b2280b9840fcaa31b56df91"><span><div id="12a30f9b5b2280b9840fcaa31b56df91" class="notion-header-anchor"></div><a class="notion-hash-link" href="#12a30f9b5b2280b9840fcaa31b56df91" title="最终方案"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">最终方案</span></span></h3><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-12a30f9b5b2280fab25ee04c21dfb9c2"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Fe185819e-76b9-458a-8b3b-3f602dc85a0e%2F61a50685-48a9-48f1-845d-de5401c1302b%2Fimage.png?table=block&amp;id=12a30f9b-5b22-80fa-b25e-e04c21dfb9c2&amp;t=12a30f9b-5b22-80fa-b25e-e04c21dfb9c2&amp;width=707.9921875&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><blockquote class="notion-quote notion-block-12a30f9b5b22804d81cec7ebf0e93e83"><div><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://excalidraw.com/#json=bicJFCq-asnFYMveXIDuR,o18QzAxdzmlY-Ub_MG66yA">原图</a></div></blockquote><div class="notion-text notion-block-12a30f9b5b2280a78113f0d0bcdd4c8c">改动如下：</div><ol start="1" class="notion-list notion-list-numbered notion-block-12a30f9b5b228042a1f8f0d0497c61b5" style="list-style-type:decimal"><li>OpenWRT换成Linux，直接用iptables，更易于排查问题，而且驱动问题好解决</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-12a30f9b5b2280e8aa93f567cdff7a3d" style="list-style-type:decimal"><li>配上了一个USB Wi-Fi Adapter，直通给VM用来做backup</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-12a30f9b5b22806c8509c031030b66d6" style="list-style-type:decimal"><li>网关改成Bridge，由Bridge来决定是走USB Net(192.168.168.101)还是走Wi-Fi(192.168.2.101)</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-12a30f9b5b228088bd8dfa85507b3177" style="list-style-type:decimal"><li>分成两个USB Gadget，日常模拟成网卡，需要维护的时候，切换成键鼠模式，使用不同的VID/PID，避免键鼠被直通，导致Windows只能看不能操作。</li></ol><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-12a30f9b5b2280ce89f1cac97c607231" data-id="12a30f9b5b2280ce89f1cac97c607231"><span><div id="12a30f9b5b2280ce89f1cac97c607231" class="notion-header-anchor"></div><a class="notion-hash-link" href="#12a30f9b5b2280ce89f1cac97c607231" title="Bridge的网卡配置"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Bridge的网卡配置</span></span></h4><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-12a30f9b5b22805bb75bff42923f7aad" data-id="12a30f9b5b22805bb75bff42923f7aad"><span><div id="12a30f9b5b22805bb75bff42923f7aad" class="notion-header-anchor"></div><a class="notion-hash-link" href="#12a30f9b5b22805bb75bff42923f7aad" title="VM的网卡配置"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">VM的网卡配置</span></span></h4><div class="notion-text notion-block-12a30f9b5b228061ae29fba302774648">当Wi-Fi断开时，在Mac上</div><div class="notion-text notion-block-12a30f9b5b22807c9292d52392b75eeb">当USB断开时，</div><div class="notion-text notion-block-12a30f9b5b228002a8eef51fee263d91">当两条链路都通时</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-13030f9b5b2280539fedddc934ce7678" data-id="13030f9b5b2280539fedddc934ce7678"><span><div id="13030f9b5b2280539fedddc934ce7678" class="notion-header-anchor"></div><a class="notion-hash-link" href="#13030f9b5b2280539fedddc934ce7678" title="维护模式"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">维护模式</span></span></h4><div class="notion-text notion-block-12a30f9b5b2280ed8268e01f2455e434">关闭USB网卡模拟，开启KVMD，在Windows进行维护。</div><div class="notion-text notion-block-12a30f9b5b2280e7877bc9db171878d4">终于，现在可以把客户机和Bridge（实际上是一台Rock 5C Lite），塞在家里任何一个角落，只要其他设备连上了家里局域网，就能正常访问内网无阻。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-22a30f9b5b22804a8f64f34e47fdb629" data-id="22a30f9b5b22804a8f64f34e47fdb629"><span><div id="22a30f9b5b22804a8f64f34e47fdb629" class="notion-header-anchor"></div><a class="notion-hash-link" href="#22a30f9b5b22804a8f64f34e47fdb629" title="Update"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Update</span></span></h4><div class="notion-text notion-block-22a30f9b5b2280faa787e081897c3603">后续改动是：</div><ol start="1" class="notion-list notion-list-numbered notion-block-22a30f9b5b22806c8f03eefaa19a4e0e" style="list-style-type:decimal"><li>设备换成Rock 3A，原因是价格便宜。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-22a30f9b5b2280969eccd7b7f2564481" style="list-style-type:decimal"><li>KVMD采用CH9329，而不是USB Gadget。因为OneKVM只需要模拟键盘和鼠标就够了。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-22a30f9b5b2280aabfb8e85e06762482" style="list-style-type:decimal"><li>修改了Bridge的路由，不由netplan控制，而是交由脚本控制，每15秒ping一次VM。</li><ol class="notion-list notion-list-numbered notion-block-22a30f9b5b2280aabfb8e85e06762482" style="list-style-type:lower-alpha"><li>如果USB线路是通的，就添加USB线路的路由。</li><li>如果无线网卡是通的，就添加无线网卡的路由。</li><li>如果都不通，就报警。</li><div class="notion-text notion-block-22a30f9b5b228069a9c9f23b7c6afb29">这样KVMD和USB网络就能共存，维护起来会更加方便。</div></ol></ol><ol start="4" class="notion-list notion-list-numbered notion-block-22a30f9b5b22802eab89c9c678a3b766" style="list-style-type:decimal"><li>在VM里面添加网络检测脚本， 每5秒检查一下WIFI，如果不通，就usbreset之后再重新netplan apply</li></ol></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Pi5 + F50 移动路由]]></title>
            <link>https://xulog.com/article/21630f9b-5b22-80c6-af4f-dc65255a626a</link>
            <guid>https://xulog.com/article/21630f9b-5b22-80c6-af4f-dc65255a626a</guid>
            <pubDate>Wed, 18 Jun 2025 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-21630f9b5b2280c6af4fdc65255a626a"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-text notion-block-21630f9b5b22800bbda8f5c2e5057b8f">最近购入一台中兴F50，需要放在新房里代替宽带用几个月。直接用F50的WIFI热点，性能可能会是瓶颈，所以需要一台额外的设备来充当网关，把F50当成一张网卡。目前手中只有树莓派5能做这个事情，因为F50不带电池，启动时需要靠USB的电力，很多设备的USB供电是不足的。（比如Radxa家的所有板子）</div><div class="notion-text notion-block-21630f9b5b22807ea159d6fd8a476244">方案就是F50的USB网卡透传给Openwrt作为WAN口，Openwrt的LAN口则是从树莓派桥接的千兆网口。</div><div class="notion-text notion-block-21630f9b5b22803f8adae1e614726293">选择使用LXC来跑Openwrt（实际上是一个很烂的方案），带来了一些问题需要解决。</div><h4 class="notion-h notion-h3 notion-h-indent-0 notion-block-21630f9b5b22803b9656fdeac0088ee4" data-id="21630f9b5b22803b9656fdeac0088ee4"><span><div id="21630f9b5b22803b9656fdeac0088ee4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#21630f9b5b22803b9656fdeac0088ee4" title="USB断开重连"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">USB断开重连</span></span></h4><div class="notion-text notion-block-21630f9b5b22805d9ac7e1eb3f9a5b0d">LXC分配一个物理网卡（F50），如果F50 USB断开重连，LXC容器内部的网卡会消失，而且不会自动恢复。</div><div class="notion-text notion-block-21630f9b5b2280f3bba8d4a2df0769a9">解决方案：udev rule</div><div class="notion-text notion-block-21630f9b5b2280eda074e264046671a8">当插入网卡时，识别到网卡ADD事件，就调用lxc命令，将device“设置”进去。</div><h4 class="notion-h notion-h3 notion-h-indent-0 notion-block-21630f9b5b2280568ff1f0f81178e007" data-id="21630f9b5b2280568ff1f0f81178e007"><span><div id="21630f9b5b2280568ff1f0f81178e007" class="notion-header-anchor"></div><a class="notion-hash-link" href="#21630f9b5b2280568ff1f0f81178e007" title="开机启动"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">开机启动</span></span></h4><div class="notion-text notion-block-21630f9b5b2280cb947efdb37349c891">采用systemd，而不是lxc自己的autostart，因为开机时，网卡可能还没准备好。</div><div class="notion-blank notion-block-21830f9b5b22806a90c7f441566a6d39"> </div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Tailscale End-to-End Network]]></title>
            <link>https://xulog.com/article/16630f9b-5b22-8032-bcba-ef648d190fa5</link>
            <guid>https://xulog.com/article/16630f9b-5b22-8032-bcba-ef648d190fa5</guid>
            <pubDate>Wed, 25 Dec 2024 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-16630f9b5b228032bcbaef648d190fa5"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-text notion-block-16630f9b5b22808c9738da9866044914">家里局域网内有一堆设备，然后又有VPS在美国、香港，加上移动设备。现在目标是，使其都在一个大内网。</div><div class="notion-text notion-block-16630f9b5b2280b6a4cdf85eebc9154a">使用 <a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://tailscale.com/kb/1019/subnets">Tailscale Subnet route</a> 能够做到，在VPS、移动设备上访问家庭内网。但是没有办法在家庭内网直接访问移动设备、VPS。</div><div class="notion-text notion-block-16630f9b5b2280fb990bf0928ae876c2">而且这种方式，经过了Tailscale节点的NAT，其源IP已经丢失。所以需要关闭NAT。</div><h4 class="notion-h notion-h3 notion-h-indent-0 notion-block-16730f9b5b22804caf2fc07df46b9912" data-id="16730f9b5b22804caf2fc07df46b9912"><span><div id="16730f9b5b22804caf2fc07df46b9912" class="notion-header-anchor"></div><a class="notion-hash-link" href="#16730f9b5b22804caf2fc07df46b9912" title="Tailscale Console"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Tailscale Console</span></span></h4><div class="notion-text notion-block-16730f9b5b2280ecac6bea4645f4c3d0">设置好Tailscale网络的IP Pool，尽可能的小。</div><div class="notion-blank notion-block-16730f9b5b22806eb982dbe5c52dddd4"> </div><h4 class="notion-h notion-h3 notion-h-indent-0 notion-block-16630f9b5b22807bbdfef52b77c5e5d9" data-id="16630f9b5b22807bbdfef52b77c5e5d9"><span><div id="16630f9b5b22807bbdfef52b77c5e5d9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#16630f9b5b22807bbdfef52b77c5e5d9" title="Tailscale 节点"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Tailscale 节点</span></span></h4><div class="notion-text notion-block-16630f9b5b228059a40ae2db9ea43fda">需要在局域网内的Tailscale节点上关闭SNAT，加上一个简单参数即可</div><h4 class="notion-h notion-h3 notion-h-indent-0 notion-block-16630f9b5b22807bafb3fb112663aecf" data-id="16630f9b5b22807bafb3fb112663aecf"><span><div id="16630f9b5b22807bafb3fb112663aecf" class="notion-header-anchor"></div><a class="notion-hash-link" href="#16630f9b5b22807bafb3fb112663aecf" title="路由器"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">路由器</span></span></h4><div class="notion-text notion-block-16630f9b5b22807ca31cc3c598dcb1c6">需要在路由器上配置相应的静态路由，使相应的流量走到Tailscale的节点。</div><div class="notion-blank notion-block-16730f9b5b22807f8ffdf544e731c3b1"> </div><div class="notion-text notion-block-16730f9b5b2280e0bf9bfbb925850e0f">然后也需要关闭NAT</div><div class="notion-blank notion-block-16730f9b5b2280c0b134c190cbda515f"> </div><h4 class="notion-h notion-h3 notion-h-indent-0 notion-block-16730f9b5b2280f9a0c0d73cfe3249e0" data-id="16730f9b5b2280f9a0c0d73cfe3249e0"><span><div id="16730f9b5b2280f9a0c0d73cfe3249e0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#16730f9b5b2280f9a0c0d73cfe3249e0" title="表现"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">表现</span></span></h4><div class="notion-text notion-block-16730f9b5b228081afebc5bc9d153867">这样之后，在家里网络和Tailscale Network就完全互通了，相互之间访问的Source IP和Remote IP都是正常的。</div><div class="notion-blank notion-block-21630f9b5b2280b49c17fb6ca0ed9f00"> </div><h4 class="notion-h notion-h3 notion-h-indent-0 notion-block-21630f9b5b2280e19069f7cbbe79e2c8" data-id="21630f9b5b2280e19069f7cbbe79e2c8"><span><div id="21630f9b5b2280e19069f7cbbe79e2c8" class="notion-header-anchor"></div><a class="notion-hash-link" href="#21630f9b5b2280e19069f7cbbe79e2c8" title="Tailscale节点路由冲突"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Tailscale节点路由冲突</span></span></h4><div class="notion-text notion-block-21630f9b5b2280358e16dd3cbbdb5230">这个比较拗口，大致就是设备A是可以移动的设备，上面装了tailscale，平常在局域网外，通过某个Node访问内网。但是当设备A在物理上回到内网了，就会出现一个诡异的现象。</div><div class="notion-text notion-block-21630f9b5b2280e78ecafd0c8341c6c4">设备A可以访问内网所有设备，内网所有设备都无法访问设备A。</div><div class="notion-text notion-block-21630f9b5b228038b474cb601d3bdd9c">解决方案是添加高优先级的路由策略，只要设备分配的IP在指定网段内，那这个网段路由的优先级就要高于tailscale</div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[iptables + tproxy 实现透明代理]]></title>
            <link>https://xulog.com/article/16330f9b-5b22-801f-aae2-f4b73d2937df</link>
            <guid>https://xulog.com/article/16330f9b-5b22-801f-aae2-f4b73d2937df</guid>
            <pubDate>Fri, 25 Feb 2022 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-16330f9b5b22801faae2f4b73d2937df"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-text notion-block-16330f9b5b228088b371f1a851b8f520">先看一下iptables，<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://cos.test4x.com/uPic/20220224/Z2cGIt-nf-packet-flow.svg">正经图</a></div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-16330f9b5b2280019728ea9558a6f913"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column"><img src="https://cos.test4x.com/uPic/20220225/zBX5US-image-20220225000210969.png?spaceId=e185819e-76b9-458a-8b3b-3f602dc85a0e&amp;t=16330f9b-5b22-8001-9728-ea9558a6f913" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-16330f9b5b2280b8ab07f396055256fc">路由设置</div><h4 class="notion-h notion-h3 notion-h-indent-0 notion-block-16330f9b5b228006be75f4533b26d45b" data-id="16330f9b5b228006be75f4533b26d45b"><span><div id="16330f9b5b228006be75f4533b26d45b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#16330f9b5b228006be75f4533b26d45b" title="不同场景"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>不同场景</b></span></span></h4><h4 class="notion-h notion-h3 notion-h-indent-0 notion-block-16330f9b5b22806dae50d025c1a03b68" data-id="16330f9b5b22806dae50d025c1a03b68"><span><div id="16330f9b5b22806dae50d025c1a03b68" class="notion-header-anchor"></div><a class="notion-hash-link" href="#16330f9b5b22806dae50d025c1a03b68" title="内网机器访问国内服务"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>内网机器访问国内服务</b></span></span></h4><div class="notion-text notion-block-16330f9b5b22807dad12f60032e1f383">A的请求到达路由器的PREROUTING链，根据链上规则</div><div class="notion-text notion-block-16330f9b5b2280c19448dbe9dca36970">直接返回原来的PREROUTING连，走FORWARD以及后续的操作</div><h4 class="notion-h notion-h3 notion-h-indent-0 notion-block-16330f9b5b22800195f2c8065508f123" data-id="16330f9b5b22800195f2c8065508f123"><span><div id="16330f9b5b22800195f2c8065508f123" class="notion-header-anchor"></div><a class="notion-hash-link" href="#16330f9b5b22800195f2c8065508f123" title="内网机器访问国外服务"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>内网机器访问国外服务</b></span></span></h4><div class="notion-text notion-block-16330f9b5b2280f59d29c94611810443">A的请求到达路由器的PREROUTING链，根据链上规则</div><div class="notion-text notion-block-16330f9b5b2280e9b7a2e3dc609b72c4">给TCP请求加上mark，然后重定向到1081，根据前面的路由设置，会直接到本地回环，请求会到达Transparent Proxy</div><ol start="1" class="notion-list notion-list-numbered notion-block-16330f9b5b228077ad5efac6f7a11356" style="list-style-type:decimal"><li>判断需要走Proxy，那接下来的流程就是，包装原请求并发出，带上了0xff（即255）的mark</li><ol class="notion-list notion-list-numbered notion-block-16330f9b5b228077ad5efac6f7a11356" style="list-style-type:lower-alpha"><div class="notion-text notion-block-16330f9b5b2280f28b1fdd47fac41918">按照OUTPUT链上的规则</div><div class="notion-text notion-block-16330f9b5b22805c8836edacd9ed4526">直接返回OUTPUT链，走POSTROUTING链出去</div></ol></ol><ol start="2" class="notion-list notion-list-numbered notion-block-16330f9b5b22802da43bf6d25edb916f" style="list-style-type:decimal"><li>判断为直连，直接原封不动的请求真实服务器，也是带上0xff的mark，后面和情况1一样</li></ol><h4 class="notion-h notion-h3 notion-h-indent-0 notion-block-16330f9b5b22805ba119ce614ffea5c2" data-id="16330f9b5b22805ba119ce614ffea5c2"><span><div id="16330f9b5b22805ba119ce614ffea5c2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#16330f9b5b22805ba119ce614ffea5c2" title="路由器访问国内服务"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>路由器访问国内服务</b></span></span></h4><div class="notion-text notion-block-16330f9b5b2280d8b027ee3b21136cff">路由器的请求会从OUTPUT开始，会匹配上OUTPUT链上规则</div><div class="notion-text notion-block-16330f9b5b22807ebd34e152f737c184">直接返回OUTPUT链，走POSTROUTING链出去</div><h4 class="notion-h notion-h3 notion-h-indent-0 notion-block-16330f9b5b2280258a3ef96728935345" data-id="16330f9b5b2280258a3ef96728935345"><span><div id="16330f9b5b2280258a3ef96728935345" class="notion-header-anchor"></div><a class="notion-hash-link" href="#16330f9b5b2280258a3ef96728935345" title="路由器访问国外服务"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>路由器访问国外服务</b></span></span></h4><div class="notion-text notion-block-16330f9b5b228056b558e8cc226f0f22">路由器的请求会匹配上OUTPUT链上最后一条规则</div><div class="notion-text notion-block-16330f9b5b22808b9619d398873cbb37">给这个请求打上mark，然后打上mark的请求会重新走PREROUTING链，会匹配上如下规则</div><div class="notion-text notion-block-16330f9b5b2280f5b450df5307326304">也就是说，流量会绕一圈，重新进入Transparent Proxy</div><h4 class="notion-h notion-h3 notion-h-indent-0 notion-block-16330f9b5b22802ba132f5d9a9c99813" data-id="16330f9b5b22802ba132f5d9a9c99813"><span><div id="16330f9b5b22802ba132f5d9a9c99813" class="notion-header-anchor"></div><a class="notion-hash-link" href="#16330f9b5b22802ba132f5d9a9c99813" title="一个坑来了"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>一个坑来了</b></span></span></h4><div class="notion-text notion-block-16330f9b5b228088992efff261151f66">当通过tproxy进入Transparent Proxy的时候，这个包的的remoteAddr是请求发起方的地址（即路由器IP），localAddr则是真实需要到达的服务器地址（比如Google.com），响应该请求的时候，DST会变成请求发起方的地址（正是路由器的地址）</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-16330f9b5b2280688acff4da338f36c4"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column"><img src="https://cos.test4x.com/uPic/20220224/e5t0ls-image-20220224235031112.png?spaceId=e185819e-76b9-458a-8b3b-3f602dc85a0e&amp;t=16330f9b-5b22-8068-8acf-f4da338f36c4" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-16330f9b5b228058a1e7e9ff57ef4c59">如果我们不在OUTPUT对这个包做操作的话，这个包会再次被设置mark，都无法完成握手</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-16330f9b5b228063b211c9c5030042c0"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column"><img src="https://cos.test4x.com/uPic/20220224/dfZKk6-image-20220224235423320.png?spaceId=e185819e-76b9-458a-8b3b-3f602dc85a0e&amp;t=16330f9b-5b22-8063-b211-c9c5030042c0" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-16330f9b5b2280298ac3def9d95d7c90">最终成品：<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/XGFan/transparent-proxy">Github</a></div><div class="notion-blank notion-block-16730f9b5b2280ce85b7d9e935e96930"> </div><h4 class="notion-h notion-h3 notion-h-indent-0 notion-block-16730f9b5b2280dc8f60ff286b135acf" data-id="16730f9b5b2280dc8f60ff286b135acf"><span><div id="16730f9b5b2280dc8f60ff286b135acf" class="notion-header-anchor"></div><a class="notion-hash-link" href="#16730f9b5b2280dc8f60ff286b135acf" title="其他小插曲"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">其他小插曲</span></span></h4><div class="notion-text notion-block-16730f9b5b22809ebba3c538074a2e45">TProxy在代理UDP流量的时候，比如，代理从192.168.2.100:1234到8.8.8.8:53的流量，会在本地监听（bind）8.8.8.8:53的流量，正常情况下是不允许这样bind的，但是如果设置了<code class="notion-inline-code">syscall.IP_TRANSPARENT</code> 就能正常bind，但有个特例，如果本地已经有服务绑定了0.0.0.0:53的监听，那就会报错<code class="notion-inline-code">EADDRINUSE (address already in use)</code></div></main></div>]]></content:encoded>
        </item>
    </channel>
</rss>