前陣子發現一直想注冊但被別人注冊了的一個域名快要過期了,就想著寫個腳本跑在電腦上,每分鐘檢查一次域名狀態,一旦域名被正式刪除,就發封郵件通知我,這樣就不用頻繁手動檢查域名狀態了。
寫腳本時發現一個有趣的現象,使用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個字母,不知道有啥稀罕的┑( ̄Д  ̄)┍