<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Tailscale on NOSAE</title>
    <link>https://nosae.top/tags/tailscale/</link>
    <description>Recent content in Tailscale on NOSAE</description>
    <image>
      <title>NOSAE</title>
      <url>https://nosae.top/images/papermod-cover.png</url>
      <link>https://nosae.top/images/papermod-cover.png</link>
    </image>
    <generator>Hugo -- 0.147.2</generator>
    <language>zh</language>
    <copyright>NOSAE</copyright>
    <lastBuildDate>Sun, 19 Apr 2026 17:45:08 +0800</lastBuildDate>
    <atom:link href="https://nosae.top/tags/tailscale/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>NAT穿透工作原理</title>
      <link>https://nosae.top/posts/nat%E7%A9%BF%E9%80%8F%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86/</link>
      <pubDate>Sun, 19 Apr 2026 17:45:08 +0800</pubDate>
      <guid>https://nosae.top/posts/nat%E7%A9%BF%E9%80%8F%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86/</guid>
      <description>&lt;h2 id=&#34;前言&#34;&gt;前言&lt;/h2&gt;
&lt;p&gt;我们在 &lt;a href=&#34;https://nosae.top/posts/tailescale%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Tailscale 工作原理&lt;/a&gt; 中涵盖了很多内容。但是，我们只是略微提及了如何绕过 NAT（网络地址转换器），而且无论设备之间有什么障碍，我们都假设他们能直连。下面我们就来详细讨论下。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://cdn.jsdelivr.net/gh/NOS-AE/assets@main/img/50eafc1638d93b9637dcee0d55967a8fa09e05c7-1700x800.png&#34; data-fancybox=&#34;gallery&#34; data-caption=&#34;NAT traversal with laptops diagram.&#34;&gt;
  &lt;img alt=&#34;NAT traversal with laptops diagram.&#34; loading=&#34;lazy&#34; src=&#34;https://cdn.jsdelivr.net/gh/NOS-AE/assets@main/img/50eafc1638d93b9637dcee0d55967a8fa09e05c7-1700x800.png&#34;&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;我们先从一个简单的问题入手：在两台机器之间建立点对点连接。在 Tailscale 的案例中，我们希望建立一个 WireGuard® 隧道，但这其实并不重要。我们使用的技术应用广泛，是许多人几十年来研究的成果。例如， &lt;a href=&#34;https://webrtc.org/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;WebRTC&lt;/a&gt; 就利用这套技术在 Web 浏览器之间传输点对点音频、视频和数据。VoIP 电话和一些视频游戏也使用了类似的技术，尽管并非总是成功。&lt;/p&gt;
&lt;p&gt;我们将对这些技术进行一般性讨论，并在适当情况下以 Tailscale 等为例进行说明。假设您正在创建自己的协议，并且需要实现 NAT 穿透。您需要两样东西：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;首先，协议应该基于 UDP&lt;/strong&gt;。虽然也可以使用 TCP 进行 NAT 穿透，但这会使原本就相当复杂的问题更加复杂，甚至可能需要对内核进行定制，具体取决于你想要实现的深度。所以下面我们重点讨论下 UDP。如果你因为希望在 NAT 穿透完成后建立面向流的连接而选择 TCP，不妨考虑改用 QUIC。QUIC 基于 UDP 构建，因此我们可以专注于使用 UDP 进行 NAT 穿透，最终仍然能够获得良好的流传输协议。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;其次，你需要直接控制发送和接收网络数据包的网络套接字&lt;/strong&gt;。通常情况下，你不能直接使用现有的网络库来穿透 NAT，因为你需要发送和接收一些额外的、不属于你正在使用的“主”协议的数据包。有些协议将 NAT 穿透与其他功能紧密集成在一起（例如 WebRTC）。但如果你要自己构建 NAT 穿透机制，最好将 NAT 穿透视为一个独立的实体，它与你的主协议共享一个套接字。两者并行运行，互相支持。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;简单来说，标准的网络库只负责传输协议数据（如 TLS 握手、HTTP 请求）。但基于 NAT 穿透的连接需要你在同一个端口上，既发送业务数据，又发送用于维持连接、探测路径的“额外数据包”。如果你无法直接控制 socket，你就没法塞进这些“私货”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://cdn.jsdelivr.net/gh/NOS-AE/assets@main/img/5bef4a143b33f1a5b2ce49e919dccb4e59b7569a-1600x760.png&#34; data-fancybox=&#34;gallery&#34; data-caption=&#34;NAT traversal with app diagram.&#34;&gt;
  &lt;img alt=&#34;NAT traversal with app diagram.&#34; loading=&#34;lazy&#34; src=&#34;https://cdn.jsdelivr.net/gh/NOS-AE/assets@main/img/5bef4a143b33f1a5b2ce49e919dccb4e59b7569a-1600x760.png&#34;&gt;
&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Tailescale工作原理</title>
      <link>https://nosae.top/posts/tailescale%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86/</link>
      <pubDate>Wed, 15 Apr 2026 23:59:18 +0800</pubDate>
      <guid>https://nosae.top/posts/tailescale%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86/</guid>
      <description>&lt;h2 id=&#34;译者序&#34;&gt;译者序&lt;/h2&gt;
&lt;p&gt;有的地方按个人理解，将一些带有外国腔的句子，翻译成了更适合中国人阅读的形式。&lt;/p&gt;
&lt;h2 id=&#34;正文&#34;&gt;正文&lt;/h2&gt;
&lt;p&gt;人们经常问我们 Tailscale 的工作原理是什么。我们一直没回答这个问题，因为我们一直在改动它！但现在情况已经稳定下来了。&lt;/p&gt;
&lt;p&gt;让我们从下到上逐一了解整个 Tailscale 系统，就像我们当初构建它时一样（但会略过一些过程中遇到的曲折）。有了这些信息，你应该能够构建自己的 Tailscale 替代方案……不过你其实不必这么做，因为我们的 &lt;a href=&#34;https://github.com/tailscale/tailscale&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;节点软件是开源的 &lt;/a&gt;，而且我们还提供 &lt;a href=&#34;https://tailscale.com/pricing&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;灵活的免费方案 &lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&#34;数据平面wireguard&#34;&gt;数据平面：WireGuard&lt;/h2&gt;
&lt;p&gt;我们的基础层是日益流行且优秀的开源 &lt;a href=&#34;https://www.wireguard.com/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;WireGuard&lt;/a&gt; 软件包（具体来说是用户空间 Go 版本 &lt;a href=&#34;https://git.zx2c4.com/wireguard-go/about/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;wireguard-go&lt;/a&gt; ）。WireGuard 会在您的计算机、虚拟机或容器（WireGuard 称之为“端点”，我们称之为“节点”）与网络中的任何其他节点之间创建一组极其轻量级的加密隧道。&lt;/p&gt;
&lt;p&gt;让我们理一下：大多数情况下，VPN 用户（包括 WireGuard 用户）会构建“星型”架构，其中每个客户端设备（例如您的笔记本电脑）都连接到中央“集中器”或 VPN 网关。&lt;/p&gt;
&lt;h3 id=&#34;星型网络--中心辐射网络hub-and-spoke-networks&#34;&gt;星型网络 / 中心辐射网络（hub-and-spoke networks）&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://cdn.jsdelivr.net/gh/NOS-AE/assets@main/img/3cbc3fa27f0b798d3a0bc98f57829a9083dad769-1400x1080.svg&#34; data-fancybox=&#34;gallery&#34; data-caption=&#34;传统的中心辐射型 VPN&#34;&gt;
  &lt;img alt=&#34;传统的中心辐射型 VPN&#34; loading=&#34;lazy&#34; src=&#34;https://cdn.jsdelivr.net/gh/NOS-AE/assets@main/img/3cbc3fa27f0b798d3a0bc98f57829a9083dad769-1400x1080.svg&#34;&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这是配置 WireGuard 最简单的方法，因为网络中的每个节点都需要知道它想要直接连接的其他节点的公钥、公网 IP 地址和端口号。如果要完全连接 10 个节点，那么每个节点都需要知道 9 个对等节点，或者说 90 个独立的隧道端点。在星型网络中，你只需要一个中心枢纽节点（hub）和 9 个外围节点（通过“辐条”（spoke）连接它们），这要简单得多。枢纽节点通常具有静态 IP 地址，并在其防火墙上打开一个端口，以便所有人都能轻松找到它。然后，它可以接受来自其他 IP 地址节点的传入连接，即使这些节点本身位于防火墙之后，就像客户端-服务器互联网协议通常做的那样。&lt;/p&gt;
&lt;p&gt;星型网络架构虽然效果不错，但也存在一些缺点。首先，大多数现代企业并没有一个固定的中心节点。它们通常拥有多个办公室、多个云数据中心、区域或虚拟专用网络 (VPC) 等等。在传统的 VPN 设置中，企业配置一个 VPN 集中器，然后在不同位置之间建立二级隧道（通常使用 IPsec）。因此，远程用户首先会到达 VPN 集中器，然后他们的流量会被转发到位于另一个位置的最终目的地。&lt;/p&gt;
&lt;p&gt;这种传统方案难以扩展。首先，远程用户可能离 VPN 集中器很远，也可能很远；如果距离较远，连接延迟就会很高。其次，他们想要访问的数据中心可能也离 VPN 集中器很远；如果距离较远，同样会面临高延迟。想象一下这种情况：一位纽约的员工试图通过公司位于旧金山总部的 VPN hub 或 BeyondCorp 代理（Google 的零信任网络）连接到位于纽约的服务器。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
