This commit is contained in:
Xiaobin.Liu 2022-11-13 22:44:48 +08:00
parent 0c280943cd
commit 4f2cfe638e
2 changed files with 256 additions and 256 deletions

View File

@ -1,256 +0,0 @@
[#]: subject: "Why do domain names sometimes end with a dot?"
[#]: via: "https://jvns.ca/blog/2022/09/12/why-do-domain-names-end-with-a-dot-/"
[#]: author: "Julia Evans https://jvns.ca/"
[#]: collector: "lujun9972"
[#]: translator: "lxbwolf"
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Why do domain names sometimes end with a dot?
======
Hello! When I was writing the zine [How DNS Works][1] earlier this year, someone asked me why do people sometimes put a dot at the end of a domain name? For example, if you look up the IP for `example.com` by running `dig example.com`, youll see this:
```
$ dig example.com
example.com. 5678 IN A 93.184.216.34
```
`dig` has put a `.` to the end of `example.com` now its `example.com.`! Whats up with that?
Also, some DNS tools require domains to have a `"."` at the end: if you try to pass `example.com` to [miekg/dns][2], like this, itll fail:
```
// trying to send this message will return an error
m := new(dns.Msg)
m.SetQuestion("example.com", dns.TypeA)
```
Originally I thought I knew the answer to this (“uh, the dot at the end means the domain is fully qualified?“). And thats true a fully qualified domain name is a domain with a “.” at the end!
But that doesnt explain _why_ dots at the end are useful or important.
### in a DNS request/response, domain names dont have a trailing “.”
I once (incorrectly) thought the answer to “why is there a dot at the end?” might be “In a DNS request/response, domain names have a “.” at the end, so we put it in to match what actually gets sent/received by your computer”. But thats not true at all!
When a computer sends a DNS request or response, the domain names in it dont have a trailing dot. Actually, the domain names dont have _any_ dots.
Instead, theyre encoded as a series of length/string pairs. For example, the domain `example.com` is encoded as these 13 bytes:
```
7example3com0
```
So there are no dots at all. Instead, an ASCII domain name (like “example.com”) gets translated into the format used in a DNS request / response by various DNS software.
So lets talk about one place where domain names are translated into DNS responses: zone files.
### the trailing “.” in zone files
One way that some people manage DNS records for a domain is to create a text file called a “zone file” and then configure some DNS server software (like `nsd` or `bind`) to serve the DNS records specified in that zone file.
Heres an imaginary zone file for `example.com`:
```
orange 300 IN A 1.2.3.4
fruit 300 IN CNAME orange
grape 3000 IN CNAME example.com.
```
In this zone file, anything that doesnt end in a `"."` (like `"orange"`) gets `.example.com` added to it. So `"orange"` is shorthand for `"orange.example.com"`. The DNS server knows from its configuration that this is a zone file for `example.com`, so it knows to automatically append `example.com` at the end of any name that doesnt end with a dot.
I assume the idea here is just to save typing you could imagine writing this zone file by fully typing out all of the domain names:
```
orange.example.com. 300 IN A 1.2.3.4
fruit.example.com. 300 IN CNAME orange.example.com.
grape.example.com. 3000 IN CNAME example.com.
```
But thats a lot of typing.
### you dont need zone files to use DNS
Even though the zone file format is defined in the official DNS RFC ([RFC 1035][3]), you dont have to use zone files at all to use DNS. For example, AWS Route 53 doesnt use zone files to store DNS records! Instead you create records through the web interface or API, and I assume they store records in some kind of database and not a bunch of text files.
Route 53 (like many other DNS tools) does support importing and exporting zone files though and it can be a good way to migrate records from one DNS provider to another.
### the trailing “.” in dig
Now, lets talk about `dig`s output:
```
$ dig example.com
; <<>> DiG 9.18.1-1ubuntu1.1-Ubuntu <<>> +all example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10712
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;example.com. IN A
;; ANSWER SECTION:
example.com. 81239 IN A 93.184.216.34
```
One weird thing about this is that almost every line starts with a `;;`. Whats up with that? Well `;` is the comment character in zone files!
So I think the reason that dig prints out its output in this weird way is so that if you wanted, you could just paste this into a zone file and have it work without any changes.
This also explains why theres a `.` at the end of `example.com.` zone files require a trailing dot at the end of a domain name (because otherwise theyre interpreted as being relative to the zone). So `dig` does too.
I really wish dig had a `+human` flag that printed out all of this information in a more human readable way, but for now Im too lazy to put in the work to actually contribute code to do that (and Im a pretty bad C programmer) so Ill just complain about it on my blog instead :)
### the trailing `"."` in curl
Lets talk about another case where the trailing `"."` shows up: curl!
One of the computers in my house is called “grapefruit”, and its running a webserver. Heres what happens if I run `curl grapefruit`:
```
$ curl grapefruit
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
```
It works! Cool. But what happens if I add a `.` at the end? Suddenly it doesnt work:
```
$ curl grapefruit.
curl: (6) Could not resolve host: grapefruit.
```
Whats going on? To understand, we need to learn about search domains:
### meet search domains
When I run `curl grapefrult`, how does that get translated into a DNS request? You might think that my computer would send a request for the domain `grapefruit`, right? But thats not true.
Lets use `tcpdump` to see what domain is actually being looked up:
```
$ sudo tcpdump -i any port 53
[...] A? grapefruit.lan. (32)
```
Its actually sending a request for `grapefruit.lan`. Whats up with that?
Well, whats going on is that:
1. To look up `grapefruit`, `curl` calls a function called `getaddrinfo`
2. `getaddrinfo` looks in a file on my computer called `/etc/resolv.conf`
3. `/etc/resolv.conf` contains these 2 lines:
```
nameserver 127.0.0.53
search lan
```
4. Because it sees `search lan`, `getaddrinfo` adds a `lan` at the end of `grapefruit` and looks up `grapefruit.lan` instead
### when are search domains used?
Now we know something weird: that when we look up a domain, sometimes an extra thing (like `lan`) will be added to the end. But when does that happen?
1. If we put a `"."` at the **end** of the domain (like `curl grapefruit.`, then search domains arent used
2. If the domain has an `"."` **inside** it (like `example.com` has a dot in it), then by default search domains arent used either. But this can be changed with configuration (see this blog post about [ndots][4] that talks about this more)
So now we know why `curl grapefruit.` has different results than `curl grapefruit` its because one looks up the domain `grapefruit.` and the other one looks up `grapefruit.lan.`
### how does my computer know what search domain to use?
When I connect to my router, it tells me that its search domain is `lan` with DHCP its the same way that my computer gets assigned an IP address.
### so why do people put a dot at the end of domain names?
Now that we know about zone files and search domains, heres why I think people like to put dots at the end of a domain name.
There are two contexts where domain names are modified and get something else added to the end:
* in a zone file for `example.com`, `grapefruit` get translated to `grapefruit.example.com`
* on my local network (with my computer configured to use the search domain `lan`), `grapefruit` gets translated to `grapefruit.lan`
So because domain names can actually be translated to something else in some cases, people like to put a `"."` at the end to communicate “THIS IS THE DOMAIN NAME, NOTHING GETS ADDED AT THE END, THIS IS THE WHOLE THING”. Because otherwise it can get confusing.
The technical term for “THIS IS THE WHOLE THING” is **“fully qualified domain name”** or **“FQDN”**. So `google.com.` is a fully qualified domain name, and `google.com` isnt.
I always have to remind myself for the reasons for this because I rarely use zone files or search domains, so I often feel like “of course I mean `google.com` and not `google.com.something.else`! Why would I mean anything else?? Thats silly!”
But some people do use zone files and search domains (search domains are used in Kubernetes, for example!), so the “.” at the end is useful to make it 100% clear that nothing else should be added.
### when to put a “.” at the end?
Here are a couple of quick notes about when to put a “.” at the end of your domain names:
**Yes: when configuring DNS**
Its never bad to use fully qualified domain names when configuring DNS. You dont always have to: a non-fully-qualified domain name will often work just fine as well, but Ive never met a piece of DNS software that wouldnt accept a fully qualified domain name.
And some DNS software requires it: right now the DNS server I use for `jvns.ca` makes me put a `"."` at the end of domains names (for example in CNAME records) and warns me otherwise itll append `.jvns.ca` to whatever I typed in. I dont agree with this design decision but its not a big deal, I just put a “.” at the end.
**No: in a browser**
Confusingly, it often _doesnt_ work to put a `"."` at the end of a domain name in a browser! For example, if I type `https://twitter.com.` into my browser, it doesnt work! It gives me a 404.
I think whats going on here is that its setting the HTTP Host header to `Host: twitter.com.` and the web server on the other end is expecting `Host: twitter.com`.
Similarly, `https://jvns.ca.` gives me an SSL error for some reason.
### I think relative domain names used to be more common
One last thing: I think that “relative” domain names (like me using `grapefruit` to refer to the other computer in my house, `grapefruit.lan`) used to be more commonly used, because DNS was developed in the context of universities or other big institutions which have big internal networks.
On the internet today, it seems like its more common to use “absolute” domain names (like `example.com`).
--------------------------------------------------------------------------------
via: https://jvns.ca/blog/2022/09/12/why-do-domain-names-end-with-a-dot-/
作者:[Julia Evans][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://jvns.ca/
[b]: https://github.com/lujun9972
[1]: https://wizardzines.com/zines/dns/
[2]: https://github.com/miekg/dns
[3]: https://www.rfc-editor.org/rfc/rfc1035#section-4.1.1
[4]: https://pracucci.com/kubernetes-dns-resolution-ndots-options-and-why-it-may-affect-application-performances.html

View File

@ -0,0 +1,256 @@
[#]: subject: "Why do domain names sometimes end with a dot?"
[#]: via: "https://jvns.ca/blog/2022/09/12/why-do-domain-names-end-with-a-dot-/"
[#]: author: "Julia Evans https://jvns.ca/"
[#]: collector: "lujun9972"
[#]: translator: "lxbwolf"
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
为什么有时候域名的末尾有个点?
======
大家好!今年早些时候,我在写杂志 [DNS 是如何工作的][1] 时,有人问我——为什么人们有时在域名的末尾加一个点?例如,如果你通过运行 `dig example.com` 查询 `example.com` 的 IP你会看到一下内容
```
$ dig example.com
example.com. 5678 IN A 93.184.216.34
```
执行完 `dig` 命令后,`example.com` 有一个 `.`——变成了 `example.com.`!发生了什么?
有些 DNS 工具也要求传给它的域名后加一个 `.`:如果你在使用 [miekg/dns][2] 时传给它 `example.com`,它会报错:
```
// trying to send this message will return an error
m := new(dns.Msg)
m.SetQuestion("example.com", dns.TypeA)
```
最初我以为我知道这个问题的答案("呃,末尾的点意味着域名是完全合格的?")。这是对的——一个完全合格的域名是一个末尾有 `“.”` 的域名!
但是*为什么*末尾的点是有用且重要的呢?
### 在 DNS 的请求/响应中,域名的末尾并没有 “.”
我曾经(错误地)认为 "为什么末尾有一个点?"的答案可能是 "在 DNS 请求/响应中,域名末尾有一个".",所以我们把它放进去,以匹配你的计算机实际发送/接收的内容"。但事实并不是这样!
当计算机发送 DNS 请求/响应时,域名的末尾并没有点。实际上,域名中*没有一个*点。
域名会被编码成一系列的长度/字符串对。例如,域名 `example.com` 被编码为这13个字节。
```
7example3com0
```
编码后的内容一个点也没有。一个 ASCII 域名(如 "example.com")被转成了各种 DNS 软件的 DNS 请求/响应中使用的格式。
今天我们来讨论域名被转成 DNS 响应的一个地方zone 文件。
### zone文件中域名末尾的 “.”
一些人管理域名的 DNS 记录的方法是创建一个被称为 "zone 文件"的文本文件,然后配置一些 DNS 服务器软件(如 `nsd``bind`)来为该 zone 文件中指定的 DNS 记录提供服务。
下面是一个对应 `example.com` 的示例 zone 文件:
```
orange 300 IN A 1.2.3.4
fruit 300 IN CNAME orange
grape 3000 IN CNAME example.com.
```
在这个文件中,任何不以 `"."` 结尾的域名(比如 `"orange"`)后都会自动加上 `.example.com`。所以 `"orange"` 成了 `"orange.example.com"` 的简称。DNS 服务器从它的配置中得知这是一个 `example.com` 的 zone 文件,所以它知道在所有不以点结尾的名字后面自动添加 `example.com`
我想这里的想法只是为了少打几个字符——如果要打出全称zone 文件会是这样:
```
orange.example.com. 300 IN A 1.2.3.4
fruit.example.com. 300 IN CNAME orange.example.com.
grape.example.com. 3000 IN CNAME example.com.
```
确实多了很多字符。
### 你也可以不通过 zone 文件来使用 DNS
尽管官方的 DNS RFC[RFC 1035][3])中定义了 zone 文件格式,但你也可以不通过 zone 文件来使用 DNS。例如AWS Route 53 就不用 zone 文件来存储 DNS 记录!你可以通过 Web 界面或 API 来创建记录,我猜他们是用某种数据库而不是一堆文本文件来存储记录。
不过Route 53像许多其他 DNS 工具一样)确实支持导入和导出 zone 文件,这个功能或许在你更换 DNS 提供商时很有用。
### `dig` 命令输出中末尾的 “.”
现在我们来讨论下 `dig` 命令的输出:
```
$ dig example.com
; <<>> DiG 9.18.1-1ubuntu1.1-Ubuntu <<>> +all example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10712
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;example.com. IN A
;; ANSWER SECTION:
example.com. 81239 IN A 93.184.216.34
```
有一件奇怪的事是,几乎每一行都以 `;;` 开头,这是怎么回事?`;` 是 zone 文件中的注释字符!
我想 `dig` 以这种奇怪的方式输出的原因可能是为了方便你粘贴这些内容到 zone 文件时不用修改就可以直接用。
这也是 `example.com` 末尾有个 `.` 的原因 ——zone 文件要求域名末尾必须有点(否则它们会被解释为是相对于该区域的)。因此 `dig` 也这么处理了。
我真的希望 dig 有一个 `+human` 选项,以更人性化的方式打印出这些信息,但现在我太懒了,懒得花工夫去实际贡献代码来做这件事(而且我并不擅长 C所以我只能在我的博客上抱怨一下 :)
### curl 命令输出中末尾的 “.”
我们来看下另一个末尾有 `.` 的例子curl!
我家里有台计算机名为 “grapefruit”其上运行着 webserver。当我执行 `curl grapefruit` 时,会输出:
```
$ curl grapefruit
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
```
这样运行没问题!但是如果我在域名后加一个 `.` 会怎样呢?它报错了:
```
$ curl grapefruit.
curl: (6) Could not resolve host: grapefruit.
```
发生了什么?为了搞清楚,我们需要先来学习下搜索域:
### 初识搜索域
当我执行 `curl grapefrult` 时,它是怎么被转成一个 DNS 请求的?你可能会认为我的计算机会向域名 `grapefruit` 发送一个请求,对吗?但事实并不是这样。
让我们用 `tcpdump` 来看看到底是什么域名在被查询。
```
$ sudo tcpdump -i any port 53
[...] A? grapefruit.lan. (32)
```
实际上是向 `grapefruit.lan.` 发送的请求。为什么呢?
解释一下:
1. `curl` 调用函数 `getaddrinfo` 来查询 `grapefruit`
2. `getaddrinfo` 查询了我计算机上的文件 `/etc/resolv.conf`
3. `/etc/resolv.conf` 包含两行内容:
```
nameserver 127.0.0.53
search lan
```
4. 因为有 `search lan` 这行内容,所以 `getaddrinfo``grapefruit` 的末尾添加了一个 `lan`,去查询 `grapefruit.lan`
### 什么时候搜索域被使用?
现在我们知道了一些奇怪的事情:当我们查询一个域名时,有时会有一个额外的东西(如`lan`)被加到最后。但是什么时候会发生这种情况呢?
1. 如果我们在域名**末尾**添加一个 `.`,那么这时不会用到搜索域
2. 如果域名**中间包含**一个 `.`(如 `example那么默认也不会用到搜索域。但是可以通过修改配置来改变处理逻辑在 [ndots][4] 里有更详细的说明)
我们现在知道了 `curl grapefruit.``curl grapefruit` 结果不一样的原因——因为一个查询的是 `grapefruit.`,而另一个查询的是 `grapefruit.lan.`
### 我的计算机怎么知道使用哪个搜索域呢?
当我连接路由时,它会通过 DHCP 告诉我它的搜索域是 `lan`——它也是通过这个方式给我的计算机分配 IP。
### 所以为什么要在域名末尾加一个点呢?
现在我们已经了解了 zone 文件和搜索域,下面是我认为的人们要在域名末尾加点的原因:
有两种情况下,域名会被修改,并在末尾添加其他东西。
* 在 `example.com` 的 zone 文件中,`grapefruit` 会被转为 `grapefruit.example.com`
* 在我的本地网络(我的计算机已经配置了使用搜索域 `lan``grapefruit` 被转为 `grapefruit.lan`
因此,由于域名在某些情况下实际上可能被转成其他名字,人们就在结尾处加一个 `.`,以此来表示 "这是域名,末尾不需要添加任何东西,这就是全部的东西"。因为否则会引起混乱。
“这就是全部内容”的技术术语是**"完全合格域名"**,简称为**"FQDN "**。所以 `google.com.` 是一个完全合格的域名,而 `google.com` 不是。
我总是要提醒自己这样做的原因,因为我很少使用 zone 文件和搜索域,所以我经常觉得——"我当然是指 `google.com` 而不是 `google.com.something.else`! 我为什么要指其他东西?那太傻了!"
但是有些人确实在使用 zone 文件和搜索域(例如 Kubernetes 中使用了搜索域!),所以结尾的 ". " 很有用,可以让人确切的知道,不应该再添加其他东西。
### 什么时候在末尾添加 “.”?
以下是关于何时在域名末尾加 ". " 的几个简单说明:
**需要添加:配置 DNS 时**
在配置 DNS 时,使用完全合格的域名从来都不是坏事。你不一定要这样做:非完全合格的域名通常也能正常工作,但我从来没有遇到过不接受完全合格域名的 DNS 软件。
有些 DNS 软件需要这样做:现在我为 `jvns.ca` 使用的 DNS 服务器让我在域名的末尾加上 `"."`(例如在 CNAME 记录中),并提示如果我不添加,它将在我输入的内容末尾加上 `.jvns.ca`。我不同意这个设计决定,但这不是什么大问题,我只是在最后加一个 "."。
**不需要加:在浏览器中**
令人困惑的是,在浏览器中,在域名结尾处加一个 `.` *不能*正常运行。例如,如果我在浏览器中输入 `https://twitter.com.`,它就会报错。它会返回 404。
我认为这里发生的事情是,它将 HTTP Host header 设置为`Hosttwitter.com.`,而对端的网络服务器则期望 `Hosttwitter.com`
同样地,`https://jvns.ca.` 由于某种原因,返回了一个 SSL 错误。
### 我认为相对域名在过去是比较常见的
最后一件事:我认为"相对"域名(比如我用 `grapefruit` 来指代我家的另一台计算机 `grapefruit.lan`)在过去更常用,因为 DNS 是在大学或其他有大型内部网络的大机构中开发的。
在今天的互联网上,使用"绝对"域名(如 `example.com`)似乎更为普遍。
--------------------------------------------------------------------------------
via: https://jvns.ca/blog/2022/09/12/why-do-domain-names-end-with-a-dot-/
作者:[Julia Evans][a]
选题:[lujun9972][b]
译者:[lxbwolf](https://github.com/lxbwolf)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://jvns.ca/
[b]: https://github.com/lujun9972
[1]: https://wizardzines.com/zines/dns/
[2]: https://github.com/miekg/dns
[3]: https://www.rfc-editor.org/rfc/rfc1035#section-4.1.1
[4]: https://pracucci.com/kubernetes-dns-resolution-ndots-options-and-why-it-may-affect-application-performances.html