dns解析現狀問題1:暴利的dns劫持
要說為啥會出現httpdns(先不用管意思,後面解釋),那麼,首先要說一下,現在的dns解析,是不是有啥問題?
dns能有啥問題呢,就是輸入一個域名xxx.com,dns伺服器遞迴獲取xxx.com背後的ip,看起來,人畜無害的技術。
但是,如果我就是負責維護某運營商的dns伺服器的技術人員,手裡很缺錢,我可能會想,是不是可以“科技向善”,搞點錢來畫畫?
比如,假設xxx.com網站很火,每天很多人訪問,那我可以這樣,xxx.com進行dns查詢,本來應該返回的ip是1.1.1.1,我呢,我給返回另一個我手裡的伺服器的ip(2.2.2.2),那麼,使用者後續再訪問xxx.com,就是訪問我手裡的2.2.2.2了。我的2.2.2.2伺服器,做個反向代理,把使用者請求轉發到1.1.1.1,再把1.1.1.1的響應轉回給使用者,使用者也不知道它的流量已經被劫持了,全得從我的2.2.2.2上過一道手,看起來還神不知鬼不覺。
我這時候想賺錢的話,完全可以去找廣告商談合作了,誰給錢多,我就:轉發1.1.1.1的響應給使用者時,加點廣告,使用者只要開啟xxx.com,就會被強制彈廣告,我呢,等著廣告商給我送錢即可。
以上就是最簡單的dns劫持的例子,大家看了後也不要覺得好像我可以,首先,你得進到運營商公司,掌握相關伺服器;其次,現在好多流量都是https域名了,https防中間人篡改的功能還是很強的,所以,基本還是說,你劫持歸劫持,你劫持了也不能改我流量,那你也很難加廣告,所以還是可以防這種彈廣告的。
我在百度搜了下dns劫持,發現這個行業還是真的很刑很賺錢,適合各位喜提畢業禮包的程式設計師們再就業(https://xw.qq.com/cmsid/20211203A014PC00)
dns解析現狀問題2:排程不準
前面有篇文章,講gslb的,提到過如下事情:
依賴運營商幫我們做dns解析,不一定很靠譜,比如我們把xxx.com要解析到我們在深圳和北京的兩個機房,一般來說,是期望可以根據使用者所在的地區來返回就近的地址,如廣東使用者就返回xxx.com在深圳機房的地址,北京使用者就給北京機房的地址。或者是dns運營商那邊,也支援按使用者的運營商路線來解析,
但是呢,總歸來說,這個解析是掌握在別人手裡,他要是靠譜,那就沒問題;他那邊要是解析不靠譜,那就問題較大,比如廣東使用者給你個北京機房地址,你說使用者是不是得卡死在你的網站上,體驗就完全不行。
httpdns的定義
定義
dns劫持,發生在dns解析過程中,一般來說走的是udp協議;dns解析,無非就是要拿到xxx.com背後的ip,那我是不是可以自己開發一個服務,對外提供http介面,介面的功能就是:接收一個引數,即待查詢的域名,如xxx.com;返回呢,就是xxx.com對應的ip或者ip列表或者ip列表再加點各個ip的負載情況(如有這個資料)。
api請求引數
按理說我們是要自己去開發這麼一個http服務的,但是,現在的各大雲廠商也做了這個功能,我就直接貼點他們的資料:
比如上面這個雲廠商,對外提供的介面,就是http://203.107.1.33/xx/d,其中,203.107.1.33是一個公網ip,是這個httpdns服務的對外ip,引數呢,主要就是兩個:host和ip,host就是你要查的域名,ip是客戶端的ip(如有,如果自身取不到自己的對外出口ip,服務也會預設取socket中的client ip,即客戶端ip),所以,這個介面就模擬了dns伺服器的dns查詢功能。
這邊也有兩個請求示例:
api響應引數
在該雲廠商的網站上,也介紹了響應體的格式:
{
"host":"www.xxx.com",
"ips":[
"140.205.140.234"
],
"ipsv6":[
"2400:3200:1300:0:0:0:0:3e"
],
"ttl":57,
"origin_ttl":120
}
可以看到,ips也是支援返回多個的。假設是我們自己實現這個api呢,也和上面這個api差不多,ips這邊,可能可以多點想法,比如把每個ip的當前狀態也返回給客戶端,客戶端就可以按照一些策略來,比如選一個負載最低的;
我看雲廠商這邊呢,都是隻返回ip,畢竟它不可能知道我們每個ip的更多資訊;雲廠商的做法,大概就是:
- 根據你的引數中的要查的域名,xxx.com,去dns系統查詢背後的真實ip地址,如查到1.1.1.1(深圳)、2.2.2.2(北京)
- 根據客戶端的ip(請求引數中的ip,如沒傳就從socket裡取對端ip)來判斷該返回xxx.com在北京的ip,還是深圳的ip;另外,我看到雲廠商也支援你自己寫一段程式碼,讓你自定義策略。
答疑解惑
重大缺陷
只適合有客戶端的場景,可以看到,這個方案是需要先去查詢httpdns服務,才能拿到真實的ip;這就需要在客戶端(安卓、ios、pc端均可)編碼實現。
B/S這種場景是沒辦法了,瀏覽器不支援先去httpdns查真實ip,再發起訪問。
為啥httpdns服務對外直接暴露ip
因為httpdns就是要解決dns劫持問題,總不能自己再套一層dns吧;另外,這個ip是有要求的,需要全國各地的使用者訪問這個ip都要足夠快,所以,這個ip所在伺服器一般是要放在BGP機房,BGP機房簡單理解就是各大主流運營商,如移動、電信、鐵通、網通等等,都和這個機房直連,因此,各大運營商的使用者訪問這個機房的伺服器都很快。
具體我也不是很懂,可以這麼理解,市面上很多IDC公司提供資料中心租用、伺服器託管等服務,它手裡的機房呢,也是有差異的,有的可能主要接了電信運營商,適合南方使用者訪問,北方使用者訪問就很慢;有的就是適合北方使用者訪問;還有一些呢,就是同時接入了很多家運營商,各大運營商訪問這個機房都比較快,即所謂BGP機房。
httpdns服務如何保證高可用
httpdns服務,像前面我們看的那個雲廠商,只有一個ip?其實不是的,是在該雲廠商的很多機房有部署,有多個ip的。
考慮到服務IP防攻擊之類的安全風險,為保障服務可用性,HTTPDNS同時提供多個服務IP,當某個服務 IP在異常情況下不可用時,可以使用其它服務IP進行重試。上述文件中使用的
203.107.1.33
是其中一個服務IP。HTTPDNS提供Android SDK和iOS SDK,兩個平臺的SDK中已經做了多IP輪轉和出錯重試的策略,通常情況下,建議開發者直接整合SDK即可,不需要自己手動呼叫HTTP API介面。
httpdns使用http協議明文傳輸,不安全?
那就使用https,雲廠商也是支援這麼玩的,
HTTPS服務URL:
https://203.107.1.33/{account_id}/d
客戶端最佳實踐
客戶端最好不要依賴這個機制,萬一httpdns服務出問題了呢,那我們的app不就完全不能用了嗎,此時可以降級為使用傳統的dns方案,劫持就劫持吧,其實概率也沒那麼大(畢竟太刑了);要是傳統的dns方案還是有問題,客戶端還可以預埋一些ip,到時候就從預埋的ip裡選一個去訪問,保證高可用。
雲廠商提供了sdk的方案,也詳細講解了一些細節問題,比如,通過httpdns拿到了某個ip,為1.1.1.1,此時,就向1.1.1.1發起了https業務請求(假設我們的後端伺服器都是使用https),此時就會遇到個問題:https一般是隻支援域名訪問(因為https伺服器會返回證書給客戶的,證書都是頒發給某個域名的,沒聽說頒發給某個ip的),此時用ip去訪問https伺服器,就會有一點問題。
雲廠商畢竟是要賺錢的,這些問題的解決方案,在他們文件裡倒是都有寫。
我感覺我都成了推銷的了,其實我就是講下這個httpdns而已,廣告費都沒有,對吧。