I'm starting to provide Chinese / English versions of some articles, switch with the Language menu above. 我开始提供部分文章的中文、英文翻译,请使用顶部语言菜单切换。

Bird 配置 BGP Confederation,及模拟 Confederation(2020-06-07 更新)

更新记录 ¶2020-10-01:添加警告,模拟 Confederation 时不能在内网滤掉内部 ASN2020-06-07:添加 Bird Confederation 的局限,及模拟 Confederation 方法 2020-05-17:最初版本ISP 内部 BGP 互联方案比较 ¶互联网中各个 ISP(互联网服务提供商)绝大多数都使用 BGP 协议互相交换自己的路由信息。每个 ISP 都会从所在区域的网络信息中心(NIC,例如 APNIC,RIPE)获得一个 ASN(自治域编号),例如中国电信的 ASN 是 4134。然后 ISP 之间通过物理连接(铜缆,光纤,卫星网络等)连接各自的边界路由器,然后在边界路由器上配置 BGP 协议,告诉对方:“我是 AS4134,我这里可以访问到 202.101.0.0/18 这个 IP 段”。与中国电信相连的 ISP 的路由器会接力把这条消息广播下去:“我是 ASXXXX,我距离 202.101.0.0/18 有一格距离”,以此类推。各个 ISP 的路由器就会根据到目标的距离等参数,把数据包发送到对这个路由器来说最优的目标。(注:以上内容经过简化,实际世界中的 ISP 互联、数据包路径选择会有更加复杂的规则。)而一个大型 AS 的内部也有可能需要使用 BGP 等路由协议,例如中国电信拥有覆盖整个中国大陆的网络,在各个城市都有核心路由器,...

x32 ABI 及相应 Docker 容器使用

x32 架构是怎么回事呢?x86、x86_64 架构相信大家都很熟悉,但是 x32 是怎么回事呢,下面就让小编带大家一起了解吧。x32 架构,其实就是 x86 和 x86_64 架构拼在一起,大家可能会很惊讶 x86 和 x86_64 架构怎么会拼在一起呢?但事实就是这样,小编也感到非常惊讶。x86 及 x86_64 的历史,以及 x32 ABI ¶我们现在使用的个人计算机及服务器绝大多数都使用 x86_64 架构,该架构由 AMD 于 2000 年发布规范,2003 年发布第一块处理器。x86_64 是一个 64 位的架构,意味着在 x86_64 中,CPU 的每个寄存器都能保存 64 bit 的数据(即 8 个字节)。在 x86_64 流行之前,多数电脑都使用 Intel 处理器以及相应的 x86 架构 / 指令集,这是一个 32 位的架构,每个寄存器可以保存 32 bit 的数据(即 4 个字节)。64 位架构的一个显著好处是内存寻址能力的提升。计算机在访问内存时通常按照这样一个流程:将要访问的内存地址写入寄存器,然后将这个寄存器的内容发送到内存地址总线上。也正因此,32 位架构计算机只能使用 32 bit 表示内存地址,总共能够表示 232=42949672962^{32} = 4294967296232=4294967296 个地址(字节),也就是 4 GB。...

写一个简单的 Telegram 机器人

应 DN42 Telegram 群群友的要求,我打算给我的 Bird Looking Glass 加上 Telegram Bot 的支持,方便群友现场查询 Whois、测试网络通断、检查漏油路由泄漏源头等。这个 Bot 要能识别以斜线 / 开头的命令,然后对命令消息进行回复。我的 Looking Glass 使用 Go 语言写成,因此我一开始先查找了 Go 语言的 Telegram Bot API。但流行的 API 库无一例外都遵循了同样的请求结构:Telegram 服务器发送一个回调到自己的服务器;自己的程序处理请求,期间可能根据本地配置的 Token 向 Telegram 服务器多次主动请求;自己的程序最终主动请求 Telegram 服务器,发送回复信息。这套方案功能强大,但有点复杂,而多余的功能我根本用不上。我更希望使用 Telegram 官方提供的另一种方式,直接回复回调 HTTP 请求的方式:Telegram 服务器发送一个回调到自己的服务器;自己的程序处理请求后,直接以 HTTP Response 方式回复回调请求,执行操作。虽然这种方法限制我对一个请求只能做出一个回复,但因为我的 Bot 也只需要回复一次,对我来说已经够用。同时这种方法也具有以下的优点:写起程序来极其简单,根本不需要第三方库。服务端无需知道 Token,减少了配置量。同时也可以创建多个机器人,...

Docker 容器共享网络命名空间,集成 Bird 实现 Anycast 高可用

正好一年前,我在 DN42 网络内用 Docker 建立了 Anycast 服务。当时我的方法是,自定义容器的镜像,在其中安装一个 Bird,然后加入 OSPF 协议的配置文件来广播 Anycast 路由。但是随着时间推移,这套方案出现了以下问题:安装 Bird 本身是个较花时间的过程。我的 Bird 不是用 apt-get 装的,因为我的 Dockerfile 需要支持多种 CPU 架构,而 Debian 有些架构的软件源里没有 Bird。而又因为我的构建服务器是 AMD64 架构,使用 qemu-user-static 支持其它架构的镜像运行,为其它架构制作镜像、编译程序时就涉及到大量的指令集翻译,效率非常低。构建一个镜像在不同架构下的版本可能需要 2 小时以上,而安装应用本身的 apt-get 流程只需要几分钟。自己定制镜像也比较花时间。因为容器中需要同时运行目标应用(例如之前的 PowerDNS)和 Bird,就不能直接把目标应用作为 ENTRYPOINT 了,而添加其它的管理程序(supervisord、s6-supervise、tini、自己写 Bash 脚本)等都额外增加了镜像复杂度(也就是出问题的概率),还要考虑信号、返回值传递,以及僵尸进程的问题。最近我在读 docker-compose 的参考文档时,...
插图

使用 PowerDNS 的 Lua 功能自建分地区解析 GeoDNS

之前,如果要为自己的网站自建权威 DNS 系统,那么(几乎)唯一的选择是 PowerDNS 加上它的 GeoIP 后端。但是 GeoIP 后端使用的是 YAML 格式的配置文件,不能与 MySQL 等数据库一同使用。这意味着必须手动配置一套跨服务器同步文件的系统,而不能使用更为成熟的数据库同步技术。不过,PowerDNS 在最新的 4.2 版本中加入了 Lua 记录的支持。Lua 是一种专门用于 “嵌入其它程序执行功能” 的编程语言,你或许曾经在 nginx 上看到过它(作为一个插件)。Lua 记录支持使得 PowerDNS 可以根据用户查询请求的不同来返回不同的回答,分地区解析 GeoDNS 功能也就可以实现了。更新 PowerDNS ¶最新的 PowerDNS 4.2 版本没有加入 Debian 10 的软件仓库中,你需要从 Debian Unstable 的软件仓库下载。但是由于 PowerDNS 依赖了一大堆新版的库文件,其中包括系统运行必须的库文件,如果用类似 apt-get install -t unstable pdns-server 的方法安装会把一些系统核心文件也升级到 Unstable 版本。在这种情况下,最好的解决方案就是 Docker。由于我们只需要从 Debian 软件源下载 PowerDNS,不需要自己编译,所以几行就可以搞定这个镜像:...
插图

学校网络中自建 VLAN,低价实现高速私有内网

和全国大多数高校一样,我所在的大学以 “一人一账号” 的方式提供网络。通过有线网络或者 Wi-Fi 联网时,所有请求会被暂时重定向到一个登录界面(即 Captive Portal),输入用户名密码后才可以访问互联网。这个做法也是大多数公共场所(例如机场,咖啡厅)的标配,对于电脑、手机等设备也还算友好。但是一些不带显示屏的设备(例如树莓派,ESP8266 等)就难以访问网络了。对于树莓派、ESP8266 等可以运行自定义代码的系统,可以模拟提交表单来登录网络,但是一旦模拟提交表单的程序出现问题,你就得手动将设备取下来,连上自己的电脑上传新的登录程序,这一过程非常的麻烦。至于其余只能运行预定程序的智能设备就完全无法联网了。由于我并没有智能台灯等设备,本文暂时只考虑可以运行 Windows、macOS、Linux 三大操作系统之一的智能设备,包括电脑及单板计算机(Single Board Computer)。另外还有几个小问题:我的寝室里只有一个网络端口供我使用,我需要将它分给我的各台设备。我的大学一个账号可以登录多台设备,且带宽是每台设备独立计算的。假设我的账号限速是 10 Mbps,那么如果我接三台设备,每台设备都可以获得 10 Mbps 的带宽。我最终购买了一只千兆交换机,并通过设置各台设备建立 VLAN,组建了一个内网。这个内网不受学校网络要求登录的限制,设备只要配置好 VLAN,...

与 Hexo 配合使用 Sass 和 Webpack

为何使用 Sass 和 Webpack ¶Sass 是 CSS 的超集,在 CSS 的基础上扩展了大量的语法,支持规则嵌套、变量定义、include 等功能,也可以进行数学运算。主要功能可以在官方入门教程中查看。Sass 原先的文件格式扩展名是 sass,其结构类似 yaml,似乎不与传统 CSS 兼容;而目前 Sass 的文件格式是 scss,兼容 CSS 文件。我使用 Sass 的目的,一是更加清晰的 CSS 规则管理。例如,我有一些 CSS 规则希望只对网站顶栏生效,我就可以将它们全部放到一个代码块中方便管理:header { h1 { ... }}二是减少网页加载时的 CSS 代码量。虽然我的网站使用了 Bootstrap,但是我只使用了一小部分功能,即 Bootstrap 的栅格系统,导航栏和下拉菜单,其它大部分功能都没有使用,这部分 CSS 就不必加载。同时,我还通过 CSS !important 覆盖的方式对一些 Bootstrap 的颜色、形状进行了自定义,这也引入了额外的代码量。我在我的 scss 文件中定义了全局的控件颜色、字体大小等,同时自己 include Bootstrap 的 scss 文件,注释掉我不需要的功能,最后产生的 CSS 文件大小也会大幅下降。另外 Sass 产生的 CSS 是合并成一个缩减过大小(Minify)的,...

开始使用 Hexo 静态网站生成器

什么是静态网站生成器 ¶我们常用的 WordPress、Typecho 等 CMS(内容管理系统)都是动态网站。当用户访问网页时,服务端运行使用 PHP、Python、Node.js 等语言的程序,根据用户的请求实时产生网页,将其返回给用户。而 Jekyll、Hexo、Hugo 等静态网站生成器采取的是另一种方法:提前预测用户的请求,一次性产生对应的 HTML 文件。这两种方式的主要优缺点如下:谁更占优动态网站静态网站动可以实现复杂的交互,根据用户的输入随时改变内容只能响应预定的输入,灵活性差动大多数 CMS 都会提供易用的管理后台,方便用户随时更新内容没有在线后台,需要在本地安装额外软件更新网站内容静安装脚本运行环境需要较复杂的配置服务端无需脚本运行环境,几乎无需服务端任何配置静实时产生网页需要较大的运算量(包括脚本运行、数据库查询),对服务器造成较大的压力服务端几乎无需计算,响应速度极快静如果需要迁移服务器,需要同时迁移脚本、数据库,还常常需要修改脚本配置迁移难度极低,只需要直接复制 HTML 文件即可我为什么从 Typecho 转向静态网站 ¶ 随着我向 VPS 上安装更多的程序,服务器资源已经捉襟见肘,导致 Typecho(尤其是 MySQL 数据库)响应变慢在我没有修改任何配置的情况下,LT-Latency HTTP 头反馈的数值从 0.02 再次提升到了 0.1,...
插图

(自建 NTP)在 Tinker Board 上使用 PPS

在前一篇文章中,我使用 Tinker Board 和 ATGM336H GPS / 北斗模块自建了 NTP 服务器,以 GPS 作为时间基准。GPS 模块除了提供传统的串口输出 NMEA 语句之外,还额外提供了一个 PPS 信号,这个信号会每秒变化一次。原本 gpsd 需要不断解析 GPS 模块传来的 NMEA 语句,需要耗费不短的时间,并且容易被其它程序抢占运行时间,产生 delay(延迟)和 jitter(波动)。而 PPS 信号可以直接触发 CPU 的中断,运行一个简单的处理程序,让操作系统以高优先级处理,不会被其它程序影响。一般而言,在 Linux 中,PPS 由内核直接提供驱动支持。但是在前文中,由于 Tinker Board 的 Armbian Linux 内核没有提供 PPS 支持,所以我们没法直接开启。解决方法 1:重新编译内核 ¶如果内核没有对应支持,那就重新编译内核,加上功能就好。Tinker Board 论坛上的这篇帖子中提供了一个内核补丁,为内核加上了 PPS 支持。打上补丁、编译内核后,将 PPS 信号连到第 22 针,就可以使用了。但是由于 Armbian 重新编译内核的过程比较复杂(需要指定的操作系统(Ubuntu 18.04),交叉编译环境等等),而且似乎不能打成 deb 包(容易被后续系统更新覆盖),所以我不打算这么做。我选择了另一种方法:...
插图

自建基于 GPS 的 NTP 服务端

NTP 是什么 ¶NTP(Network Time Protocol)是目前使用最广泛的互联网时间同步协议。我们常用的 Windows、macOS、Linux 等都自带了 NTP 客户端,可以连接远程服务器获取当前的时间。例如,Windows 的 Internet 时间同步功能就是基于 NTP:(图片来自网络)Windows 默认会连接到 time.windows.com 这台由微软维护的 NTP 服务器同步时间。但是,默认的这台服务器在国内并不好用。这台服务器位于美国,到国内的延迟很大并且容易波动,因此 NTP 客户端也很难得出准确的时间。那么中国大陆有没有 NTP 服务器呢?有,但是不多:cn.pool.ntp.org 由 www.pool.ntp.org 维护的 NTP 服务器池项目,所有服务器由志愿者提供,在各个地区通过 DNS 负载均衡到不同的服务器上。现在(2019 年 9 月 16 日)共有 63 台服务器位于 CN 池内(但不是所有的服务器都在国内)可以通过 0.cn.pool.ntp.org,1.cn.pool.ntp.org 等方式获得更多的服务器 cn.ntp.org.cnV2EX 网友 qiuai 维护的 NTP 服务器池,似乎部分服务器是自行维护的,部分是志愿者提供目前网站 www.ntp.org.cn 正在备案,但 NTP 仍然可用 ntp.ntsc....