<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tailscale &#8211; mylogs.cn</title>
	<atom:link href="https://mylogs.cn/tag/tailscale/feed/" rel="self" type="application/rss+xml" />
	<link>https://mylogs.cn</link>
	<description>发现、记录、分享</description>
	<lastBuildDate>Wed, 12 Aug 2026 15:31:36 +0000</lastBuildDate>
	<language>zh-Hans</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	
	<item>
		<title>Tailscale 半年排查，揪出潜伏 16 年的 SQLite 漏洞</title>
		<link>https://mylogs.cn/tailscale-sqlite-16-year-wal-bug/</link>
		
		<dc:creator><![CDATA[steve, zhang]]></dc:creator>
		<pubDate>Wed, 12 Aug 2026 15:31:22 +0000</pubDate>
				<category><![CDATA[科技]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[Tailscale]]></category>
		<category><![CDATA[WAL 预写日志]]></category>
		<category><![CDATA[嵌入式数据库]]></category>
		<category><![CDATA[数据库损坏]]></category>
		<category><![CDATA[漏洞修复]]></category>
		<category><![CDATA[竞态条件]]></category>
		<guid isPermaLink="false">https://mylogs.cn/tailscale-sqlite-16-year-wal-bug/</guid>

					<description><![CDATA[一家以网络工具著称的公司，花了半年时间追查自家生产环境里反复出现的数据库损坏，最终定位到一个潜伏了十六年的底层 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">一家以网络工具著称的公司，花了半年时间追查自家生产环境里反复出现的数据库损坏，最终定位到一个潜伏了十六年的底层漏洞。这个漏洞不在 Tailscale 自己的代码里，而在几乎所有人都信赖的嵌入式数据库 SQLite 之中。</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6a80cb6cdf856&quot;}" data-wp-interactive="core/image" data-wp-key="6a80cb6cdf856" class="wp-block-image size-large aligncenter wp-lightbox-container"><img fetchpriority="high" decoding="async" width="1200" height="630" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://mylogs.cn/wp-content/uploads/2026/08/991015ebe84b149917d7bc9c38d8568d_header.webp" alt="Tailscale 半年排查，揪出潜伏 16 年的 SQLite 漏洞" class="wp-image-4598" style="max-width:100%;height:auto;" srcset="https://mylogs.cn/wp-content/uploads/2026/08/991015ebe84b149917d7bc9c38d8568d_header.webp 1200w, https://mylogs.cn/wp-content/uploads/2026/08/991015ebe84b149917d7bc9c38d8568d_header-300x158.webp 300w, https://mylogs.cn/wp-content/uploads/2026/08/991015ebe84b149917d7bc9c38d8568d_header-1024x538.webp 1024w, https://mylogs.cn/wp-content/uploads/2026/08/991015ebe84b149917d7bc9c38d8568d_header-768x403.webp 768w" sizes="(max-width: 1200px) 100vw, 1200px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button><figcaption class="wp-element-caption">图片来源：Tailscale</figcaption></figure>





<h2 class="wp-block-heading">半年拉锯：控制平面的数据库为何频频损坏</h2>



<p class="wp-block-paragraph">Tailscale 的工程师团队在排查中发现，公司的控制平面（control plane）数据库会间歇性地出现损坏，进而导致服务不稳定。这段时间里，客户和员工都深受其扰，而问题却像捉迷藏一样时隐时现——曾有连续六周的「虚假平静」，让团队一度以为已经修好。</p>



<p class="wp-block-paragraph">真正的突破口，来自对 SQLite 预写日志（Write-Ahead Log，简称 WAL）机制的一次深入剖析。WAL 是现代 SQLite 在写入数据时采用的模式：新数据先追加到日志文件，再由「检查点」（checkpoint）操作把日志内容正式写回数据库主文件。Tailscale 团队发现，当一次写入事务与一次 WAL 重置（WAL-reset）发生在极短的时间窗口内重叠时，就会触发一个边界情况的竞态条件，进而让索引与数据不同步，最终造成数据库损坏。</p>



<h2 class="wp-block-heading">漏洞藏在 WAL 重置的瞬间</h2>



<p class="wp-block-paragraph">问题的精确触发条件相当苛刻：一个连接正在执行检查点操作，且这次检查点必须顺利完成；紧接着第二个检查点启动，而在它运行期间，另一个数据库连接提交了一笔事务，把 WAL 文件冲刷一遍并向文件开头写入了新内容。由于数据访问发生冲突，第二个检查点没有意识到 WAL 文件已被那笔事务冲刷过，于是在 WAL 索引头里写入了错误的字段值，误以为部分事务已经提交。后续再有事务提交时，WAL 文件里的页数超过了第一次检查点时的页数，等到第三次检查点发生时，第二步写入的那部分事务被整段跳过，永远没能进入数据库主文件，损坏就此产生。</p>



<p class="wp-block-paragraph">更令人意外的是，这个漏洞影响范围极广。它存在于自 SQLite 3.7.0（发布于 2010 年 7 月 21 日）起、直到 3.51.2 的所有版本。也就是说，十六年来几乎所有基于 WAL 模式的 SQLite 部署都携带这一隐患。修复先是在 3.51.3 版本（2025 年 3 月）中落地，部分较早版本也拿到了热修复补丁（3.44.6 与 3.50.7）。后续的 3.53.0 版本还新增了自动自愈的索引功能，从机制上防止过期表达式索引再次引发同类问题。</p>



<h2 class="wp-block-heading">Tailscale 为何偏偏踩中：偏离了「标准路径」</h2>



<p class="wp-block-paragraph">值得玩味的是，绝大多数开发者从未遇到这个问题。SQLite 拥有远超代码量的测试套件，被公认为软件可靠性的标杆。Tailscale 之所以中招，是因为他们以非标准的方式使用了这项「无聊的技术」：团队手动接管了检查点过程，并按照自己激进的节奏来运行，从而踏上了常规配置之外的小径。</p>



<p class="wp-block-paragraph">整个排查是一场跨职能的苦战，动用了数十人，包括 Tailscale 的工程与客服团队，以及 SQLite 的核心维护者。为了隔离这个竞态条件，Tailscale 还资助了一个开源的 SQLite VFS（虚拟文件系统）中间层工具，帮助在未来追踪类似问题。</p>



<h2 class="wp-block-heading">等了两个月，才等来那声「令人愉快的警报」</h2>



<p class="wp-block-paragraph">为了拿到生产环境确实发生该竞态的正面证据，Tailscale 在自家的 SQLite 驱动里打了补丁：当写入事务与 WAL 重置重叠时，记录一条警告。随后便是漫长的等待——两周、一月、两月。就在团队开始怀疑补丁是否失效、理论是否出错时，那条等待已久的警报终于触发，证明这个精确条件在真实生产环境中确实会出现。此后，系统又平稳运行了四个月，再无数据库事故。</p>



<h2 class="wp-block-heading">启示：成熟技术也怕「非常规用法」</h2>



<p class="wp-block-paragraph">这起事件给工程界提了个醒：运行成熟技术时，如果脱离常规配置、以非标准方式使用，风险会被悄然放大。常见的路径和标准配置经过了极其充分的测试，可靠性很高；而一旦为了性能或控制力手动接管底层机制，就必须为那些「几乎不可能发生」的边缘错误做好准备。对依赖 SQLite 存储关键数据的系统而言，定期执行完整性校验、保留可靠的备份与恢复流程，依旧是必要的兜底手段。</p>



<p class="has-small-font-size wp-block-paragraph">来源：Tailscale 工程博客《How we tracked down a 16-year-old SQLite bug》</p>

]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>旧手机别扔：用 Termux 把它变成家庭服务器</title>
		<link>https://mylogs.cn/old-phone-termux-home-server/</link>
					<comments>https://mylogs.cn/old-phone-termux-home-server/#respond</comments>
		
		<dc:creator><![CDATA[steve, zhang]]></dc:creator>
		<pubDate>Sun, 09 Aug 2026 07:24:43 +0000</pubDate>
				<category><![CDATA[科技]]></category>
		<category><![CDATA[chroot]]></category>
		<category><![CDATA[Tailscale]]></category>
		<category><![CDATA[Termux]]></category>
		<category><![CDATA[安卓]]></category>
		<category><![CDATA[家庭服务器]]></category>
		<category><![CDATA[旧手机]]></category>
		<category><![CDATA[自托管]]></category>
		<guid isPermaLink="false">https://mylogs.cn/old-phone-termux-home-server/</guid>

					<description><![CDATA[付着月费的小型云服务器，总让人觉得有点亏。一名开发者此前把个人服务跑在德国 Hetzner 的一台虚拟主机上， [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">付着月费的小型云服务器，总让人觉得有点亏。一名开发者此前把个人服务跑在德国 Hetzner 的一台虚拟主机上，里面装着几个 Web 应用、一个叫 Surf 的远程浏览器、反向代理 Caddy 等。问题出在 Surf 上：最便宜的共享机型还能应付日常，一旦 Chrome 真正开始干活就捉襟见肘，换带独享 CPU 的机型，月费又高得让一个私人浏览器显得不划算。</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6a80cb6ce0bb6&quot;}" data-wp-interactive="core/image" data-wp-key="6a80cb6ce0bb6" class="wp-block-image size-large aligncenter wp-lightbox-container"><img decoding="async" width="1200" height="970" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://mylogs.cn/wp-content/uploads/2026/08/f1d9fe002f85_header.webp" alt="旧手机别扔：用 Termux 把它变成家庭服务器" class="wp-image-4170" style="max-width:100%;height:auto;" srcset="https://mylogs.cn/wp-content/uploads/2026/08/f1d9fe002f85_header.webp 1200w, https://mylogs.cn/wp-content/uploads/2026/08/f1d9fe002f85_header-300x243.webp 300w, https://mylogs.cn/wp-content/uploads/2026/08/f1d9fe002f85_header-1024x828.webp 1024w, https://mylogs.cn/wp-content/uploads/2026/08/f1d9fe002f85_header-768x621.webp 768w" sizes="(max-width: 1200px) 100vw, 1200px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button><figcaption class="wp-element-caption">图片来源：seg6.space</figcaption></figure>





<p class="wp-block-paragraph">买新机器也划不来。内存价格高得离谱，组装一台内存宽裕的小主机时机糟糕。就在他翻看二手迷你主机时，想起了那台吃灰的 CMF Phone 1：八颗 ARM 核、8GB 内存、128GB 闪存、Wi-Fi 6、5G 调制解调器，还自带电池。硬件明显被闲置，而且钱早就付过了。</p>



<p class="wp-block-paragraph">这台手机如今跑着 Surf 及其托管的 Chrome 实例、个人记账工具、屏幕共享服务，外加几个小应用。它们能扛住重启、从 Git 部署，手机在不同网络间移动时依旧可达——也就是说，它真正替代了那台虚拟主机。</p>



<h2 class="wp-block-heading">第一次走弯路：想刷掉安卓</h2>



<p class="wp-block-paragraph">最直接的思路是刷入常规 Linux 发行版。CMF Phone 1 确实有 postmarketOS 设备移植，能启动，设备页上够多的绿勾让人冲动。这位开发者成了那个冲动的人。</p>



<p class="wp-block-paragraph">他没太在意那些标红的「已损坏」项：Wi-Fi、蓝牙、硬件加速，以及让这部手机胜任小服务器的几乎一切。结果只看到 postmarketOS 的开机画面和一块黑屏——既不是服务器，也不是手机了。</p>



<p class="wp-block-paragraph">把原厂 Nothing OS 刷回来又成了另一桩苦差：刷机工具依赖 Windows，他得先在 QEMU 里装 Windows，和 USB 透传、联发科驱动搏斗，看工具卡死，最后挪到真机才恢复出厂镜像。中间一度软砖，只有黑屏，他真以为把一台好端端的设备变成了砖头。</p>



<p class="wp-block-paragraph">手机救回来了，教训也清楚：安卓已经为这块硬件写好了能用的驱动，Wi-Fi、电源管理、电池、GPU、调制解调器，连同所有古怪的厂商细节都正常工作。为了一个更常规的用户态而全盘抛弃，是笔亏本买卖。</p>



<h2 class="wp-block-heading">Termux 才是主机</h2>



<p class="wp-block-paragraph">第二次尝试保留原厂安卓，把 Termux 当作宿主环境。它提供了 OpenSSH、runit、Caddy、Cloudflared、包管理，以及足够像样的 Unix 工具；Termux:Boot 在重启后拉起监控进程与 SSH；Tailscale 给手机一个稳定的私网地址，于是从 tailnet 里的任意机器只要敲一句 <code>ssh cmf</code> 就能连上。</p>



<p class="wp-block-paragraph">Termux 不是虚拟机，它的进程仍跑在安卓的 Linux 内核上，只是它那套基于 Bionic 的用户态和标准 Debian 差别足够大，现成的 Linux 应用镜像没法直接丢进去。这个分裂反而有用：Termux 当小巧的宿主控制面，每个应用自带它期望的 Linux 文件系统。</p>



<p class="wp-block-paragraph">实际服务由 runit 监管。安卓的省电机制对一台假装服务器的设备极不友好，于是他用 Ansible 给安卓施加一套主机配置：常驻唤醒锁、关闭浅层与深层待机、把 Termux 与 Tailscale 移出后台限制、阻止 Wi-Fi 挂起，并把 Tailscale 设为常驻 VPN。</p>



<p class="wp-block-paragraph">恢复链路比任何单项设置都重要：</p>



<pre class="wp-block-code"><code>Android 启动
→ Tailscale 常驻 VPN
→ Termux:Boot
→ runit
→ 常驻服务
→ 本地与公网健康检查</code></pre>



<h2 class="wp-block-heading">从 PRoot 到真正的 chroot</h2>



<p class="wp-block-paragraph">他的应用大多以 Linux ARM64 的 OCI 镜像分发，proot-distro 能在 Debian 下轻松跑起来而不改动应用本身。PRoot 在用户态拦截文件系统和进程操作，让普通 Termux 进程以为自己身处 Debian 根文件系统里。它不是容器边界，仍与安卓共享内核、网络命名空间和 Termux 的用户身份，但作为兼容层极其好用——既不需要 root，也不需要特殊内核。</p>



<p class="wp-block-paragraph">普通 Web 服务起初这么跑毫无问题。例外是 Surf 这种对延迟敏感的浏览器负载：启动进程、加载库、读取浏览器配置、搬运截屏数据，全都要穿过 PRoot 的用户态翻译层。CPU 明明有富余，Chrome 却够不着。于是他把手机 root 了——不是为了替换安卓，而是为了把同一个 Debian 文件系统正确挂载，用真正的 <code>chroot</code> 进去。runit 依旧掌管生命周期，应用数据仍留在 Termux 存储里；负载只是改用原生系统调用而非 PRoot 抵达安卓内核。提升幅度相当明显。</p>



<p class="wp-block-paragraph">等这条路走稳，把剩下几个小服务也迁了过去。他的工作站把每个 ARM64 镜像解析到精确的摘要，导出文件系统，Ansible 在手机上校验并安装；一个小的 root 辅助程序建立私有挂载命名空间、以 chroot 进入、降权并启动原镜像的入口。手机上既不需要 Docker，也不需要编译器。这些仍是兼容环境而非安全边界，私有挂载命名空间主要让挂载与清理可预期。</p>



<h2 class="wp-block-heading">整机变成可复现的状态</h2>



<p class="wp-block-paragraph">到这一步手机什么都能跑，但他不想养一只靠一周后就会忘的命令行历史拼出来的宠物服务器。他把整个宿主搬进 Ansible 管理的状态：版本、服务定义、路由、电源设置、密钥、健康检查，全在同一个私有仓库里。</p>



<pre class="wp-block-code"><code>发布版 / OCI 镜像
→ 在 Git 中固定摘要（digest）
→ 通过 SSH 执行 Ansible
→ 手机上写入带版本号的目录
→ 原子 current 软链接
→ runit 服务
→ 本地与公网健康检查</code></pre>



<p class="wp-block-paragraph">发布版按摘要固定，装进带版本号的目录，背后是一个原子的 <code>current</code> 软链接；校验和或健康检查不通过就停下部署，回滚只需改回固定版本再应用一遍。应用数据独立于发布版存放。密钥不落在手机上，Ansible Vault 的密文放在基础设施仓库，部署时只把每个服务所需的运行时值渲染进 Termux 的私有存储。</p>



<h2 class="wp-block-heading">让手机从家用宽带接进流量</h2>



<p class="wp-block-paragraph">下一个要处理的是入口。家用宽带没有虚拟主机那样的静态地址，他也不想通过路由器把 SSH 或随机端口暴露出去，同时仍希望手机拔掉电源、带到别处、连上网络，服务器还在。</p>



<p class="wp-block-paragraph">HTTP 应用走 Cloudflare Tunnel。cloudflared 从手机发起一条出站连接，Cloudflare 把每个主机名经这条隧道送来，Caddy 再路由到对应的本地回环服务：</p>



<pre class="wp-block-code"><code>互联网
→ Cloudflare Tunnel
→ 127.0.0.1 上的 Caddy
→ 127.0.0.1 上的应用</code></pre>



<p class="wp-block-paragraph">这些服务没有任何入站路由器规则。cloudflared 只需要一条出站连接，所以手机换到别的网络，隧道会自动重连，主机名也跟着走。Tailscale 在管理面上做同样的事。</p>



<p class="wp-block-paragraph">Surf 远程浏览器的后端对延迟敏感、自己终结 TLS，而连它的旧 iPad 锁定了服务器身份，普通 Cloudflare Tunnel 在 Cloudflare 一侧终结 TLS 正好踩中它不想要的。解法是把整条 Surf TLS 流裹进一个普通的 WebSocket 里：Cloudflare 转发的是 WebSocket，真正的 Surf 连接仍在其中端到端加密，代价只是多一两个网络来回（iPad 初次测试约 60 毫秒），却能在一条只需出站连接的隧道里跑通。</p>



<h2 class="wp-block-heading">到底跑了什么</h2>



<p class="wp-block-paragraph">这台机器分两层。安卓与 Termux 掌管硬件、网络、入口与监管；Linux 常驻环境拿到自己期望的文件系统，其余时间不挡宿主的路。</p>



<ul class="wp-block-list"><li>安卓 / Termux 宿主：负责硬件、网络、入口、监管，组件含 runit、Tailscale、Caddy、Cloudflared、DDNS、运维仪表盘</li><li>root 后的 Linux 常驻环境：负责应用兼容与负载，运行 Surf 与 Chrome、记账工具、屏幕共享等</li></ul>



<p class="wp-block-paragraph">最吃力的负载是 Surf，它把现代 Chromium 带到老款 iPhone 和 iPad 上。手机在 Debian 运行时里跑桌面版 Chrome（较新的 arm64 版本）和 Surf 后端，iPad mini 收下 H.264 视频与音频，回传触摸、键盘、标签页和导航指令。另一个常驻项是个人记账工具，记录周期性收支、一次性交易、月度支出上限并逐日推算余额，它的 SQLite 数据库有自动化的离机备份和验证过的恢复流程。最新添的可观测性服务收集八核 CPU、内存、电池、温度与可达性，在 <code>https://dash.cmf</code> 提供一个只能局域网或 tailnet 内访问的界面。</p>



<h2 class="wp-block-heading">你该照做吗</h2>



<p class="wp-block-paragraph">如果你手边正有一台还算现代、可 root 的 ARM64 手机在吃灰，这事远没有听起来那么荒唐。你得到安静的硬件、低功耗、闪存、Wi-Fi、一块用于救急的内置屏幕，以及一块行为像微型不间断电源的电池。原厂安卓已经支持这块硬件，而 Termux 加一个 root 后的 chroot，足够跑起多得惊人的常规 Linux 软件。</p>



<p class="wp-block-paragraph">他不会把无可替代的数据放上去而不做自动化离机备份，也不会把 chroot 当成敌意负载的隔离边界。root 扩大了信任边界，安卓仍是个不寻常的服务器宿主，软件渲染的桌面版 Chrome 也打不过带 GPU 的专用工作站。但对手头那几个私人服务，尤其是当替代方案是无限期为一台要么慢、要么贵得离谱的虚拟主机付费时，它是个真正有用的选项，而不只是一个噱头。</p>



<p class="has-small-font-size wp-block-paragraph">来源：Hacker News / seg6.space</p>

]]></content:encoded>
					
					<wfw:commentRss>https://mylogs.cn/old-phone-termux-home-server/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>家庭服务器别再端口转发，改用 mesh VPN 更稳</title>
		<link>https://mylogs.cn/home-server-mesh-vpn-tailscale/</link>
					<comments>https://mylogs.cn/home-server-mesh-vpn-tailscale/#respond</comments>
		
		<dc:creator><![CDATA[steve, zhang]]></dc:creator>
		<pubDate>Sat, 08 Aug 2026 14:42:53 +0000</pubDate>
				<category><![CDATA[科技]]></category>
		<category><![CDATA[mesh VPN]]></category>
		<category><![CDATA[Tailscale]]></category>
		<category><![CDATA[内网穿透]]></category>
		<category><![CDATA[家庭服务器]]></category>
		<category><![CDATA[端口转发]]></category>
		<category><![CDATA[网络安全]]></category>
		<category><![CDATA[自托管]]></category>
		<guid isPermaLink="false">https://mylogs.cn/home-server-mesh-vpn-tailscale/</guid>

					<description><![CDATA[家里跑着 NAS、Home Assistant 或者 Jellyfin，想在外面也能访问，最省事的办法就是端口 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">家里跑着 NAS、Home Assistant 或者 Jellyfin，想在外面也能访问，最省事的办法就是端口转发。但科技媒体 How-To Geek 于 2026 年 8 月 8 日刊文提醒：这条“最省事”的路，恰恰是把服务器敞开给整个互联网的入口。</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6a80cb6ce1ac6&quot;}" data-wp-interactive="core/image" data-wp-key="6a80cb6ce1ac6" class="wp-block-image size-large aligncenter wp-lightbox-container"><img decoding="async" width="1200" height="675" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://mylogs.cn/wp-content/uploads/2026/08/b51b333c8f05f403b206c4604222ac13_header.webp" alt="家庭服务器别再端口转发，改用 mesh VPN 更稳" class="wp-image-4122" style="max-width:100%;height:auto;" srcset="https://mylogs.cn/wp-content/uploads/2026/08/b51b333c8f05f403b206c4604222ac13_header.webp 1200w, https://mylogs.cn/wp-content/uploads/2026/08/b51b333c8f05f403b206c4604222ac13_header-300x169.webp 300w, https://mylogs.cn/wp-content/uploads/2026/08/b51b333c8f05f403b206c4604222ac13_header-1024x576.webp 1024w, https://mylogs.cn/wp-content/uploads/2026/08/b51b333c8f05f403b206c4604222ac13_header-768x432.webp 768w" sizes="(max-width: 1200px) 100vw, 1200px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button><figcaption class="wp-element-caption">图片来源：How-To Geek</figcaption></figure>





<p class="wp-block-paragraph">端口转发的逻辑很简单：在路由器上把某个外部端口指向服务器的内网地址，外面的人连你的公网 IP 加这个端口，请求就直达内部服务。问题也正出在这里——路由器分不清来的是你、你的朋友、自动扫描器，还是正寻找破绽的攻击者，它一律放行。于是挡住攻击的重担全压在应用本身身上，一个弱密码就可能让大门洞开。换用冷门外部端口能挡掉一部分明显的扫描，但全网的扫描器会自动探测海量地址和端口，一旦被盯上，就会反复回来。</p>



<p class="wp-block-paragraph">更稳妥的做法是用网状 VPN（mesh VPN）。以 Tailscale 为例，它在服务器和你批准的手机、笔记本之间建立一条私有网络（tailnet），两端直连、端到端加密，全程不需要端口转发，也不用自己搭传统 VPN 服务器。装上之后，Tailscale 会给服务器分配一个稳定的私有地址，配合 MagicDNS 还能用一个好记的设备名访问，比如在浏览器里输 homeserver:8096 就能打开 Jellyfin。同类工具还有 ZeroTier、NetBird，以及普通的 WireGuard。</p>



<p class="wp-block-paragraph">迁移时有个关键顺序：先装好 Tailscale 并用手机流量（而非家里 Wi-Fi）确认能连上服务器，再回头登录路由器删掉端口转发规则，连同 UPnP 自动生成的规则一起清掉；最后两头各测一遍——走 Tailscale 地址应当照常可用，走公网 IP 加旧端口则应连不通。</p>



<p class="wp-block-paragraph">Tailscale 挡住了外网，但不代表对内网设备可以完全信任。文章建议用访问控制限定哪些用户、哪些设备能碰服务器，并且只给它们真正需要的服务：手机也许只需要 Jellyfin，不需要 SSH，也不该打开管理后台。子网路由（subnet routing）尤其要小心，把整张局域网都暴露给 Tailscale，会重新造出当初想逃离的那种“扁平、过度信任”的网络。至于网站、游戏服这类本就该公开的服务，作为例外保留在外网即可。</p>



<p class="has-small-font-size wp-block-paragraph">来源：How-To Geek</p>

]]></content:encoded>
					
					<wfw:commentRss>https://mylogs.cn/home-server-mesh-vpn-tailscale/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
