關於我遇到的一個DNS問題

clipboard.png

最近遇到一個小問題,在某些用戶的請求中會莫名其妙的出現重定向而後致使404,在這裏分享下致使這種問題的緣由。

這裏不會介紹DNS和CDN,若是想了解請google或百度,有好幾斤的數據能夠看,我也不必再說了。這篇文章主要是從關於客戶端DNS解析和CDN服務解析的整個流程角度去解釋我遇到的這個很幼稚的buglinux

DNS服務器能夠部署在不少階段

DNS對於大多數同窗來講均可能知道是幹嗎的,可是深刻了解工做原理可能有些模糊,首先它它分佈在不少個階段,總體分爲兩大塊:本地DNS服務,遠端DNS服務。程序員

本地(Local Resolver)

每臺電腦本地都會配置一個DNS解析文件,在Nginx上咱們能夠在 /etc/resolv.conf 中查看,固然也能夠從界面中查看。數據庫

下面是我在CLI查看個人本地DNS服務配置,即DNS客戶機配置(/etc/resolv.conf)
clipboard.png瀏覽器

下面是我在設置中查看DNS服務配置
clipboard.png緩存

你們會問,這兩個同樣嗎?只不過一個是在文件系統查看一個是在GUI上查看,二者沒區別吧?嗯,是的沒區別。服務器

實際上,修改本地的DNS解析規則,在Nginx上有三個地方,分別是網絡

hosts文件-->網卡配置文件-->DNS服務器地址配置文件

咱們剛纔修改的只是系統的DNS服務器地址配置文件,固然GUI上也是對應的這個文件。前兩個配置方式比較粗暴,在這裏就不講了,有傷大雅。app

分析一下配置文件中的字段(實際上還有不少,先說兩個吧):dom

  1. domain提供一個基本的搜索域,解析失敗的域名會和這個基本的搜索域拼接,再去作DNS解析,看我下面偷的這一句話,就明白它的做用了。例如,若是您指定搜索域爲 apple.com,在您的網頁瀏覽器中鍵入「store」將會前往 store.apple.com。或者,若是使用 campus.university.edu 做爲搜索域,那麼您能夠在「訪達」的「鏈接服務器」對話框中鍵入「server1」來鏈接到 server1.campus.university.edu。
  2. nameserver,也就是本地的DNS服務器列表,它的格式是IP地址,v4 v6 d均可以,遠端或本地地址均可以,甚至這個地址能夠填寫一個本地的服務,而後咱們就能夠自定義處理DNS解析服務了。

nameserver這個字段就太好玩了,一般家庭版的地址是192.168.0.1,也就是大多數路由器的IP地址,而後用戶能夠在本身的路由器設置頁面配置DNS解析服務器的地址。belowsocket

clipboard.png

固然,你也能夠不使用路由器來轉發你的DNS解析,直接填寫這個根DNS服務器地址,也就是圖上面的222.*。

做爲程序員,突發奇想,咱們還能夠玩的更浪一些~~~,就好比:

添加一個本地域名解析服務,也就是添加一個127.0.0.1在你的DNS配置文件中,注意必定要添加在第一行,別忘了nameserver是in order的哦。

clipboard.png

而後在本地開一個UDP服務,監聽53端口(爲何是UDP爲何是53端口,好奇同窗請trace here),你就會看到本地的DNS處理記錄:

let dgram = require('dgram');
let socket = dgram.createSocket('udp4');
// 服務端監聽一個端口 數據到來時 能夠讀出信息
socket.bind(53,'localhost',function(){
    //讀取消息
    socket.on('message',function(data,rinfo){
        console.log(data.toString());
    })
});

下面這些亂七八糟的,就是DNS解析記錄...

clipboard.png

咱們能夠修改上面的代碼來自定義解析後的信息,我不知道這個返回狀態應該怎麼設定,沒事閒的同窗能夠去查查怎麼能夠僞造這個信息,聽起來很刺激... 不過我以爲不太可能,53端口受特殊保護,就連監聽和查看它的佔用狀況都須要提權,上述代碼linux上出EACCES錯的能夠加上sudo,win提權太麻煩不說了。

說了 一大堆沒用的,回正題,如今開始咱們假設本地DNS服務接受了一個軟件的解析請求~~

咱們假設上述的 hosts文件-->網卡配置文件-->DNS服務器地址配置文件,前兩個不作任何處理的狀況下。如下順序處理。

  1. 在DNS解析服務開始以前,系統會找到本地的這個DNS服務器列表,在我這是兩個,10.10. and 10.120. 從第一個開始向這個DNS服務器發送域名解析請求。
  2. 若是第一個處理失敗,或者查詢不到,就用第二個找。也就是 10.120.*。
  3. 若是10.120.*也找不到(最後一個nameserver),那麼使用這個domain來處理了。

本地DNS服務的任務就是接受計算機軟件的DNS解析服務,去向根DNS服務器發送請求,得到最終的IP地址。

若是本地有 DNS resolver 的話,也是能夠緩存你的DNS解析的,什麼是Resover?就是我們剛纔創建在53端口的服務,它就是一個Resolver。

// 驗證是否存在 resolver
sduo lsof -i:53
// or 查看 /etc/resolv.conf

resolver 有可能緩存上一次DNS解析結果。若是碰到惡意的resolver,看誰不順眼就能夠篩選全部某站的主域名(好比競爭對手的...嘿嘿)返回一個不存在的ip地址,而後這個域名在那臺電腦上就over了,除非技術手動撤銷這個resolver,不然卸載重裝,重啓,通通很差使。

因此,友情提醒:儘可能不要使用本地的DNS resolver。

根DNS(Root DNS)

接着從上面的本地DNS服務開始說,它把解析請求發送給 20.20.* 服務器,這個服務器就是根DNS,全部DNS解析請求都通過它來轉發
根DNS服務器免費的沒有幾個,國內的114.114*比較快一點,國外的Google的4個8或者4個1,都是廣泛使用的。那麼又一個問題,世界上這麼多電腦才這麼幾個服務器,並且每臺電腦的DNS解析請求是很是頻繁的,這幾個服務器受得住嗎?

首先,它確實是接受全部的請求的,但它不負責處理這個解析,只負責分類並返回子DNS服務器IP。而後LocalDNS接收到這個子DNS服務器IP後,再去向子DNS迭代查詢。

這個階段,若是你本地有DNS緩存服務的話,它會記住某個域名與它所屬的子DNS的IP地址,下次請求直接去子DNS地址,而不用通過ROOT DNS處理。

頂級 DNS(TLD DNS)

子DNS分不少區,這個分類其實就是根據域名的後綴來的,好比,有 COM DNS 服務器,它只負責 com這個後綴的域名解析。固然還有其餘類型的,好比 .cn .net。固然,不可能每一個後綴都來一臺服務器,流量較少的的後綴應該被分在一個區裏。

子DNS接到LocalDNS請求以後,查詢此域名以後發現它已經交給專屬DNS服務器(也就是你購買域名時設置的域名解析服務器)處理

子DNS的做用就是幫助RootDNS減小不少查庫和處理請求的時間。

自定義DNS服務器

服務器DNS屬於咱們域名下的專屬DNS服務器,咱們可使用本身的DNS服務器配置到你的域名上(申請DNS服務器須要到國內註冊局申請辦理)。

若是是本地內網搭建,就沒那麼多規則,可使用Bind ((Berkeley Internet Name Domain))。

一般,咱們在阿里雲購買的域名綁定上域名解析就能夠了,默認使用的是萬網的DNS服務器,若是你有本身的DNS服務器的話,能夠在域名管理中配置。

最後來張圖通一通。以我司客戶端爲例:

  1. LocalDNS 接收到一個客戶端發送的域名解析請求,看看本地有沒有上次緩存的現成的hetao101域下的DNS服務器。若是沒有,取出第一個nameserver(也就是根DNS服務器),進行迭代查詢。若是有,直接跳到第5步。
  2. 根DNS解析咱們的www.hetao101.com地址屬於 com 區,而後把 com 區的子DNS服務器的IP返回給LocalDNS處理。
  3. LocalDNS收到子DNS的IP,而後再次發送迭代查詢向子DNS
  4. 子DNS查詢數據庫,找到www.hetao101.com這個域名對應的服務器DNS地址,而後把地址返回給LocalDNS
  5. LocalDNS發送請求到www.hetao101.com的DNS 服務器,而後返回給它域名對應的IP地址。
  6. LocalDNS拿到IP後很是雞凍(來回串了這麼多服務器終於拿到了),趕忙握握手親熱親熱,而後開始了創建網絡通道(e.g TCP)。

注意,以上的遞歸查詢和迭代查詢的區別,遞歸查詢的是:我向A請求,A你必須得給我一個結果,不到黃河不死心。而迭代查詢是,我向A請求,A有可能沒有這個東西,它把B返回給你,讓你和B問...

clipboard.png

CDN服務器

網絡就是數個燈泡中間的導線,電線長了,電流抵達的速度也就慢了,燈泡亮的速度就慢了。。。

因此,咱們在導線的中間加上了一個繼電器式的資源服務器。也就是CDN服務器。保證資源快速響應給局部用戶。

CDN服務器一般包括一個源站和子節點(其餘區域的資源服務器),上傳文件到CDN服務器首先到達源站,而後源站分發給子節點。而後當客戶端請求時候經過它們本身的DNS服務器解析請求IP(地理位置因素),而後返回不一樣的子節點地址。

若是源站的資源被替換或者刪除,子節點也會與它同步。

簡單的打了個比方,具體使用場景及原理,能夠自行Goog,很少說了廢話了,下面簡單說下我遇到那個問題。

最近遇到一個小問題,在更新資源文件後,在某些用戶的請求中會莫名其妙的出現 302而後重定向地址是404,在這裏分享下致使這種問題的緣由。

上下文:這個請求是阿里雲OSS的,客戶是河北滄州移動運營商,重定向後的IP地址後面添加相比源路徑多了不少層路徑,位置是河北石家莊的移動網絡。

我一開始的分析是,本地DNS服務或運營商緩存了DNS解析(阿里雲DNS解析後的IP是能夠根據客戶端的區域分配就近節點的,因此應該被分到了石家莊節點),而後當我更新這個文件時,因爲ISP緩存沒有到期(假定是ISP,還有多是本地DNS Resolver),而後更新文件後,繼續請求上次的解析後的地址(地址上是有文件的hash的),致使資源404(hash值被更新)。

仔細想一下是不對的,首先DNS解析只會返回域名區段,不會給你添加路徑。第二若是是阿里雲子節點在上傳文件到源站的時候,就會同步到各個子節點,因此不會出現404的狀況。

那麼,若是這個重定向的IP地址不是阿里雲的,難道是運營商本身的,它把響應文件緩存起來,而後放到本身的緩存服務器,若是請求在緩存期內就從運營商本身的緩存服務器裏取?我估計這個也不可能,由於,條件是每次在阿里雲OSS上更新文件時,纔會出現這個問題,因此,有兩種可能:

  1. 由於資源是和阿里雲源站同步的,因此,可斷定這個地址並非運營商的地址(是阿里雲的)。
  2. DNS劫持,劫持和緩存同樣,區別是前者以攻擊爲目的,給你返回指望以外的IP,後者是給你目標IP。

而當我分析上面說的302返回的重定向地址時,我不太確信這是一個DNS劫持,由於這地址看起來太正經,如:

http://111.**.135.171/files/317200004364C385/***.oss-cn-beijing.aliyuncs.com/***.zip

第一段 IP,後面的的路徑很是有規律,files下面的file hash,而後是源站的下載地址。

這麼正經的IP不多是被劫持吧,那麼再說回去,若是302是運營商的DNS緩存致使的,302後的地址也就是這個地址,它是怎麼來的呢??

我分別測試了山東和杭州的網絡,DNS解析***.oss-cn-beijing.aliyuncs.com這個源下載地址並無返回動態子節點IP,實際上仍是beijing區的源站IP,這說明DNS解析是沒有動態返回節點的。

不是運營商也不是阿里雲,到底是什麼?

愁了我一個星期,在阿里雲棲社區問了此問題,也沒有收到特別準確的回答,由於用戶的問題已經使用其餘方式修復,因此沒有辦法再次肯定問題,目前只能認爲是

  1. DNS劫持
  2. 運營商的DNS緩存,DNS緩存阿里雲的OSS地址解析後的IP,但是並不起做用,由於阿里的OSS使用的是虛擬站點,用DNS後的ip+路徑 和 地址+路徑是不同的, 。

DNS解析後的IP是不能直接替換域名的,DNS是爲了取IP,而IP是在創建鏈接層之根基,可是鏈接層上還有寫一層,一些服務器上的httpserver,好比Apach或者Nginx會提供一個叫作虛擬站點的功能,簡單來講根據你請求的host(域名)來分撥出不一樣的文件路徑,也就是說一臺服務器是能夠享有多個域名的。固然不只是分撥路徑,中間還能夠去向其餘服務請求(有點像proxy,可是根據域名來判斷的proxy分撥),想了解更多請搜索 虛擬站點

如何解決?

一切惡果毋庸置疑終究是運營商釀造的,可是想繞過它卻不現實。

  1. 請求地址換成IP,避免DNS解析緩存。
  2. 若是是資源文件,爲資源文件名加鹽

若是你對於個人問題有其餘見解,請評論。若是你以爲我說的不對,請糾正(有懸賞)。若是你想跳槽,請看個人我的資料右上角。若是你覺還有點幫助,請使勁兒點個贊。若是你以爲這篇文章浪費了你的時間,沒啥乾貨,請私聊噴我一頓。

相關文章
相關標籤/搜索