Linux 科学上网指南:DNS

最近经常出现 Firefox 可以打开 GitHub 网站,但是命令行 Git 无法拉取/推送代码的情况。甚至开了 VPN 也不行。运行 ping 命令发现 github.com 被解析到了 127.0.0.1,这是 DNS 被劫持了。是谁搞的鬼,相信你一定懂得。

为啥 Firefox 可以打开 GitHub

最新的 Firefox 桌面版默认启用了 DoH(DNS over HTTPS),通过向特定的服务器发送 HTTPS 请求获取域名的 IP 地址。这就绕过了电信/联通/移动等提供的有毒 DNS 服务器。因为 DoH 采用 HTTPS 协议,不容易被劫持。另外国内用 Firefox 的很少,这个技术并不普及,所以暂时没有被老大哥盯上。

但是很可惜,DoH 目前无法在 Linux 系统层面支持,运行命令行仍然是使用 ISP 提供的 DNS 服务器。电信/联通/移动经常抽风,甚至某些路由器都会给你下毒,让你打不开网页或者直接跳到某网址导航。

为啥开了 VPN 也不行

因为通常是先连接本地网络,这时候已经从 ISP 获取了一个 DNS 服务器。再连接 VPN,(以 OpenVPN 为例)仍然是用的这个 DNS 服务器。

某些商业 VPN 客户端是会在连接上 VPN 之后自动更换 DNS 服务器的。但是 Linux 自带的网络管理是没这个能力的。

因此,如果你只用 Linux 自带的网络管理,最好的解决方法依然是手动设置一个可靠的 DNS 服务器。

DNS 服务器哪家强

如果你去网上搜,很多老的文章会推荐这两个:

  1. Google 的 8.8.8.8
  2. Cloudflare 的 1.1.1.1

这两个 DNS 还是能用的,但是在有些地方不太稳定,甚至直接连不上。

目前还是推荐国内正规企业提供的 DNS 服务器:

  1. DNSPod/腾讯云 119.29.29.29
  2. 阿里云 223.5.5.5

并不能保证腾讯和阿里的 DNS 百分之百可靠,但是比电信/联通/移动好太多。起码 GitHub 是可以正常解析的。

如何设置 DNS

这里就只介绍普通桌面用户用 NetworkManager 和 KDE 的用法。GNOME 基本类似。用 Wicked 的都是技术大佬,相信也不用看下面这些了。

  1. 从系统托盘网络图标右击,打开“网络设置”。
  2. 选择你的有线或者 WiFi 链接,进行编辑。
  3. 切换到 IPv4 标签页。
  4. 将“方法”从“自动”改成“自动(仅网络地址)”。
  5. 将“DNS服务器”改成“119.29.29.29”。
  6. 点“应用”并关闭“网络设置”窗口。
  7. 点击系统托盘的网络图标,打开网络列表,断开并重新链接。

注意,如果需要频繁更换不同的 WiFi 链接,则需要对不同的 WiFi 配置添加自己的 DNS 服务器。

如果是自己家的网络,可以在路由器上配置,方法和上面类似,都是配置 IPv4 方法和 DNS 服务器。(注意,路由器的 WAN 互联网和 LAN 局域网设置都要配一下)这样家里的设备就不用单独配置了。

清空 DNS 缓存

因为 DNS 记录是有本地缓存的,即使你更换了 DNS 服务器,依然会优先从缓存里取 IP 地址。所以更换 DNS 之后,需要清空 DNS 缓存。

这是一个比较头疼的问题,因为各家 Linux 发行版用来管理 DNS 的方式不一样,清空 DNS 缓存的方法也不一样。

最通用的方法:重启系统。

如果不想重启系统,那么可以参考这篇文章 https://www.techrepublic.com/article/how-to-flush-the-dns-cache-on-linux/

我大概总结一下,就是逐个试下面的命令:

sudo systemd-resolve --flush-caches
sudo systemctl restart nscd
sudo systemctl restart named

如果没有用的话,还是重启系统吧。

测试 DNS 解析

首先用 nslookup 测试一下 DNS 服务器是否能解析,如果解析出来的 Server 是你之前配的地址,Address 不是 127.0.0.1 或者 0.0.0.0 这种,应该就是好的。

$ nslookup github.com
Server:         119.29.29.29
Address:        119.29.29.29#53

Non-authoritative answer:
Name:   github.com
Address: 20.205.243.166

但是 nslookup 能解析,并不意味着就能连上。实际连接还要看 ping 命令。注意 github.com 并不回应 ping 请求,也就是数据包都会 lost,这是正常的。只要 ping 能解析到 IP 地址就行了。

$ ping github.com
PING github.com (20.205.243.166) 56(84) 字节的数据。
^C
--- github.com ping 统计 ---
已发送 3 个包, 已接收 0 个包, 100% packet loss, time 2049ms

如果 ping 没问题,最后再试一下 git pull 命令。如果不能访问,则需要试试 VPN 了。

GKD 350H 掌机的游戏移植

开源掌机可以理解为是带手柄按键和屏幕的嵌入式开发板,软件开发的方法都是一样的。移植游戏时,我们不止要保证能够编译通过,运行通过,还要让游戏适配掌机的分辨率,以及映射掌机的按键。

我玩过的第一台开源掌机是借的同学的 Gameshell,首发售价 1200 RMB。它很强大,用的是全志的 ARM 芯片,运行完整的 Debian 系统。因此可以直接 SSH 进去,安装需要的开发工具,直接编译和修改游戏即可,非常方便。

第二台开源掌机是我淘的二手 GKD 350H,全新的首发售价 399 RMB。这台掌机性能就弱很多了,用的是君正的 MIPS 芯片,运行特制的精简 Linux 系统。掌机本身的系统无法 SSH,无法安装开发工具链,性能也不支持它从事复杂编译。只能在电脑上用 buildroot 构建好开发工具链,然后交叉编译。

老张的 GKD 350H 和 GKD mini 用的相同的芯片和系统,理论上它们的构建工具和移植过的游戏也是通用的。不过我手头没有 GKD mini,不能保证兼容性。

周哥的 RG 350/351/280 系列,我手头没有设备,以后入手了可能会移植一下。

构建 Buildroot

GKD 350H 官方并没有开源系统,但是这块芯片很常见,所以 GitHub 出现了很多为 GKD 350H 或 GKD mini 定制的 buildroot。我用的是这个:

https://github.com/gameblabla/gkdmini_buildroot

首先你的电脑需要安装至少以下工具:

  • git
  • make
  • gcc
  • bc

我的电脑是 openSUSE Linux 系统,只要用包管理器安装即可。不太了解 Windows 和 macOS 要怎么安装。

然后,我们下载并构建 buildroot (国内同学建议全程开启 VPN,耗时较长,可以晚上睡觉前开始构建):

git clone git@github.com:gameblabla/gkdmini_buildroot.git
cd gkdmini_buildroot
make gkdmini_defconfig
make

构建完成之后,我们打开 output/host 这个目录,它就很像 GNU/Linux 发行版的目录结构。在 output/host/bin 目录下面,我们能够找到交叉编译所需要的工具链,比如 mipsel-linux-gcc。buildroot 推荐的使用方法是把 output/host/bin 添加到 $PATH 环境变量中:

# ~/.profile
export PATH=~/git/gkdmini_buildroot/output/host/bin:$PATH

在我们编译游戏的时候,要把工具链配置成 buildroot 提供的工具链路径。

移植 2048

2048 是当年在程序员之间很流行的小游戏。最初版本是网页游戏(JavaScript),Libretro 项目有一个 C 版本。它足够简单,依赖的库也少,所以我把它作为第一个练手项目。

make HOST=mipsel-linux CC=mipsel-linux-gcc CXX=mipsel-linux-g++ platform=linux

移植 Craft

Craft 是一个简化的 Minecraft 类沙盒游戏。我

Btrfs 断电损坏

强制关机是危险的,至少对于 Btrfs 文件系统来说。

即使如今 Linux 桌面的稳定性已经极大改善,使用滚动发行版或特殊显卡驱动的用户仍然可能会遇到系统卡死的情况。这时候很多人就会直接长按电源键关机。这会导致系统强制断电,而文件系统读写尚未完成(可能是文件系统层面,也可能是存储硬件层面)。

为什么偏偏 Btrfs 会特别敏感呢?

其实 Btrfs 本身并没有特别弱势的地方,但是使用 Btrfs 的发行版,比如 openSUSE,会定期进行 btrfs-balance 和 btrfs-cleaner。这些 Btrfs 维护任务会带来巨大的 CPU 和 IO 负担,让桌面更容易卡死崩溃。假如你正在玩一款特别占用资源的游戏,而这时 btrfs-balance 开始了,系统很可能会被卡死。如果此时强制断电,btrfs-balance 的数据转移就会被中断,从而使文件系统处于异常状态。

再次开机时,则可能会遇到无法挂载分区,无法进入系统,甚至无法启动的情况。通常系统的 /home 分区或子卷读写最频繁,也最容易因为断电而损坏。无法挂载 /home 分区或子卷的表现为:能进入登录界面却无法进入桌面。

这时要怎么做呢?

第一,重启后即使无法进入系统,也请先让机器继续运行。这可以让 SSD 硬件断电保护机制工作,将之前未完成的数据操作恢复,这可能需要几分钟。请尽量等待时间长一些,以确保数据写入已经完全完成。

第二,再次重启。如果第一步有效,那么您应该能够正常进入系统了。您可以多试几次。如果最终仍然不能进入系统,那么您还需要检查和修复 Btrfs 文件系统。

第三,制作救援盘,从救援盘启动。

第四,插入移动硬盘,使用 btrfs restore 将数据恢复出来。这一步是完全安全的,不会更改已有文件系统。接下来的步骤都或多或少有些风险,因此建议您先保留数据。

第五,按照维基上的 Btrfs 修复教程操作。需要注意的是,这些修复方法的风险依次增大。某些情况下,btrfs check --repair /dev/sda1 甚至可能会完全摧毁一个 Btrfs 文件系统。

Code Journey #11

九月亮点:高分屏BUG修复模拟器打包

KDE:

  • Kompare 高分屏渲染支持 [patch]
  • Filelight 高分屏渲染支持 [patch]
  • KSysGuard 系统卫士高分屏渲染支持,传感器折线图尚未支持 [patch]
  • 字体管理器高分屏渲染支持 [patch]
  • 字体管理器的 enablefont 和 disablefont 图标 [patch]
  • KWallet 钱包高分屏渲染支持 [patch]
  • KWin 高分屏渲染支持 [patch]
  • Krita 加载界面高分屏渲染支持 [patch]
  • Kate/KonsolePart 多屏渲染问题 [bug] [patch]
  • Spectale 多屏渲染问题 [bug] [patch]

openSUSE:

  • 更新 python-PyMuPDF 包并修复库链接问题
  • 更新 arcanist 包并提交到 Factory [request]
  • 提交 PCSX2 包到 Factory [request]
  • 更新 retroarch 包使之开箱即用 [request 1] [request 2]
  • 创建 retroarch-assets 包 [request]
  • 创建 retroarch-joypad-autoconfig 包 [request]
  • 创建 libretro-core-info 包 [request]
  • 创建 libretro-database 包 [request]
  • 创建 libretro-mame2000 核心包 [request]
  • 创建 libretro-genesis-plus-gx 核心包 [request]
  • 创建 libretro-flycast 核心包 [request]
  • 创建 libretro-yabause 核心包 [request]

Code Journey #10

KDE:

  • 修复 JuK 每次启动都弹出文件夹设置对话框的 BUG
  • 翻译 TechBase
  • 修复每日一图不更新的 BUG
  • 研究蓝牙耳机自动连接后无法识别的 BUG。确认是 Linux 内核的问题,已经汇报给上游。

openSUSE:

  • 更新维基 FAQ 页面,还在继续
  • Chameleon 主题:新的导航栏的页脚设计,以及暗色模式
  • 更新文档网页主题
  • 更新维基网页主题

Code Journey #8

openSUSE

Wiki

  • 更新 FAQ 页面

Plasma 主题

  • 更新配色方案
  • 改进面板透明度

opi

  • 修复 Leap 15.1 系统版本空格问题

Geeko Store

  • OBS/PMBS 搜索 API 集成
  • 软件包列表

打包

  • 更新 php-composer
  • 创建 npm2rpm
  • 打包 npmjs-gulp-cli
  • 打包 npmjs-create-react-app
  • 打包 npmjs-webpack-cli
  • 更新 patterns-base,移除 dejavu-fonts 推荐,以改进 emoji 支持

KDE

翻译

  • 更新 KDE Connect 翻译
  • 构建同步到 SVN

Code Journey #7

openSUSE

opi

  • 解决了硬编码登录信息的安全问题,使用代理服务器转发请求
  • 支持 Packman 软件包查询
  • 解决了依赖关系缺失的问题

chameleon

  • 添加主题文档页面
  • 支持 hot reload 的开发模式
  • 增加暗色背景下的按钮和表单控件主题
  • 改进主题风格

打包

  • 更新 python-PyMuPDF

其他

Rabbit Lyrics

  • 支持多个歌词块

Code Journey #6

为了避免日志太多,以后将会按周总结。发布日期通常是每周日。

openSUSE

opi

  • 快捷安装 Packman codecs, VS Code, Skype
  • PMBS 搜索功能研究(只要得到账号,就能做了)

打包

  • 更新 adobe-sourcehansans-fontsadobe-sourcehanserif-fonts包,提供语言支持信息with additional provides for languages

KDE

翻译

  • 保持核心翻译 100%
  • 翻译 Kdenlive
  • 同步翻译到 SVN