前阵子发现一直想注册但被别人注册了的一个域名快要过期了,就想着写个脚本跑在电脑上,每分钟检查一次域名状态,一旦域名被正式删除,就发封邮件通知我,这样就不用频繁手动检查域名状态了。
写脚本时发现一个有趣的现象,使用whois命令查询域名状态时,它给我返回了两组信息,而且这两组信息的域名状态竟然是不一致的,让人非常好奇,所以特意了解了一下whois的机制,记录在这里。
$ whois $DOMAIN | grep "Domain Status"Domain Status: pendingDelete https://icann.org/epp#redemptionPeriod
Domain Status: pendingDelete https://icann.org/epp#ok
在whois返回的两组信息中,第一组来自注册局(Registry,如VeriSign),第二组来自注册商(Registrar,如阿里云),注册商通常拥有比注册局更加详细的域名信息。whois会执行递归查询:首先从注册局查询域名信息,注册局返回的信息中包含注册商的whois服务器,然后再向注册商查询域名信息。调用whois命令时加上--verbose
参数可以观察到这个过程:
$ whois $DOMAIN --verbose | grep -E "Using server|Registrar WHOIS Server"
Using server whois.verisign-grs.com.Registrar WHOIS Server: whois.paycenter.com.cn
Using server whois.paycenter.com.cn.
Registrar WHOIS Server: whois.paycenter.com.cn
那么问题来了:注册商whois服务器是从注册局查询得来的,那注册局whois服务器是从哪里来的呢?答案是硬编码。whois命令源码中包含一个tld_serv_list
文件,里面包含各顶级域名的注册局whois服务器,以下是该文件的节选:
...
.com VERISIGN whois.verisign-grs.com.za.net whois.za.net
.net VERISIGN whois.verisign-grs.com.eu.org whois.eu.org
.za.org whois.za.org
.org whois.pir.org.edu whois.educause.edu
.gov whois.dotgov.gov
.int whois.iana.org
.mil NONE
...
既然whois信息保存在不止一个地方,那么由于数据同步的延迟,有时信息不一致也就不足为奇了,那到底该以哪边为准呢?就域名状态而言,应当以注册局的信息为准,https://lookup.icann.org/en/faq里面提供了各字段的数据源,以下是摘录:
Result Label | Description | Source |
---|---|---|
Domain Information | ||
Name | The name of the domain name which was entered into the lookup tool. | Registry |
Internationalized Domain Name | The non-ASCII character name of the domain name which was entered into the lookup tool, if applicable. | Registry |
Registry Domain ID | Registry-unique identifier for a domain name. | Registry |
Domain Status | The status of a domain name registration. Every domain has at least one status code, but they can also have more than one status code. See EPP Status Codes for more info. | Registry |
Nameservers | Information regarding the domain name’s DNS nameservers. To include nameserver unicode name and IP addresses, where applicable. | Registry |
Dates | ||
Dates | Multiple dates may be displayed in the “Dates” section and can include the date when the domain name registration was created, expires, and updated, as applicable. | Registry/Registrar |
Contact Information | ||
Registrant, Administrative, Technical, and Billing Contact Information | The contact information of the registrant, administrative, technical, and billing contacts will appear in this section, where applicable. | Registrar |
Registrar Information | ||
Name | The name of the registrar sponsoring the domain name’s registration. | Registrar |
IANA ID | The registrar’s IANA ID from the IANA’s Registrar ID registry (https://www.iana.org/assignments/registrar-ids/registrar-ids.xhtml) | Registry |
Abuse contact email | The abuse contact email address of the registrar. | Registrar |
Abuse contact phone | The abuse contact telephone number of the registrar. | Registrar |
… |
我关心的是域名状态这个信息,为了防止从注册商那里获取到过时的数据,可以使用-h
选项指定只从注册局获取数据:
$ whois $DOMAIN -h whois.verisign-grs.com --verbose | grep -E "Using server|Domain Status"
Using server whois.verisign-grs.com.Domain Status: ok https://icann.org/epp#redemptionPeriod
后来又改用js,在js中使用whois模块时也有类似的问题,需要指定server
参数和follow
参数来防止对注册商服务器进行查询:
whois.lookup(domain, { server: "whois.verisign-grs.com", follow: 0 }, (err, data) => {if (err) return reject(err);let statusLines = data.split("\n").filter(line => /Domain Status/i.test(line)).map(line => {const match = line.match(/Domain Status:\s+(\w+)/i);return match ? match[1] : "";}).sort().join("\n");if (statusLines === "") {statusLines = "(empty)";}resolve(statusLines);
});
不过最终的结局是仍然没能注册上这个域名,今天早上醒来,发现域名已经被人注册了,域名状态在半夜两点多发生了变化,从pendingDelete状态直接变更为了ok。这个域名就是我名字的全拼,有9个字母,不知道有啥稀罕的┑( ̄Д  ̄)┍