Featured image of post 阿里云内网 DNS 解析配置

阿里云内网 DNS 解析配置

- 解决阿里云内网 DNS IP 段与 Tailscale 冲突等问题

前言

在阿里云中,大学生通过身份认证后可以免费 直接领取一台 1 个月的 ECS 云服务器,做完任务后自动续费半年(这是 2024 年初的活动,现在的规则可能有变化)。任务简单得很:搭建一个 WordPress 博客。

这台免费服务器的规格是:2 核 4 GB,1 Mbps 带宽,40 GB SSD 系统盘,100% 独享 CPU,不是以前那种拉垮的 突发性能 t5 实例。

这个配置、这个性能,足够用来搭建个人博客、各种小型网站、个人云盘、游戏服务器(Minecraft、幻兽帕鲁、七日杀(7 Days to Die)balabala,太多了)。

阿里云还是很大方的。

但是!!!当我准备在上面跑 derper + tailscale 的时候,发现了致命的问题 = =:

问题描述

开启 Tailscale 后,使用 apt 进行软件更新时,无法连接到阿里云的内网镜像站 mirrors.cloud.aliyuncs.com。

问题排查

经查,Tailscale 给设备分配的 IP 段是固定的 100.64.0.0/10,目前没法直接更改:

分配 100.64.0.0/10 子网中的地址(从 100.64.0.0 到 100.127.255.255)。这称为运营商级 NAT(CGNAT)地址空间,由 RFC 6598(IANA 为共享地址空间保留的 IPv4 前缀)保留。

—— 取自 Tailscale 官方文档

另外,Tailscale 的 MagicDNS 地址 100.100.100.100 也在这个网段里。

戏剧性的重点来了:阿里云默认的内网 DNS 地址也在 100.100.x.x 网段,恰好落在 Tailscale 的地址范围里:

阿里云内网地址与 Tailscale 地址段重叠

这就导致我在使用 Tailscale 的同时,无法使用阿里云的内网解析服务,具体影响如下:

  • 影响使用内网地址访问 OSS 等服务,甚至影响 ECS 之间的内网通信;
  • 影响使用阿里云的内网镜像站 mirrors.cloud.aliyuncs.com,进而影响 apt/dnf 等包管理器进行更新。

本以为修改 Tailscale 的 ACL 配置可以解决问题,但 Tailscale 的 IP 段是不支持修改的,所以只能从内网 DNS 下手。

解决方案

说了这么多,直接贴出阿里云内网的 DNS 服务器 IP 地址吧:

  • 100.100.2.136
  • 100.100.2.137
  • 100.100.2.138

上述 3 个 IP 地址都可以正常解析 mirrors.cloud.aliyuncs.com 以及其他内网服务。

我用的是 Ubuntu 22.04 LTS,直接修改 /etc/resolv.conf 是不行的,因为这个文件由程序自动生成,文件头也写明了手动修改会被覆盖:

默认的 /etc/resolv.conf

现在你有两个选择:

  • 继续保留 systemd-resolved,通过修改 /etc/systemd/resolved.conf 来指定 DNS(稍麻烦);
  • 直接干掉 systemd-resolved,简单粗暴地自己管理 /etc/resolv.conf(推荐)。

方式一:保留 systemd-resolved

编辑 /etc/systemd/resolved.conf,在 [Resolve] 段中加入:

1
2
[Resolve]
DNS=100.100.2.136 100.100.2.138

然后重启服务并确认生效:

1
2
sudo systemctl restart systemd-resolved
resolvectl status

方式二:停用 systemd-resolved(推荐)

1
2
3
sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved
sudo systemctl mask systemd-resolved

在 Ubuntu 上,/etc/resolv.conf 通常是一个指向 /run/systemd/resolve/ 下文件的软链接。停用 systemd-resolved 后,要先删掉这个软链接,再新建一个普通文件,否则改动可能在重启后丢失:

1
2
3
ls -l /etc/resolv.conf     # 如果显示 -> ../run/systemd/resolve/... 就是软链接
sudo rm /etc/resolv.conf
sudo nano /etc/resolv.conf

写入如下内容:

1
2
3
nameserver 100.100.2.136
nameserver 100.100.2.137
nameserver 100.100.2.138

至于如何根治……感觉需要修改 Tailscale 分配 IP 的那一段代码(?),用 Headscale 魔改也许可以,没精力折腾了。能用就行

2024-03-29 20:46:13 更新:好像也不太行,直接看下面的临时解决方法吧 = =。

为什么改了 DNS 还是不行

原因在于:Tailscale 在 Linux 上会往防火墙里加一条规则,丢弃所有源地址在 100.64.0.0/10、却不是从 tailscale0 网卡进来的数据包,用来防止有人伪造 Tailscale 地址。

阿里云内网 DNS 的回包源地址是 100.100.2.136,从 eth0 进来,正好命中这条规则被丢掉了。很多阿里云内网服务的地址同样在 100.100.x.x,所以光换 DNS 解决不了问题:

回包被 Tailscale 的防火墙规则丢弃

可以自己确认一下这条规则(使用 iptables 模式时):

1
sudo iptables -S ts-input

输出里能看到类似 -A ts-input -s 100.64.0.0/10 ! -i tailscale0 -j DROP 的一行。

想绕过它,可以用 sudo tailscale up --netfilter-mode=off 让 Tailscale 不再管理防火墙规则,但这样也失去了上面说的防伪造保护,需要自己维护防火墙,请评估后再用。

临时解决方法

临时的解决方法就是先用 tailscale down 停掉 Tailscale,这期间正常使用内网 DNS 和内网服务,用完之后再用 tailscale up 启动。

1
2
3
sudo tailscale down
sudo apt update && sudo apt upgrade
sudo tailscale up
  • 最终效果:

    效果图

  • 而且对于内网的访问也是正常的:

    内网访问

参考

由 Hugo 强力驱动