DNS support edns-client-subnet
看了2天RFC,終于讓DNS支持edns-client-subnet協(xié)議,通過google dns resolver的請求,可以獲取用戶的ip地址。
國內(nèi)很多CDN和DNS提供商都已經(jīng)實現(xiàn)了,但網(wǎng)上的中文資料比較少,所以在這里分享一下,能力有限,錯誤之處還請諒解。
問題
- CDN使用DNS獲取查詢IP,根據(jù)IP對用戶進行地域調(diào)度。但這里獲取的IP地址是DNS地址,而不是用戶真實的IP地址。
- 大多數(shù)情況下,我們假設(shè)用戶通過會使用離自己網(wǎng)絡(luò)最近的DNS resolver,CDN調(diào)度基本還是準確的。
- 但也有很多nameserver設(shè)置錯誤,或者用戶使用google public dns(nameserver 8.8.8.8/8.8.4.4)或opendns進行DNS resolver
比如:
edns-client-subnet
- google提交了一份DNS擴展協(xié)議,允許DNS resolver傳遞用戶的ip地址給authoritative DNS server.
- CDN的DNS支持該協(xié)議,就可以獲取用戶真實的IP地址,進行準確的調(diào)度。
- OpenDNS和Google Public DNS已經(jīng)支持了該協(xié)議,如果希望他們的query中帶有用戶IP,需要聯(lián)系他們添加白名單。提供nameserver的hostname、ip以及可以用來測試解析的域名即可,一般幾天就可以搞定。(注:我是晚上22:l00提交的申請,第二天10:00就已經(jīng)生效了)
實現(xiàn)
一. 支持發(fā)送和接收edns-client-subnet的dig
下載上述2個包,將patch打進bind,編譯出dig進行測試:
?
?
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ./dig www.baidu.com @8.8.8.8 +client=104.119.200.200 ? ; <<>> DiG 9.7.3 <<>> www.baidu.com @8.8.8.8 +client=104.119.200.200 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1068 ;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1 ? ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 512 ; CLIENT-SUBNET: 104.119.200.200/32/0 ;; QUESTION SECTION: ;www.baidu.com.???????? IN??A ? ;; ANSWER SECTION: www.baidu.com.??????1030????IN??CNAME?? www.a.shifen.com. www.a.shifen.com.?? 130 IN??A?? 220.181.112.143 www.a.shifen.com.?? 130 IN??A?? 220.181.111.148 ? ;; Query time: 42 msec ;; SERVER: 8.8.8.8#53(8.8.8.8) ;; WHEN: Wed Jun 26 14:38:13 2013 ;; MSG SIZE??rcvd: 113 |
?
注意上面的OPT PSEUDOSECTION,已經(jīng)可以發(fā)送和接收edns-client-subnet請求了
二. 協(xié)議
- DNS協(xié)議
- DNS query會包含header和RR 2部分,這里只介紹我們關(guān)注地方,網(wǎng)上可以搜到很多協(xié)議的介紹,比如這個http://archercai.blog.sohu.com/60779796.html
- header會描述本次請求中Questions、Answer RRs、Authority RRs和Additional RRs的數(shù)量,RR部分會詳細描述每個資源的內(nèi)容,所有的RR格式是相同的,如下:
?
?
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | ????????????????????????????????????1??1??1??1??1??1 ??????0??1??2??3??4??5??6??7??8??9??0??1??2??3??4??5 ????+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ ????|?????????????????????????????????????????????? | ????/?????????????????????????????????????????????? / ????/??????????????????????NAME???????????????????? / ????|?????????????????????????????????????????????? | ????+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ ????|??????????????????????TYPE???????????????????? | ????+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ ????|???????????????????? CLASS???????????????????? | ????+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ ????|??????????????????????TTL??????????????????????| ????|?????????????????????????????????????????????? | ????+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ ????|?????????????????? RDLENGTH????????????????????| ????+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--| ????/???????????????????? RDATA???????????????????? / ????/?????????????????????????????????????????????? / ????+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
?
- 個人理解edns-client-subnet是對edns協(xié)議的擴展,附加在一個DNS請求的Additional RRs區(qū)域,這里重點描述edns-client-subnet的結(jié)構(gòu)
- EDNS協(xié)議 Extension mechanisms for DNS (EDNS0):http://tools.ietf.org/html/draft-ietf-dnsind-edns0-01
- EDNS0每個字段的結(jié)構(gòu)和描述如下:
?
?
| 1 2 3 4 5 6 7 8 | ?? Field Name?? Field Type???? Description ?? ------------------------------------------------------ ?? NAME???????? domain name????empty (root domain) ?? TYPE???????? u_int16_t??????OPT ?? CLASS????????u_int16_t??????sender's UDP payload size ?? TTL??????????u_int32_t??????extended RCODE and flags ?? RDLEN????????u_int16_t??????describes RDATA ?? RDATA????????octet stream?? {attribute,value} pairs |
?
- OPT 的值41,詳細的協(xié)議值如下:
?
?
| 1 2 3 4 5 6 7 8 9 | (A, NS, MD, MF, CNAME, SOA, MB, MG, MR, NULL, WKS, PTR, HINFO, MINFO, MX, TXT, RP, AFSDB) = range(1, 19) AAAA = 28 SRV = 33 NAPTR = 35 A6 = 38 DNAME = 39 SPF = 99 OPT = 41 |
?
- RDLENGTH描述RDATAD的長度,edns-client-subnet的詳細格式存在RDATA中,如下:
?
?
| 1 2 3 4 5 6 7 8 9 10 11 12 | ????????????????+0 (MSB)????????????????????????????+1 (LSB) ???? +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ ?? 0: |??????????????????????????OPTION-CODE??????????????????????????| ??????+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ ?? 2: |???????????????????????? OPTION-LENGTH???????????????????????? | ??????+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ ?? 4: |????????????????????????????FAMILY???????????????????????????? | ??????+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ ?? 6: |??????????SOURCE NETMASK?????? |????????SCOPE NETMASK??????????| ??????+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ ?? 7: |?????????????????????????? ADDRESS...??????????????????????????/ ??????+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ |
?
- OPTION-CODE: 2個字節(jié)
- OPTION-LENGTH: 2個字節(jié),描述它之后的內(nèi)容長度(BYTE)
- FAMILY: 2個字節(jié),1表示ipv4, 2表示ipv6
- ADDRESS: 實際存放IP地址的地方,ipv4長度為4,google發(fā)送過來的長度一般為3,隱藏了ip地址最后一位
三. 開發(fā)
完成前2個步驟,就可以開搞了,邏輯很簡單:
1. 判斷dns query是否包含Additional RRs,讀取NAME部分
2. 讀取10個字節(jié)(byte),判斷TYPE是否為41,rdlength > 8
3. 如果rdlength > 8,再讀取8個字節(jié),對應(yīng)OPTION-CODE(2)–>OPTION-LENGTH(2)–>FAMILY(2)–>SOURCE NETMASK(1)–>SCOPE NETMASK(1)
4. 讀取剩下的address,長度 rdlength – 8 或者 option-length – 4都行
注:讀取到的地址長度為4,可以用socket.inet_ntoa變成ip地址,如果不夠4個字節(jié),需要后面補\x00
5. 獲取到的IP地址就可以用來進行判斷調(diào)度了
6. respond時也需要增加一個Additional RRs區(qū)域,直接把請求的Additional內(nèi)容發(fā)過去就可以(如果支持source netmask,將請求中的source netmask復制到scope netmask中,OpenDNS要求必須支持scope netmask)
四. 抓包
- 發(fā)送dns query請求時,可以看到Questions:1, Additional RRs: 1
- Additional RRs中,type: 41(OPT), rdlength: 12 (google發(fā)過來的包,長度為11,沒有IP地址最后一位)
- 12 – OPTION-CODE(2) – OPTION-LENGTH(2) – FAMILY(2) – SOURCE NETMASK(1) – SCOPE NETMASK(1) = 4,IPV4 地址的大小
- 發(fā)送dns query請求時,可以看到Questions:1, Answer RRs:1, Additional RRs: 1
This article was posted in?CDN?and tagged?cdn,?dns,?edns,?edns-client-subnet. Bookmark the?permalink. Follow comments with the?RSS feed for this post.?Post a Comment?or leave a trackback:?Trackback URL.
?
總結(jié)
以上是生活随笔為你收集整理的DNS support edns-client-subnet的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: apr---接口篇
- 下一篇: UPYUN CDN 高可用架构实践