玩一玩泛域名解析

玩一玩泛域名解析

先看看作品的最终效果。访问 http://XXX.我喜欢你.top:521/ 会返回字符串 一直都很喜欢 XXX 呢。
其中 “XXX” 可以改为任意字符(中文也可以)。

实现原理其实很简单。首先是泛域名解析。泛域名解析就是把某一级子域名全部解析到同一IP(A记录)。
比如将 *.test.uint128.com 解析到 127.0.0.1。
这样访问 任意字符.test.uint128.com 都会指向 127.0.0.1。

那么, 服务器怎么知道用户是从哪个域名访问过来的呢?
这里利用了 HTTP 协议头部的 Host 字段。
Host 字段记录了域名, 使得服务器可以分辨用户访问服务器时使用的域名。
这个字段就是用来实现一台服务器部署多个网站的效果。
比如把 baidu.com 和 jd.com 都部署到 1.1.1.1 这台服务器上。
为了区分两个网站, 浏览器在发出请求时, 要在 Host 字段上记录域名。
服务器在分析 HTTP 协议头部的时候, 就能正确地把请求转发给不同网站的程序。
所以只要分析 HTTP 请求的头部, 读取 Host 字段的值, 就能知道请求是通过哪个域名发来的了。

最后一个技术点, 就是让 URL 支持中文。请求参数部分如果要支持中文, 一般使用 百分号编码 (Percent-encoding, 有时候也叫 URL 编码)。这种编码就是把 GBK 编码或者 UTF-8 编码的字符串, 用 16 进制表示, 再加上百分号。比如 %C4%E3%BA%C3%CA%C0%BD。

但是域名部分要支持中文, 可就不能用百分号编码了, DNS 服务器不认识。域名部分要支持非 ASCII 字符, 一般用 Punycode (国际化域名编码)。
它长得像这样 xn--rhq34a65tw32a, 一般以 “xn—“ 开头, 中间是ASCII 字符。

虽然上面说了很多, 但是实现这个小作品非常简单: 买个域名、泛域名解析、写个程序。
这个程序的工作也很简单: 读取 HTTP 请求头部的 Host 字段, 返回相应的欢迎文本。
我这个程序用 C# 来实现, 代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[HttpGet]
public IActionResult Home()
{
// idnMapping 用于将 Punycode 转化为 Unicode 字符串
IdnMapping idn = new IdnMapping();
// 读取 HTTP请求头部的 Host 字段
string rawHost = Request.Headers["host"];
// 将 Punycode 转化为 Unicode 字符串
string host = idn.GetUnicode(rawHost);
// 使用正则表达式匹配域名中的姓名
Regex regex = new Regex(@"([^.]+)(.*?)");
Match match = regex.Match(host);
string info_name = match.Groups[1].Value;
// 返回对应的欢迎文本
string text = $"一直都很喜欢 {info_name} 呢!";
return Ok(text);
}

枯燥。

作者

uint128.com

发布于

2020-04-06

更新于

2022-08-22

许可协议

评论