2014/1/27

DNS support edns-client-subnet

2019/1/30日更新
有專家見解:"支援ECS的 recursive DNS resolver 可將DNS請求來源(DNS request client)的IP subnet(網段即可,不一定要精準到IP)附加到DNS query內提交給ADNS (authoritative DNS server),以便ADNS判斷最佳回應"


2018/11月就告訴我,我到今天(1/30日)才看到...
得證:夠偷懶....

 當時因為工作翻牆出來,從CDN的觀念查到這個
到今天新聞:一些google、IBM等等的DNS開始要支援EDNS
我又再度翻了一遍..





解釋:依照你來的IP,轉給目標網站,讓目標網站依照你的ISP等等,轉CDN給你資料
在台灣,這沒啥用處
在大陸,這用處可大了
不過遇到電信、聯通自己不願意公開自己DNS給別人,那也沒啥用處

來源:http://noops.me/?p=653




DNS support edns-client-subnet

作者: |   2,020 瀏覽  | 

看了2天RFC,終於讓DNS支持edns-client-subnet協議,通過google dns resolver的請求,可以獲取用戶的ip地址。
國內很多CDN和DNS提供商都已經實現了,但網上的中文資料比較少,所以在這裡分享一下,能力有限,錯誤之處還請諒解。

問題

  • CDN使用DNS獲取查詢IP,根據IP對用戶進行地域調度。但這裡獲取的IP地址是DNS地址,而不是用戶真實的IP地址。
  • 大多數情況下,我們假設用戶通過會使用離自己網絡最近的DNS resolver,CDN調度基本還是準確的。
  • 但也有很多nameserver設置錯誤,或者用戶使用google public dns(nameserver 8.8.8.8/8.8.4.4)或opendns進行DNS resolver
比如:
  1. 國內用戶設置nameserver 8.8.8.8 (dig xxx.com @8.8.8.8)
  2. 我們得到的DNS query IP是74.125.16.208,判斷IP屬於美國,,,加利福尼亞州山景市谷歌公司
  3. 這個時候,我們的DNS會返回離美國加州最近的CDN節點IP給用戶。
  4. 國內用戶錯誤的調度到美國節點…… :(

edns-client-subnet

  • google提交了一份DNS擴展協議,允許DNS resolver傳遞用戶的ip地址給authoritative DNS server.
  • CDN的DNS支持該協議,就可以獲取用戶真實的IP地址,進行準確的調度。
    图片1
  • OpenDNS和Google Public DNS已經支持了該協議,如果希望他們的query中帶有用戶IP,需要聯繫他們添加白名單。提供nameserver的hostname、ip以及可以 用來測試解析的域名即可,一般幾天就可以搞定。(註:我是晚上22:l00提交的申請,第二天10:00就已經生效了)

實現

一. 支持發送和接收edns-client-subnet的dig

  1. 先下載bind,下載地址
  2. 下載edns-client-subnet dig patch,下載地址
    下載上述2個包,將patch打進bind,編譯出dig進行測試:
注意上面的OPT PSEUDOSECTION,已經可以發送和接收edns-client-subnet請求了

二. 協議

  • DNS協議
  • DNS query會包含header和RR 2部分,這裡只介紹我們關注地方,網上可以搜到很多協議的介紹,比如這個http://archercai.blog.sohu.com/60779796.html
  • header會描述本次請求中Questions、Answer RRs、Authority RRs和Additional RRs的數量,RR部分會詳細描述每個資源的內容,所有的RR格式是相同的,如下:
  • 個人理解edns-client-subnet是對edns協議的擴展,附加在一個DNS請求的Additional RRs區域,這裡重點描述edns-client-subnet的結構
    • EDNS協議 Extension mechanisms for DNS (EDNS0):http://tools.ietf.org/html/draft-ietf-dnsind-edns0-01
  • EDNS0每個字段的結構和描述如下:
  • OPT 的值41,詳細的協議值如下:
  • RDLENGTH描述RDATAD的長度,edns-client-subnet的詳細格式存在RDATA中,如下:
  • OPTION-CODE: 2個字節
  • OPTION-LENGTH: 2個字節,描述它之後的內容長度(BYTE)
  • FAMILY: 2個字節,1表示ipv4, 2表示ipv6
  • ADDRESS: 實際存放IP地址的地方,ipv4長度為4,google發送過來的長度一般為3,隱藏了ip地址最後一位

三. 開發

完成前2個步驟,就可以開搞了,邏輯很簡單:
1. 判斷dns query是否包含Additional RRs,讀取NAME部分
2. 讀取10個字節(byte),判斷TYPE是否為41,rdlength > 8
3. 如果rdlength > 8,再讀取8個字節,對應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個字節,需要後面補\x00
5. 獲取到的IP地址就可以用來進行判斷調度了
6. respond時也需要增加一個Additional RRs區域,直接把請求的Additional內容發過去就可以(如果支持source netmask,將請求中的source netmask複製到scope netmask中,OpenDNS要求必須支持scope netmask)

四. 抓包

  1. 發包
    • 發送dns query請求時,可以看到Questions:1, Additional RRs: 1
    • Additional RRs中,type: 41(OPT), rdlength: 12 (google發過來的包,長度為11,沒有IP地址最後一位)
    • 12 – OPTION-CODE(2) – OPTION-LENGTH(2) – FAMILY(2) – SOURCE NETMASK(1) – SCOPE NETMASK(1) = 4,IPV4 地址的大小
      图片2
  2. 回包
    • 發送dns query請求時,可以看到Questions:1, Answer RRs:1, Additional RRs: 1
      图片3

2 則留言:

Weijack 提到...

不好意思,給點建議:
"依照你來的IP,轉給目標網站,讓目標網站依照你的ISP等等,轉CDN給你資料"
這個對ECS(EDNS Client Subnet)的理解應該有點誤會,應該是:
"支援ECS的 recursive DNS resolver 可將DNS請求來源(DNS request client)的IP subnet(網段即可,不一定要精準到IP)附加到DNS query內提交給ADNS (authoritative DNS server),以便ADNS判斷最佳回應"

冒犯之處請見諒,正好在網上查資料,中文資訊較少,感謝您的用心!

阿龍 提到...

感謝專家......提點
當時在廣州工作,因為想要知道CDN的觀念,又被CDN服務的公司洗臉
所以才會在那時候找一下文章,覺得這篇文章挺好的,
就把這一篇文章拿用過來

JPA+complex key+custom Query

  來源: https://www.cnblogs.com/520playboy/p/6512592.html   整個來說,就是有複合主鍵 然後要使用  public interface XxXXxx DAO extends CrudRepository<Tc...