<?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>Str.</title>
        <link>https://blog.borry.org/</link>
        <description>Nothing.</description>
        <lastBuildDate>Sun, 10 May 2026 02:36:46 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>zh-CN</language>
        <copyright>All rights reserved 2026, Borui</copyright>
        <item>
            <title><![CDATA[Nginx配置反向代理]]></title>
            <link>https://blog.borry.org/article/nginx-reverse-proxy</link>
            <guid>https://blog.borry.org/article/nginx-reverse-proxy</guid>
            <pubDate>Tue, 12 Sep 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[反向代理和正向代理，如何复用端口等]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-387baa7990174d999c9f5db6c2be9913"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-26cb4551008d4f679d51b639a766b1c1" data-id="26cb4551008d4f679d51b639a766b1c1"><span><div id="26cb4551008d4f679d51b639a766b1c1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#26cb4551008d4f679d51b639a766b1c1" 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-6878bfe48fa24ee68c274e6c029a45c8">Nginx和Apache一样是一款轻量级的web服务器，反向代理服务器。Web服务器我们都知道能够用来托管一个Web服务。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-a587cf96e0914298bea20b854d3cbc90" data-id="a587cf96e0914298bea20b854d3cbc90"><span><div id="a587cf96e0914298bea20b854d3cbc90" class="notion-header-anchor"></div><a class="notion-hash-link" href="#a587cf96e0914298bea20b854d3cbc90" 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-5e3418ebca4946e79e671390f1ed0e5e">很多人可能听说过，或者正在使用代理服务，我们平常所说的代理对于用户来说都是“正向代理”。</div><div class="notion-text notion-block-ee91e00201784923a16cd90dfacd5506">正向代理能够向被访问的服务器隐藏访问者的信息，因此也能够通过代理服务器绕过防火墙，访问由于政策原因被限制的网站。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-23deb69f3dfe41a4ba7478928ff6a0c4"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:332.9921875px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Fa5a46c38-63f0-4f6a-ab7a-2cd059e716c8%2F716055cf-dbf7-4916-92dc-2ca58ef2f9db%2FUntitled.png?table=block&amp;id=23deb69f-3dfe-41a4-ba74-78928ff6a0c4&amp;t=23deb69f-3dfe-41a4-ba74-78928ff6a0c4&amp;width=332.9921875&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-94bd77cf4bf1463f998c1040ecdd173b" data-id="94bd77cf4bf1463f998c1040ecdd173b"><span><div id="94bd77cf4bf1463f998c1040ecdd173b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#94bd77cf4bf1463f998c1040ecdd173b" 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-f8dd571db0e54ccaa9706c805bc1c630">而反向代理，则和正向代理恰恰相反，正向代理代理的是“客户端”，使用代理服务器代理客户端来访问服务器，而反向代理，则是代理的“服务端”，客户端访问服务端访问到的先是代理服务器，通过代理服务器才能够真正连接到目标服务器。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-d4d66c4cd982497d8e5c449563e3e9ad"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:337.9921875px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Fa5a46c38-63f0-4f6a-ab7a-2cd059e716c8%2Fe97316a8-31fc-47e2-bc94-41b1dd3cc748%2FUntitled.png?table=block&amp;id=d4d66c4c-d982-497d-8e5c-449563e3e9ad&amp;t=d4d66c4c-d982-497d-8e5c-449563e3e9ad&amp;width=337.9921875&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-63e117cf40bc48a0b94d1759edcda066">如上图所示，我们使用反向代理的时候，客户端访问baidu.com，实际上访问到了百度的反向代理服务器，反向代理服务器再根据各个服务器的负载，响应速度来进行分发。这样不仅使得服务端的资源得到了最大的利用，同时还使得位于反代服务器后的业务服务器得到了保护。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-dafe0d386e2f48f5bc684c8d126e0c2c" data-id="dafe0d386e2f48f5bc684c8d126e0c2c"><span><div id="dafe0d386e2f48f5bc684c8d126e0c2c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#dafe0d386e2f48f5bc684c8d126e0c2c" 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-2c5d059c5023416a8a9d6c1243db8b19">安装完成后访问服务器ip，应该会看到nginx的默认欢迎页。</div><div class="notion-text notion-block-24459d8c5bb141ca9bacc88ed9fde3f8">nginx的默认配置文件一般在/etc/nginx/目录下，目录下sites-enabled中的default为nginx的默认欢迎页的配置文件。而nginx的主配置文件为nginx.conf，其中通过include来引用了位于其他目录下的各部分nginx配置文件。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-f680a046733f4d87a7547570ee9e8a77" data-id="f680a046733f4d87a7547570ee9e8a77"><span><div id="f680a046733f4d87a7547570ee9e8a77" class="notion-header-anchor"></div><a class="notion-hash-link" href="#f680a046733f4d87a7547570ee9e8a77" 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-682d74589791424790a92fb5b9a569c1">我们最常用的部分是配置文件中的http块，http块其中又嵌套了server块，每个server块都是一个虚拟主机，Server块中还包含了location块，location块则指定了被访问资源的虚拟位置。</div><div class="notion-blank notion-block-b51bb253eaa84135beda27b4f0b64539"> </div><div class="notion-text notion-block-a89d14a1aad94b37814bfc9babe3b6a7">以上是一个示例http块，其中包含了一个具有两个location的虚拟主机，如果我们要托管一个静态页面，则可以在location中指定root为静态文件的目录，而如果我们要进行反向代理，则可以使用proxy_pass将指定的url转发到监听的端口上。</div><table class="notion-simple-table notion-block-b2a06ab523924b6fa00ce9b8b9d0ae42"><tbody><tr class="notion-simple-table-row notion-block-6a1e36dc50aa402589867ab55dc3f79f"><td class="" style="width:120px"><div class="notion-simple-table-cell">listen</div></td><td class="" style="width:586px"><div class="notion-simple-table-cell">监听端口号</div></td></tr><tr class="notion-simple-table-row notion-block-8ec5b72450cc49d48934c02f51f0bab6"><td class="" style="width:120px"><div class="notion-simple-table-cell">server_name</div></td><td class="" style="width:586px"><div class="notion-simple-table-cell">匹配请求中的Host字段，满足端口号和Host字段才会被该虚拟主机捕获</div></td></tr><tr class="notion-simple-table-row notion-block-dbc83b86648642d8a978306503c1fec8"><td class="" style="width:120px"><div class="notion-simple-table-cell">location</div></td><td class="" style="width:586px"><div class="notion-simple-table-cell">location为相对路径，也可使用正则表达式进行匹配</div></td></tr><tr class="notion-simple-table-row notion-block-b0fa800c65b941859a77c888d164ffa8"><td class="" style="width:120px"><div class="notion-simple-table-cell">root</div></td><td class="" style="width:586px"><div class="notion-simple-table-cell">静态页面的目录</div></td></tr><tr class="notion-simple-table-row notion-block-53eaad980c1443a59a29210314f06bd2"><td class="" style="width:120px"><div class="notion-simple-table-cell">index</div></td><td class="" style="width:586px"><div class="notion-simple-table-cell">静态页面的主页文件</div></td></tr><tr class="notion-simple-table-row notion-block-71035cb73bed4e21838c4b61c3f7dffd"><td class="" style="width:120px"><div class="notion-simple-table-cell">proxy_pass</div></td><td class="" style="width:586px"><div class="notion-simple-table-cell">要进行反向代理的端口、地址</div></td></tr></tbody></table><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-287ae56454a944f8bad3ac873fac0f6f" data-id="287ae56454a944f8bad3ac873fac0f6f"><span><div id="287ae56454a944f8bad3ac873fac0f6f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#287ae56454a944f8bad3ac873fac0f6f" 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-3852cb4b08e54806aaebedea98a72d0b">       在我最开始接触到linux服务器的时候，常常会有多个服务部署在一台服务器上，但由于只有80和443端口可以不带端口号访问，为了访问对应的服务的时候能更优雅，于是才了解到nginx的反向代理，反向代理在我目前使用最多的场景就是在单服务器上的多个服务，通过映射多个域名到服务器，然后nginx通过server_name来分辨目标服务并进行转发。</div><div class="notion-text notion-block-1f2d9758bf424e1e8dea06e77cc565f4">像这样就可以实现，输入domain1.borry.org访问位于8080端口的服务，输入domain2.borry.org访问位于6789端口的服务，实现了端口的复用。</div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[使用Github Action来进行CI/CD]]></title>
            <link>https://blog.borry.org/article/github-action-ci</link>
            <guid>https://blog.borry.org/article/github-action-ci</guid>
            <pubDate>Tue, 12 Mar 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[使用Github Action来进行自动部署到服务器]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-cd4417c2060c40828f27a6d6ea10ca3b"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-text notion-block-68b28f7aa95f4c45816fc332a5f9dfcc">使用 Github Action来自动化构建Dockerfile，并且将Images推送到Docker Hub。</div><div class="notion-text notion-block-3afdbcda59174d158fc49c86a1566089">最后使用SSH连接服务器进行自动部署</div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[HTTP分块编码传输]]></title>
            <link>https://blog.borry.org/article/http-chunked</link>
            <guid>https://blog.borry.org/article/http-chunked</guid>
            <pubDate>Thu, 14 Sep 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[关于HTTP的长连接、短连接和如何使用fiber来实现chunked分块编码传输]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-4bfed4c2c7b04a0ba75569b1273bdf3c"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-b16c10f137b64b0fb23b06a9bebade78" data-id="b16c10f137b64b0fb23b06a9bebade78"><span><div id="b16c10f137b64b0fb23b06a9bebade78" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b16c10f137b64b0fb23b06a9bebade78" title="HTTP的长连接和短连接"><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">HTTP的长连接和短连接</span></span></h3><div class="notion-text notion-block-31cd12e12be34e60a24e254cd798a51f">HTTP协议是应用层协议，它是建立在TCP协议之上的。而TCP协议在传输数据之前，需要先通过三次握手来建立连接，并且由于TCP的慢启动的特性，使得一开始不会满负载传输，在不断尝试后才会提高负载。因此便提出了复用TCP的连接的需求，那样将会节约很多时间和资源。</div><div class="notion-text notion-block-967aa261f9754e07a1c0469aced664af">在最早的HTTP/1.0中是不支持长连接的，在每次HTTP响应结束后，都要求必须要结束连接，这就是短连接。</div><div class="notion-text notion-block-fa5f3c954e7b42c9b751df448e5d1404">在HTTP1/1.1中在Header中新增了Connection字段，取值为 close 和 keep-alive，close就是对应的HTTP/1.0时期的短连接，而默认则都是keep-alive，即长连接，除非特别声明使用close，否则均为长连接。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-02bd7eac678e4b8893de7e5ab4ccd483" data-id="02bd7eac678e4b8893de7e5ab4ccd483"><span><div id="02bd7eac678e4b8893de7e5ab4ccd483" class="notion-header-anchor"></div><a class="notion-hash-link" href="#02bd7eac678e4b8893de7e5ab4ccd483" 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-3faa7e1df7f54d7a86513ee86076f96a">在HTTP/1.0时不存在这个问题，只要结束连接即可视为传输完成，但在HTTP1/1.1复用TCP连接时，边出现了问题，我要怎么知道使用同一个TCP连接的某一个请求是否响应完成。</div><div class="notion-text notion-block-2a2241ed605d486a8c127c8506adb9a0">而在持久连接中，我们为了判断当前请求是否结束，我们向响应头中增添了一个Content-Length字段，这个字段用于告诉浏览器等客户端，响应体有多大，在读取到一定的数据后即可认为相应结束。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-461e584d43324bd9ac51704f9a403739"><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%2Fa5a46c38-63f0-4f6a-ab7a-2cd059e716c8%2Ff45d1b6a-da3c-411f-8ed1-1f3536afd2b1%2FUntitled.png?table=block&amp;id=461e584d-4332-4bd9-ac51-704f9a403739&amp;t=461e584d-4332-4bd9-ac51-704f9a403739&amp;width=1028&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-261ed5dead4c4184aa8acbc8db0af1a9">利用这个字段我们就可以很好的判断响应是否结束，但也因此我们必须要确保Content-Length的大小和实际响应大小要完全一致，如果Content-Length大于实际相应就会导致浏览器一直处于Pending状态，而Content-Length小于实际响应就会导致响应被错误截断，可能会发生意想不到的情况。</div><div class="notion-text notion-block-446169acb00c4802a8464865f33877a4">在早期的互联网，提前算出响应的大小并放在响应头中是完全可以做到的，但在互联网不断的发展下，相应的内容可能是动态生成的，或是无法提前算出长度。</div><div class="notion-text notion-block-5742297b0988451da59d8cbb451528e0">比如，一个很大的文件，如果你要算出其长度则需要将其先读取到内存中，才能获取到整个文件的大小，但这样则必须确保内存大小足够，但实际上只是为了统计大小，实在有点浪费资源。</div><div class="notion-text notion-block-59117da0cb754fe9b30fd5f6354d9a69">又或者，我现在要返回的内容是在不断生成的，我可能正在使用ffmpeg来处理视频，处理的视频文件在不断生成，为了算出响应大小，唯一的办法只能等待文件全部生成完毕然后读取到内存来计算，但这样耗费的时间不说，同样也面临着上面的问题。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-d698c24f0e064bfb9be90450bf93449d" data-id="d698c24f0e064bfb9be90450bf93449d"><span><div id="d698c24f0e064bfb9be90450bf93449d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d698c24f0e064bfb9be90450bf93449d" title="分块编码传输 chunked"><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">分块编码传输 chunked</span></span></h3><div class="notion-text notion-block-2f78829162664470b4b88c29e581aeb1">为了解决以上的问题，在HTTP1/1.1中还增加了一个请求头Transfer-Encoding，在HTTP1/1.1中唯一的取值为chunked。</div><div class="notion-callout notion-gray_background_co notion-block-40d300b98aed4e6e8227796379370028"><div class="notion-page-icon-inline notion-page-icon-span"><span class="notion-page-icon" role="img" aria-label="💡">💡</span></div><div class="notion-callout-text"><div class="notion-text notion-block-e5bc53c777154498858cd725bdf583a3">分块传输的规则：</div><ol start="1" class="notion-list notion-list-numbered notion-block-27cb76df441a47018088d843feddae0c" style="list-style-type:decimal"><li>每个分块包含一个 16 进制的数据长度值和真实数据。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3891eb9facc34f188b7d1976d6444c05" style="list-style-type:decimal"><li>数据长度值独占一行，和真实数据通过 CRLF(\r\n) 分割。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3740bae1574a42699b47d7aa3967affe" style="list-style-type:decimal"><li>数据长度值，不计算真实数据末尾的 CRLF，只计算当前传输块的数据长度。</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-c89df90d10af4ae6b2cf6b287d61ad62" style="list-style-type:decimal"><li>最后通过一个数据长度值为 0 的分块，来标记当前内容实体传输结束。</li></ol></div></div><div class="notion-text notion-block-12398bb93a894dc083b0d5fe7c805519">由于分块编码传输将数据分为长度很短的数据块，并且以0作为结束，那么我们就不需要使用Content-Length来告知浏览器响应何时结束，只需要在读取到结束分块后拼接数据。</div><div class="notion-text notion-block-089932d031714248998d36f29fc56dd6">而由于分块编码传输的分块特性，分块编码传输建立在TCP连接复用的基础上，所以这也是在HTTP1/1.1中才提出的原因。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fa4c2233c0f453b804954c2f64d2bf2" data-id="3fa4c2233c0f453b804954c2f64d2bf2"><span><div id="3fa4c2233c0f453b804954c2f64d2bf2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fa4c2233c0f453b804954c2f64d2bf2" 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-46633fcf157a43038115ac636c961399">在实习的过程中，由于使用的gofiber来做后端，而在fiber的文档中对分块编码传输的帮助又少之又少，最后是在相关的issue中找到，在下面记录一下代码实现。</div><a class="notion-external notion-external-block notion-row notion-block-3002830676554af6b70a2be3af435584" href="https://github.com/gofiber/fiber/issues/2429" target="_blank" rel="noopener noreferrer"><div class="notion-external-image"><svg viewBox="0 0 260 260"><g><path d="M128.00106,0 C57.3172926,0 0,57.3066942 0,128.00106 C0,184.555281 36.6761997,232.535542 87.534937,249.460899 C93.9320223,250.645779 96.280588,246.684165 96.280588,243.303333 C96.280588,240.251045 96.1618878,230.167899 96.106777,219.472176 C60.4967585,227.215235 52.9826207,204.369712 52.9826207,204.369712 C47.1599584,189.574598 38.770408,185.640538 38.770408,185.640538 C27.1568785,177.696113 39.6458206,177.859325 39.6458206,177.859325 C52.4993419,178.762293 59.267365,191.04987 59.267365,191.04987 C70.6837675,210.618423 89.2115753,204.961093 96.5158685,201.690482 C97.6647155,193.417512 100.981959,187.77078 104.642583,184.574357 C76.211799,181.33766 46.324819,170.362144 46.324819,121.315702 C46.324819,107.340889 51.3250588,95.9223682 59.5132437,86.9583937 C58.1842268,83.7344152 53.8029229,70.715562 60.7532354,53.0843636 C60.7532354,53.0843636 71.5019501,49.6441813 95.9626412,66.2049595 C106.172967,63.368876 117.123047,61.9465949 128.00106,61.8978432 C138.879073,61.9465949 149.837632,63.368876 160.067033,66.2049595 C184.49805,49.6441813 195.231926,53.0843636 195.231926,53.0843636 C202.199197,70.715562 197.815773,83.7344152 196.486756,86.9583937 C204.694018,95.9223682 209.660343,107.340889 209.660343,121.315702 C209.660343,170.478725 179.716133,181.303747 151.213281,184.472614 C155.80443,188.444828 159.895342,196.234518 159.895342,208.176593 C159.895342,225.303317 159.746968,239.087361 159.746968,243.303333 C159.746968,246.709601 162.05102,250.70089 168.53925,249.443941 C219.370432,232.499507 256,184.536204 256,128.00106 C256,57.3066942 198.691187,0 128.00106,0 Z M47.9405593,182.340212 C47.6586465,182.976105 46.6581745,183.166873 45.7467277,182.730227 C44.8183235,182.312656 44.2968914,181.445722 44.5978808,180.80771 C44.8734344,180.152739 45.876026,179.97045 46.8023103,180.409216 C47.7328342,180.826786 48.2627451,181.702199 47.9405593,182.340212 Z M54.2367892,187.958254 C53.6263318,188.524199 52.4329723,188.261363 51.6232682,187.366874 C50.7860088,186.474504 50.6291553,185.281144 51.2480912,184.70672 C51.8776254,184.140775 53.0349512,184.405731 53.8743302,185.298101 C54.7115892,186.201069 54.8748019,187.38595 54.2367892,187.958254 Z M58.5562413,195.146347 C57.7719732,195.691096 56.4895886,195.180261 55.6968417,194.042013 C54.9125733,192.903764 54.9125733,191.538713 55.713799,190.991845 C56.5086651,190.444977 57.7719732,190.936735 58.5753181,192.066505 C59.3574669,193.22383 59.3574669,194.58888 58.5562413,195.146347 Z M65.8613592,203.471174 C65.1597571,204.244846 63.6654083,204.03712 62.5716717,202.981538 C61.4524999,201.94927 61.1409122,200.484596 61.8446341,199.710926 C62.5547146,198.935137 64.0575422,199.15346 65.1597571,200.200564 C66.2704506,201.230712 66.6095936,202.705984 65.8613592,203.471174 Z M75.3025151,206.281542 C74.9930474,207.284134 73.553809,207.739857 72.1039724,207.313809 C70.6562556,206.875043 69.7087748,205.700761 70.0012857,204.687571 C70.302275,203.678621 71.7478721,203.20382 73.2083069,203.659543 C74.6539041,204.09619 75.6035048,205.261994 75.3025151,206.281542 Z M86.046947,207.473627 C86.0829806,208.529209 84.8535871,209.404622 83.3316829,209.4237 C81.8013,209.457614 80.563428,208.603398 80.5464708,207.564772 C80.5464708,206.498591 81.7483088,205.631657 83.2786917,205.606221 C84.8005962,205.576546 86.046947,206.424403 86.046947,207.473627 Z M96.6021471,207.069023 C96.7844366,208.099171 95.7267341,209.156872 94.215428,209.438785 C92.7295577,209.710099 91.3539086,209.074206 91.1652603,208.052538 C90.9808515,206.996955 92.0576306,205.939253 93.5413813,205.66582 C95.054807,205.402984 96.4092596,206.021919 96.6021471,207.069023 Z" fill="#161614"></path></g></svg></div><div class="notion-external-description"><div class="notion-external-title">🤗 [Question]: How to stream large file for download ?</div></div></a><div class="notion-blank notion-block-39f67fdeb7354d04bc8152a484766368"> </div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Tailscale 杂谈NAT]]></title>
            <link>https://blog.borry.org/article/tailscale-net</link>
            <guid>https://blog.borry.org/article/tailscale-net</guid>
            <pubDate>Mon, 20 Nov 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[NAT是什么，Tailscale是怎么实现的异地组网和端到端连接]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-ddd7a974f4ad456097e8ae070c13b70b"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-28f2f29399e04a69bb26742112d942bd" data-id="28f2f29399e04a69bb26742112d942bd"><span><div id="28f2f29399e04a69bb26742112d942bd" class="notion-header-anchor"></div><a class="notion-hash-link" href="#28f2f29399e04a69bb26742112d942bd" 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></h2><div class="notion-text notion-block-cdf9c0ff6fa14dcbaaa9159be5bf7dc5">随着全球终端设备的增加，IPV4的数量早已经不足以支持为每台设备分配一个独立的公网IP地址。从子网掩码到NAT，都是为了解决IPV4数量不够用的技术，虽然IPV6已经推广了很多年，但由于IPV6和IPV4的协议栈不能直接兼容，必须要得到服务提供商的适配，因此IPV6即使推出很久，市面上的解决方案依旧是使用NAT相关技术，从早年电信会提供公网IP，到现在基本全都是分配的内网路由。</div><div class="notion-text notion-block-43929ffafcf54017a8def7b31226c087">所以现在很难在现代互联网中实现理想中的端到端连接，有着一层层防火墙，NAT，更甚还有ISP运营商的CGNAT。</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-012bde2ae5784b9f95896836023bdb34" data-id="012bde2ae5784b9f95896836023bdb34"><span><div id="012bde2ae5784b9f95896836023bdb34" class="notion-header-anchor"></div><a class="notion-hash-link" href="#012bde2ae5784b9f95896836023bdb34" title="防火墙和NAT是怎么阻止端到端连接的"><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">防火墙和NAT是怎么阻止端到端连接的</span></span></h2><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-278de2ffd4da4208ad697c4b867894f2" data-id="278de2ffd4da4208ad697c4b867894f2"><span><div id="278de2ffd4da4208ad697c4b867894f2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#278de2ffd4da4208ad697c4b867894f2" 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-bbcfa5a5159b4b8eba09c5318efafbcb">在Windows和Linux上都有自己的防火墙，Windows上是Windows Defendar防火墙，Linux如ubuntu是ufw等，无论是哪个平台的防火墙，目的都是使用规则来允许或阻止特定的网络流量。用户可以使用规则来配置允许的入站、出站端口、源IP、目标IP，使用的协议等，本质是为了确保本机的网络安全，但却对我们所需要的端到端连接进行了阻碍。所以，即使IPV6进行了普及，类似的组网技术不会消失，因为没有了NAT的阻碍，企业和运营商也会为了网络安全配置防火墙，企业和运营商的网络出口仍然不是个人能够控制的。</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-1829b83edfa046819705af85a96714be" data-id="1829b83edfa046819705af85a96714be"><span><div id="1829b83edfa046819705af85a96714be" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1829b83edfa046819705af85a96714be" title="NAT"><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">NAT</span></span></h3><div class="notion-text notion-block-79ab2c58a7c14c06ac89cf8ce8327da8">NAT(NETWORK ADDRESS TRANSLATION) 网络地址转换，NAT也是为了解决IPV4地址的短缺而提出的，下面用一个例子来解释NAT是如何工作，以及如何阻止我们进行端到端连接的。</div><div class="notion-text notion-block-5728c4d0db3b403ea1398c7da75a596e"><b>如下：</b></div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-abff1460b80d4958a396340713913b54"><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%2Fa5a46c38-63f0-4f6a-ab7a-2cd059e716c8%2Fb1f70790-4600-411c-8abc-7b5423fd8b5f%2FIMG_1086.png?table=block&amp;id=abff1460-b80d-4958-a396-340713913b54&amp;t=abff1460-b80d-4958-a396-340713913b54&amp;width=2080&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-94cfb0d6183d40989d06510877ed1332">我们的Laptop是位于一个192.168.0.0/16的内网地址中，那么他要向一个处于公网的Server（7.7.7.7）通信，如果不经过NAT直接和Server进行通信，Server在进行响应的时候就会产生疑惑，因为内网地址在不同网络中是可以重复的，每个人家中都有可能有一台192.168.0.20的设备，所以Server无法定位到唯一的设备。</div><div class="notion-text notion-block-f1f84b551679482fabbfdb3ebe664618">因此NAT的作用就是将无法和公网通信的内网IP转为公网IP交由网关进行转发。</div><ul class="notion-list notion-list-disc notion-block-81b85f2bed584ca79e10d1d1b372da7f"><li>Laptop 发起请求 Server </li></ul><ul class="notion-list notion-list-disc notion-block-0ae09ec6bd54489bae080a1b6795bb7b"><li>请求转发给网关</li></ul><ul class="notion-list notion-list-disc notion-block-1b15e7c494b74cdd9d35fe4b3fc1fe2c"><li>网关使用NAT对IP数据包进行修改，首先为这个请求分配一个端口用于接收响应，然后维护一条记录，内容为 内网ip:port — 公网ip:port ，最后将数据包中的源地址进行修改再将数据包发往Server</li></ul><ul class="notion-list notion-list-disc notion-block-5cb3790131124a3a907dadc578a97314"><li>Server收到请求后，将响应发回给指定端口，网关即可根据NAT维护的记录得知该将响应转发给内网的哪台设备</li></ul><div class="notion-text notion-block-41caf4c38e2644d58b39cec6ef2cb1b8">通过在网关上维护一个ip:port表，实现了公网IP复用。虽然NAT解决了IPV4地址的短缺，但同时也让网络变得更复杂了，现在只能由Laptop向Server发起单向通信，但Server却没有办法主动向Laptop发起通信请求，因为它无法通过NAT网关来直接访问Laptop。</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-f306e6fcbfa341e2b9697ea5954315e6" data-id="f306e6fcbfa341e2b9697ea5954315e6"><span><div id="f306e6fcbfa341e2b9697ea5954315e6" class="notion-header-anchor"></div><a class="notion-hash-link" href="#f306e6fcbfa341e2b9697ea5954315e6" 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></h2><div class="notion-text notion-block-0086f3f3e82a47c4810bbad7624f2f05">Tailscale是一个基于wireguard协议的虚拟组网工具，能进行NAT穿透、Relay中转的方式进行虚拟组网。 </div><div class="notion-row"><a class="notion-bookmark notion-block-88a501f0578b40178cff64cefcf48249" href="https://tailscale.com" target="_blank" rel="noopener noreferrer"><div><div class="notion-bookmark-title">Tailscale</div><div class="notion-bookmark-description">Tailscale is a zero config VPN for building secure networks. Install on any device in minutes. Remote access from any network or physical location.</div><div class="notion-bookmark-link"><div class="notion-bookmark-link-icon"><img src="https://www.notion.so/image/https%3A%2F%2Ftailscale.com%2Ffiles%2Fapple-touch-icon.png?table=block&amp;id=88a501f0-578b-4017-8cff-64cefcf48249&amp;t=88a501f0-578b-4017-8cff-64cefcf48249" alt="Tailscale" loading="lazy" decoding="async"/></div><div class="notion-bookmark-link-text">https://tailscale.com</div></div></div><div class="notion-bookmark-image"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Ftailscale.com%2Ffiles%2Fimages%2Fog-image.png?table=block&amp;id=88a501f0-578b-4017-8cff-64cefcf48249&amp;t=88a501f0-578b-4017-8cff-64cefcf48249" alt="Tailscale" loading="lazy" decoding="async"/></div></a></div><div class="notion-text notion-block-90aa58999f36475bb08c7bf4bfc1452d">说起虚拟组网，大家可能会想到VPN，VPN就是为了在公网中实现加密的内网通信所提出的，它能够利用互联网建立加密的隧道来进行通信，异地组网，企业中为了安全性一般防火墙规则一般都异常严格，因此企业一般都采用VPN来使得员工连接公司内网。</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-0a9fc5f14e4044ffa11374f1ffc4c285" data-id="0a9fc5f14e4044ffa11374f1ffc4c285"><span><div id="0a9fc5f14e4044ffa11374f1ffc4c285" class="notion-header-anchor"></div><a class="notion-hash-link" href="#0a9fc5f14e4044ffa11374f1ffc4c285" title="传统VPN"><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">传统VPN</span></span></h3><div class="notion-text notion-block-b4569aee650b4dc1a7904185eded956f">传统的VPN都需要一个拥有公网IP的服务器充当中转，因为无论是NAT还是防火墙，都只会接收本机想要通信的目标所发送的包，因此才需要一个位于公网并且配置了转发表的服务器。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-1af28ae99fd94d50be1fd87c7dda3f05"><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%2Fa5a46c38-63f0-4f6a-ab7a-2cd059e716c8%2F6a1cfc56-197e-46bb-9a60-22ea4df7eb63%2FIMG_1084.png?table=block&amp;id=1af28ae9-9fd9-4d50-be1f-d87c7dda3f05&amp;t=1af28ae9-9fd9-4d50-be1f-d87c7dda3f05&amp;width=2100&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-ffe53ebf031e4c1f8d44d7887897900c">这样的网络因为都是基于中转服务器进行通信，所以也被称为“星形网络”，网络的上限受困于中转服务器的带宽限制，再加上国内云服务商高昂的带宽使得这种方案在国内收到很大的限制。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-6f181fbcbadd4c3aa2d2e396e888f7fe"><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%2Fa5a46c38-63f0-4f6a-ab7a-2cd059e716c8%2Ff8f14548-09e6-4a3f-bda4-078ba7d6a8c3%2FIMG_1083.png?table=block&amp;id=6f181fbc-badd-4c3a-a2d2-e396e888f7fe&amp;t=6f181fbc-badd-4c3a-a2d2-e396e888f7fe&amp;width=2210&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-1282ac3047784a76bb93e403afae65c3" data-id="1282ac3047784a76bb93e403afae65c3"><span><div id="1282ac3047784a76bb93e403afae65c3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1282ac3047784a76bb93e403afae65c3" 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></h2><div class="notion-text notion-block-fb818ada6b4247a1aee350ea2fa16bd1">而Tailscale是一个基于wireguard协议的虚拟组网工具，能够实现端对端访问，即最理想的访问方式，我要访问B，那我直接向B发起请求，实现了跨NAT通信。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-d0eb1c6b2d354a47a01b5352650d915b"><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%2Fa5a46c38-63f0-4f6a-ab7a-2cd059e716c8%2F2af6f245-a797-4e5e-9a23-11ac9d7b0e03%2FIMG_1085.png?table=block&amp;id=d0eb1c6b-2d35-4a47-a01b-5352650d915b&amp;t=d0eb1c6b-2d35-4a47-a01b-5352650d915b&amp;width=1700&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-36ed8a283cec46829a322a08dbefed89" data-id="36ed8a283cec46829a322a08dbefed89"><span><div id="36ed8a283cec46829a322a08dbefed89" class="notion-header-anchor"></div><a class="notion-hash-link" href="#36ed8a283cec46829a322a08dbefed89" 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-c222ff44f7ed4fcbb5f91ba5b1952238">但大家可能好奇这是怎么实现的，在层层路由器下，我们的终端设备所能拿到的IP大多都是内网IP段。</div><div class="notion-callout notion-gray_background_co notion-block-a8ff96bc11234cdd82a38efc66cec328"><div class="notion-page-icon-inline notion-page-icon-span"><span class="notion-page-icon" role="img" aria-label="💡">💡</span></div><div class="notion-callout-text">内网IP段如下
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16   </div></div><ol start="1" class="notion-list notion-list-numbered notion-block-d6eeec4c38104c06921942f0e36e64e1" style="list-style-type:decimal"><li>首先laptop在经过NAT将请求转为一个 <b>ip:port 格式后，向 Server发起请求，但由于Server的NAT表中不存在发向2.2.2.2的请求自然无法实现转发</b></li></ol><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-e2047643f3b542b0944707128b0f8b7f"><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%2Fa5a46c38-63f0-4f6a-ab7a-2cd059e716c8%2Fa317cfd9-1623-4b40-b920-5309656f56bc%2FIMG_1087.png?table=block&amp;id=e2047643-f3b5-42b0-9447-07128b0f8b7f&amp;t=e2047643-f3b5-42b0-9447-07128b0f8b7f&amp;width=1740&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><ol start="2" class="notion-list notion-list-numbered notion-block-9cd7f3e0572246b38c4d439d28374051" style="list-style-type:decimal"><li>虽然第一步失败了，但是由于laptop向server发起请求，在laptop的NAT上存在了转发关系，此时只要server向laptop的 <b>ip:port 发送请求自然就会被latop的NAT进行转发</b></li></ol><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-27b532ecced04db0b05fc465331af15e"><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%2Fa5a46c38-63f0-4f6a-ab7a-2cd059e716c8%2F718353bd-fb65-48c9-b896-1f5a2e5ecf84%2FIMG_1088.png?table=block&amp;id=27b532ec-ced0-4db0-b05f-c465331af15e&amp;t=27b532ec-ced0-4db0-b05f-c465331af15e&amp;width=1740&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><ol start="3" class="notion-list notion-list-numbered notion-block-80edfc31f56b4e7c867d931a3a40422e" style="list-style-type:decimal"><li>最后因为Server向laptop发起请求，因此server的NAT表上也有了转发关系，因此也能接受来自laptop的后续请求。</li></ol><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-6ebdeb4bb53745a0953ba0e072e02815"><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%2Fa5a46c38-63f0-4f6a-ab7a-2cd059e716c8%2Fcbef400e-cd29-431e-95f6-b6e5b91df05c%2FIMG_1091.png?table=block&amp;id=6ebdeb4b-b537-45a0-953b-a0e072e02815&amp;t=6ebdeb4b-b537-45a0-953b-a0e072e02815&amp;width=1740&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-5b1ce0195b1a47f7ba0d966fedd49e88">这样来看是不是很简单，但这只是非常理想的情况，实际的网络环境可能非常复杂，NAT不止一层，防火墙也不止一层，在上面的模型中，甚至第一步都无法顺利实施，在两边都是内网的情况下，谁先发起通信，发给谁，我的公网出口是什么？</div><div class="notion-text notion-block-10f55c8f11b548b9bd4b95faa70c11a5">感兴趣的可以去看看Tailscale官方的这篇博客</div><div class="notion-row"><a class="notion-bookmark notion-block-2cfd356cdcfb47c9a3f7df4b47fe8ec8" href="https://tailscale.com/blog/how-nat-traversal-works/" target="_blank" rel="noopener noreferrer"><div><div class="notion-bookmark-title">How NAT traversal works</div><div class="notion-bookmark-description">In this post, we’ll talk about how to establish a peer-to-peer connection between two machines, in spite of all the obstacles in the way.</div><div class="notion-bookmark-link"><div class="notion-bookmark-link-icon"><img src="https://www.notion.so/image/https%3A%2F%2Ftailscale.com%2Ffiles%2Fapple-touch-icon.png?table=block&amp;id=2cfd356c-dcfb-47c9-a3f7-df4b47fe8ec8&amp;t=2cfd356c-dcfb-47c9-a3f7-df4b47fe8ec8" alt="How NAT traversal works" loading="lazy" decoding="async"/></div><div class="notion-bookmark-link-text">https://tailscale.com/blog/how-nat-traversal-works/</div></div></div><div class="notion-bookmark-image"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Ftailscale.com%2Fblog%2Fhow-nat-traversal-works%2Fsocial.png?table=block&amp;id=2cfd356c-dcfb-47c9-a3f7-df4b47fe8ec8&amp;t=2cfd356c-dcfb-47c9-a3f7-df4b47fe8ec8" alt="How NAT traversal works" loading="lazy" decoding="async"/></div></a></div><div class="notion-blank notion-block-ff4de9977e48485fb4c139f048273e25"> </div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[深澜自助服务中心分析]]></title>
            <link>https://blog.borry.org/article/srun-analyse</link>
            <guid>https://blog.borry.org/article/srun-analyse</guid>
            <pubDate>Fri, 23 Jun 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[校园网自助服务中心模拟登陆]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-59143adf27bf428fb14504995f4b1d71"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-callout notion-red_co notion-block-9b4176f7a36a401a963ac882547daf8c"><div class="notion-page-icon-inline notion-page-icon-span"><span class="notion-page-icon" role="img" aria-label="💡">💡</span></div><div class="notion-callout-text">该漏洞已被修复，现在只能已登陆的设备才能使用code进行快速跳转。 </div></div><div class="notion-callout notion-red_co notion-block-6ce41e6db5db4956b520df8dfbe36478"><div class="notion-page-icon-inline notion-page-icon-span"><span class="notion-page-icon" role="img" aria-label="💡">💡</span></div><div class="notion-callout-text">更新于 2023/12/05</div></div><div class="notion-blank notion-block-d841de6cf503400e86019566dedfc714"> </div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-5bc35178fc484265a0b8cc812a51af7a" data-id="5bc35178fc484265a0b8cc812a51af7a"><span><div id="5bc35178fc484265a0b8cc812a51af7a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#5bc35178fc484265a0b8cc812a51af7a" 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-bf039ffa9675489e873b63d500e68c7f">为了实现对深澜校园网登陆设备，无感知认证等自动控制，尝试使用抓包了来进行模拟登陆实现。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-4d589dcd1eda4a90a88e295ed7e2d1d4"><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%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F5135853d-c979-4080-a52b-28dc37f70360%2FUntitled.png?table=block&amp;id=4d589dcd-1eda-4a90-a88e-295ed7e2d1d4&amp;t=4d589dcd-1eda-4a90-a88e-295ed7e2d1d4&amp;width=1063&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-09a5d037dc44440b99dad04b515ea4b0">登陆非常简单，一个POST请求就可以实现，但是由于验证码的存在，想到了ddddocr来实现验证码识别，但识别效果欠佳，虽然可以自行训练数据集，但是过于麻烦，便就此放弃了这个方案。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-8f5617fabeeb4c589cf1859326510a58" data-id="8f5617fabeeb4c589cf1859326510a58"><span><div id="8f5617fabeeb4c589cf1859326510a58" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8f5617fabeeb4c589cf1859326510a58" 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-539e4cd48df943fba95bf0f04b9a0823">在日常使用过程中，无意间发现如果当前已经登陆了校园网，那么点击校园网认证页面的“自助服务”按钮即可直接跳转到自助服务中心不需要手动登陆，通过观察跳转的url，发现本质其实是跳转的url中包含了认证信息。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-e45cd882a6254fe384a9e71f99443dc4"><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%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F0e0230e3-c0c1-4a0b-84b5-a4882be80cde%2FIMG_0411.jpeg?table=block&amp;id=e45cd882-a625-4fe3-84a9-e71f99443dc4&amp;t=e45cd882-a625-4fe3-84a9-e71f99443dc4&amp;width=1006&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-40746b79d1c7418eace21574901c6ead">经过测试只要拿到data的内容即可实现无需密码登录，便不用考虑验证码的问题。</div><div class="notion-text notion-block-8709c80e311347169ee2bf6b02c0bfd2">通过分析认证页面的所有js文件和html中的跳转逻辑，最终成功找到了一个名为 toSelfService一个函数</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-8e980091123042ed9e1bcea7f3fa544f"><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%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Ff1cb96f6-1d34-40be-bc67-925a9f3d5be3%2FUntitled.png?table=block&amp;id=8e980091-1230-42ed-9e1b-cea7f3fa544f&amp;t=8e980091-1230-42ed-9e1b-cea7f3fa544f&amp;width=1887&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-a18dc98c91de47e790b363bbd9f7e30e">在这个函数中详细的写到了url的生成，前面猜想data的内容是静态在这里也得到了证实，将用户名密码进行编码后即可得到data的值，这里猜想会有很多安全隐患，假如这个接口没有其他的防止爆破的保护的话，那么我是否可以利用学号和身份证后六位来试出学校大多数学生的校园网密码。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-c4fd42a7232e41b9adad5263c1ca4fa3" data-id="c4fd42a7232e41b9adad5263c1ca4fa3"><span><div id="c4fd42a7232e41b9adad5263c1ca4fa3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c4fd42a7232e41b9adad5263c1ca4fa3" 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-ab79a77e725d4dbe896b780978feddcc">选用Python来进行快速的想法验证，后期会使用Go进行全部重写。</div><div class="notion-text notion-block-d782d8e03c9547f1824c38bab7428261">首先，使用requests库的session()来存储登录状态，方便实现登陆后其他操作。</div><div class="notion-text notion-block-66c7199742634c0fa5d6f89c9b204117">其次，由于校园网的认证页面为10.0.0.0/8的内网地址，因此为了在任何地方都能进行操作，考虑在校内搭建一个代理服务</div><div class="notion-text notion-block-b6e56d4238774a948cd640f3c85edf99">最后就是很简单的代码实现了</div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[使用环境变量存储SSH私钥格式错误]]></title>
            <link>https://blog.borry.org/article/ssh-environment-key</link>
            <guid>https://blog.borry.org/article/ssh-environment-key</guid>
            <pubDate>Wed, 19 Jul 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[在使用Zeabur等托管平台时，使用环境变量来存储Key遇到的问题]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-29579a827df448748d5080e71968726c"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-text notion-block-f2969c608da64571bbc56c2467e92c9a">如果你想把你的ssh私钥或公钥放到环境变量中，然后在CI系统上访问它，怎么办？</div><div class="notion-text notion-block-74be73770e4c4816af2f09c9277423e3">一个键看起来像这样，那么你如何在没有换行的情况下将其转换为base64字符串呢？</div><div class="notion-text notion-block-8e9075d7c7514f8f81b722d944af1b61">首先生成你的钥匙，或者你可以使用任何现有的钥匙，无论是RSA还是ED25519。</div><div class="notion-text notion-block-1ee645a2c6fa43d1a3051f3aa851da46">将其编码为base64</div><div class="notion-text notion-block-4e99e49c562c49a5b4afc272743bfaaa">现在你可以把输出结果复制粘贴到你想要的任何地方，这应该会给你一个有0个换行的字符串。</div><div class="notion-text notion-block-6399e46c275f4f87a2e8fa33c4bd7951">To verify</div><div class="notion-text notion-block-22262105d03545788abb9749b52058d4">你应该看到与你的文件中相同的键。</div></main></div>]]></content:encoded>
        </item>
    </channel>
</rss>