DNS 劫持是什麼意思?型別、檢測、處理與防範
DNS 劫持是指域名查詢的結果被人為篡改:你存取的是正確的域名,拿到的卻是別人指定的 IP,於是被帶到廣告頁、釣魚頁或攻擊者的伺服器。判斷方法只有一條主線:拿你看到的解析結果和域名權威伺服器的結果對比,不一致就說明某一環被改了,再按篡改位置分別處理。
DNS 劫持是什麼意思?簡單說,就是域名解析的結果被篡改了:你輸入的域名沒錯,DNS 返回的卻不是網站真實的 IP,而是廣告伺服器、釣魚頁面或攻擊者控制的主機。篡改可以發生在解析鏈路的任何一環:你自己的電腦和路由器、運營商的遞迴伺服器、域名的註冊商帳號,或者被投毒的 DNS 快取。處理 DNS 劫持的第一步不是換 DNS,而是確認篡改發生在哪一環,因為影響範圍和修復方法完全不同。
DNS 劫持的四種型別:篡改發生在哪一環
| 型別 | 篡改位置 | 典型表現 | 影響範圍 |
|---|---|---|---|
| 本機或路由器 DNS 被改 | 電腦的 DNS 設定、hosts 檔案,或路由器下發給終端的 DNS 位址 | 很多網站被插廣告、跳轉;換一個網路就正常 | 這台電腦,或這個路由器下的所有終端 |
| 運營商或出口劫持 | 運營商的遞迴伺服器,或出口裝置搶先回答 UDP 53 查詢 | 輸錯的域名跳到導航頁;某些域名在某個運營商網路下解析異常 | 某個地區、某個運營商的使用者 |
| 域名帳號被盜 | 註冊商帳號或 DNS 託管帳號,NS 或解析記錄被改 | 全網訪客都進了假網站,郵件收不到 | 所有訪客,後果最嚴重 |
| 快取投毒 | 遞迴伺服器的快取被注入偽造應答 | 使用某個遞迴伺服器的使用者解析到錯誤位址,一段時間後自行恢復 | 使用這台遞迴伺服器的所有使用者,直到快取過期 |
還有一種發生在機房和辦公網裡的變體:攻擊者先在同一個二層網路裡做 ARP 欺騙,把自己偽裝成閘道器,再偽造 DNS 應答。表現和本機 DNS 被改很像,但電腦上的設定是正常的。
DNS 劫持有什麼後果
- 釣魚和盜號:仿冒的登入頁收集帳號密碼,訪客看到的域名是對的,很難察覺。
- 插廣告、改跳轉:運營商或流量販子把存取導向廣告頁變現,網站自己的流量和收入被截走。
- 郵件被截獲:MX 記錄被改後,發往你域名的郵件全部進了攻擊者的伺服器,包括其他平台發來的“重置密碼”郵件,攻擊者可以藉此接管更多帳號。
- 簽發合法證書:控制瞭解析的人能透過證書頒發機構的域名驗證,拿到你域名的正規 HTTPS 證書,瀏覽器的小鎖照樣顯示。
- 軟體更新和下載被替換:伺服器上用
curl ... | sh安裝指令碼、下載程式卻不校驗簽名和雜湊的,可能執行攻擊者的程式碼。yum、apt 的軟體包有 GPG 簽名,受到的影響小得多。 - 業務中斷與搜尋收錄異常:解析指向不可用的位址時網站直接打不開;搜尋引擎的爬蟲如果抓到被替換的內容,收錄也會受影響。
怎麼檢測 DNS 劫持:拿結果和權威伺服器對比
第一步:對比權威伺服器與各個遞迴伺服器的結果
權威伺服器上的記錄是“正確答案”,直接問它不經過任何快取。再用本機配置的 DNS 和幾個公共 DNS 分別查詢,對比結果:
# 找出域名的權威伺服器
dig +short NS example.com
# 直接問權威伺服器(換成上一步查到的 NS)
dig +short www.example.com @ns1.example-dns.com
# 本機當前使用的 DNS
dig +short www.example.com
# 幾個公共 DNS 逐一查詢
for s in 223.5.5.5 119.29.29.29 114.114.114.114 8.8.8.8 1.1.1.1; do
printf '%-16s %s\n' "$s" "$(dig +short +time=2 +tries=1 www.example.com @"$s" | tr '\n' ' ')"
done
注意,用了 CDN 或智慧解析的域名,不同地區、不同運營商本來就會拿到不同的 IP,結果不一致不等於被劫持。這時看返回的 IP 屬於誰:whois 198.51.100.7 查出的組織是你的 CDN 或機房,就是正常排程;屬於一個完全不相干的機構,才是可疑結果。還要從不同地區的幾台伺服器上各跑一遍,有些劫持只在特定城市或運營商出現。
第二步:測試不存在的域名會不會被改寫
# 隨機生成一個肯定不存在的子域名,正常應返回 status: NXDOMAIN
dig nx-$(date +%s).example.com | grep -E 'status|IN[[:space:]]+A'
如果返回的是 NOERROR 外加一個 IP,說明你用的遞迴伺服器會把“域名不存在”改寫成自己的位址,這是運營商劫持最常見的形式。測試要用一個確定沒有泛解析(*.example.com)的域名,否則結論不成立。
第三步:查註冊資訊,看 NS 有沒有被改
# 註冊商、NS、域名狀態和最近一次修改時間
whois example.com | grep -iE 'registrar:|name server|status|updated date'
# 直接問 TLD(域名字尾)伺服器,看註冊局裡登記的 NS,不受任何遞迴快取影響
dig +norecurse +noall +authority NS example.com @a.gtld-servers.net
.com、.net 的 TLD 伺服器是 a.gtld-servers.net 等,.cn 用 a.dns.cn。NS 不是你在用的 DNS 服務商,或者 Updated Date 是一個你沒有操作過的時間,就要按帳號被盜處理。順便看一眼 Status 裡有沒有 clientTransferProhibited、clientUpdateProhibited 這類鎖定狀態。
第四步:檢查本機和伺服器的設定
# Linux 伺服器
cat /etc/resolv.conf
resolvectl status 2>/dev/null | grep -i 'dns server' # 使用 systemd-resolved 的系統
grep -vE '^\s*(#|$)' /etc/hosts # 一般只有 localhost、本機名和 IPv6 預設條目
lsattr /etc/resolv.conf /etc/hosts # 出現 i 屬性,說明有人鎖定了它們
getent hosts www.example.com # 程式實際拿到的結果,會經過 hosts
# Windows
Get-DnsClientServerAddress -AddressFamily IPv4
Get-Content C:\Windows\System32\drivers\etc\hosts | Where-Object { $_ -notmatch '^\s*(#|$)' }
路由器要登入管理頁面,看 WAN 口和 DHCP 下發的 DNS 是不是你設定的位址。伺服器的 DNS 或 hosts 被不明來源改過並加了鎖定屬性,這不只是 DNS 問題,說明機器很可能已被入侵,要按入侵排查處理。
第五步:查證書透明度日誌
所有公開信任的 HTTPS 證書都會記錄在證書透明度(CT)日誌裡。查一下最近有沒有你不認識的證書:
curl -s "https://crt.sh/?q=example.com&output=json" \
| jq -r '.[] | [.not_before, .issuer_name, .name_value] | @tsv' | sort -r | head -20
出現了不是你申請的證書,說明有人短暫控制過你的解析,或者透過其他方式透過了域名驗證,要連同帳號一起排查。
對照表:根據結果判斷是哪一類
| 檢測結果 | 結論 |
|---|---|
| 權威、公共 DNS 都正確,只有本機或本網路的結果錯誤 | 本機、路由器 DNS 被改,或區域網裡有 ARP 欺騙 |
| 權威正確,某個運營商、某個地區的結果錯誤 | 運營商劫持,或該地區的遞迴伺服器快取被投毒 |
| 不存在的域名返回了 IP | 遞迴伺服器改寫 NXDOMAIN |
| 權威伺服器返回的就是錯誤 IP,或註冊局裡的 NS 變了 | 域名帳號或 DNS 託管帳號被盜 |
| 各處解析都正確,頁面仍被插廣告或跳轉 | 不是 DNS 劫持:可能是 HTTP 內容在傳輸中被篡改(用 HTTPS 解決),也可能是本機的瀏覽器外掛或惡意程式 |
DNS 劫持怎麼處理:按型別分別修復
本機或路由器被改:“DNS 劫持異常”怎麼修復
安全軟體提示“DNS 劫持異常”或“DNS 被篡改”,多數屬於這一類。Windows 上按順序處理:
# 1. 看當前網路卡名稱和 DNS
Get-DnsClientServerAddress -AddressFamily IPv4
# 2. 改成可信的 DNS(網路卡名換成上一步看到的),或恢復為自動獲取
Set-DnsClientServerAddress -InterfaceAlias "乙太網" -ServerAddresses 223.5.5.5,119.29.29.29
# 或者恢復為自動獲取(二選一)
# Set-DnsClientServerAddress -InterfaceAlias "乙太網" -ResetServerAddresses
# 3. 清掉已經快取的錯誤結果
ipconfig /flushdns
# 4. 全盤掃描,找出修改設定的程式
Start-MpScan -ScanType FullScan
hosts 檔案裡刪掉不認識的條目。只改設定不查原因,修改它的程式會再改回去。路由器這一側:修改管理員密碼,關閉從外網存取管理頁面的功能,把 DHCP 下發的 DNS 改回自動或可信位址,升級韌體;韌體太老、廠商已不再更新的,換掉。
Linux 伺服器上的 /etc/resolv.conf 被改成陌生位址,先 chattr -i 去掉鎖定再恢復,同時查 crontab 和 systemd 服務裡有沒有定時改寫它的任務,並把這台機器當作已被入侵來排查。
運營商劫持:留證、投訴、加密
- 儲存證據:在出問題的網路裡執行上面的 dig 對比,把命令、結果、時間、寬頻帳號或出口 IP 一起儲存,網頁被替換的截圖也留著。
- 向運營商客服投訴,要求處理;沒有結果的,可以向工業和資訊化部電信使用者申訴受理中心(12300)申訴。
- 技術上減少暴露:網站全站 HTTPS 並開啟 HSTS,讓中途篡改內容和降級到 HTTP 都行不通;訪客一側改用加密 DNS(DoH 或 DoT),查詢在傳輸途中無法被改寫;App 可以使用雲服務商的 HTTPDNS 服務,繞過運營商的遞迴伺服器。
域名帳號被盜:最緊急,按小時算
- 能登入的,立刻改密碼、開二次驗證,並檢查帳號繫結的郵箱、手機號有沒有被改,有沒有新增的子帳號和 API 金鑰。
- 把 NS 改回原來的 DNS 服務商,在 DNS 託管平台逐條核對 A、CNAME、MX、TXT 記錄,TXT 裡的 SPF 和各類平台的域名驗證記錄也要看。
- 登入不了的,馬上聯絡註冊商走找回流程,準備好實名認證材料,同時說明正在發生劫持,請求先凍結域名的修改。
- 查攻擊期間簽發的證書:按上面的方法查 CT 日誌,找到不屬於你的證書,聯絡對應的證書頒發機構吊銷。
- 處理郵件被截的後果:攻擊期間收到過“重置密碼”郵件的平台,逐個檢查登入記錄並改密碼。
- 評估影響,必要時報案:出現資金損失或使用者資料洩露的,向公安機關網安部門報案,並按規定通知受影響的使用者。
修復之後不會立刻全網恢復。已經快取了錯誤 NS 和記錄的遞迴伺服器,要等快取過期才會重新查詢,TLD 伺服器給出的 NS 記錄快取時間通常是一到兩天(例如 .com 為 172800 秒,即兩天),攻擊者還可能給偽造的記錄設了很長的 TTL。這段時間可以在主流公共 DNS 的快取重新整理頁面提交重新整理請求,縮短一部分使用者的受影響時間。
快取投毒:自建遞迴 DNS 的維運要做的事
# BIND:清除某個名稱或整個快取
rndc flushname www.example.com
rndc flush
# Unbound:清除某個域名下的全部快取
unbound-control flush_zone example.com
清快取只是止血。遞迴伺服器要開啟 DNSSEC 驗證,保持軟體更新(源連接埠隨機化等防投毒機制依賴較新的版本),並且只對自己的網段提供遞迴,不要做對公網開放的遞迴伺服器。
怎麼防範 DNS 劫持:域名側與伺服器側清單
| 措施 | 主要防哪一類 | 怎麼做 |
|---|---|---|
| 註冊商帳號加固 | 帳號被盜 | 強密碼加二次驗證;用公司專用郵箱註冊,不掛在某個員工的個人帳號下;定期檢查登入記錄 |
| 域名鎖定 | 帳號被盜 | 開啟註冊商提供的轉移鎖、更新鎖;重要域名可以申請註冊局鎖定(Registry Lock),改 NS 需要線下核驗 |
| DNSSEC | 快取投毒、傳輸途中篡改 | 在 DNS 服務商處開啟簽名,再到註冊商處提交 DS 記錄 |
| CAA 記錄 | 被冒簽證書 | 只允許你實際在用的證書頒發機構簽發 |
| 可信的遞迴 DNS | 本機被改、運營商劫持 | 伺服器用機房 DNS 或知名公共 DNS,必要時開啟 DoT;辦公網統一下發 |
| HTTPS 與 HSTS | 內容篡改、降級 | 全站 HTTPS,HSTS 設足夠長的有效期 |
| 解析監控 | 所有型別 | 定時從多個遞迴伺服器和 TLD 伺服器查詢,結果不符就告警 |
DNSSEC 要說清楚它能做和不能做的:它讓開啟了驗證的遞迴伺服器能識別偽造的應答,對快取投毒和途中篡改有效;但如果攻擊者偷了你的註冊商帳號,可以連 DS 記錄一起刪掉,所以它代替不了帳號安全。驗證是否生效:
dig +dnssec www.example.com @1.1.1.1 | grep flags # flags 裡出現 ad,表示透過了驗證
delv www.example.com # 輸出 fully validated 表示簽名鏈完整
dig +short CAA example.com # 例如:0 issue "letsencrypt.org"
解析監控用一個簡單指令碼就能做,放進 crontab 每 5 分鐘跑一次,輸出接到你的告警渠道:
#!/bin/bash
# /usr/local/bin/dns-watch.sh:解析結果或 NS 與預期不符時輸出一行告警
DOMAIN=example.com
HOST=www.example.com
EXPECT_A="203.0.113.10"
EXPECT_NS="ns1.example-dns.com. ns2.example-dns.com."
for s in 223.5.5.5 119.29.29.29 8.8.8.8; do
got=$(dig +short +time=3 +tries=1 A "$HOST" @"$s" | sort | xargs)
[ "$got" = "$EXPECT_A" ] || echo "$(date '+%F %T') $s 返回 [$got],預期 [$EXPECT_A]"
done
ns=$(dig +norecurse +noall +authority NS "$DOMAIN" @a.gtld-servers.net | awk '{print $5}' | sort | xargs)
[ "$ns" = "$EXPECT_NS" ] || echo "$(date '+%F %T') 註冊局 NS 為 [$ns],預期 [$EXPECT_NS]"
用了 CDN 的域名,A 記錄會隨排程變化,改為監控 CNAME 的目標是否正確;預期值裡有多個位址時,按排序後的順序寫。
機房和 IDC 這一側能做什麼
IDC 給客戶提供的遞迴 DNS,本身就是快取投毒的目標。只對本機房的位址段開放遞迴、開啟 DNSSEC 驗證、兩台互為備份並監控應答時間,是自建遞迴 DNS 的基本要求。客戶的伺服器該填哪兩個 DNS,在 IP 位址管理 裡每個 IP 段都可以登記兩個 DNS 位址,開通和排障時有據可查,不會出現同一機房的伺服器各填各的。
區域網裡的 DNS 欺騙,前提是攻擊者能冒充閘道器或偽造源位址發包。接入交換器上把每台伺服器的 IP 與 MAC 繫結、開啟源位址校驗,偽造來源的資料包會被直接丟棄,一台客戶機器被入侵後,也很難對同網段的其他客戶發起 ARP 欺騙和偽造應答。這兩項都可以在 交換器管理 裡開啟,伺服器側的 MAC 由系統自動學習並繫結,換線和遷移時不用再人工核對。
常見問題
DNS 劫持會自動恢復嗎?
要看型別。快取投毒在偽造記錄的 TTL 到期後會消失;本機、路由器被改和運營商劫持不會自己恢復,要改回配置或投訴處理;域名帳號被盜更不會,必須先奪回帳號、把 NS 改回來,之後各地才會隨快取過期陸續恢復。
網站用了 HTTPS,還會被 DNS 劫持嗎?
解析結果照樣可能被改,但攻擊者拿不到你域名的有效證書時,訪客會看到證書錯誤,而不是悄無聲息地進入假網站;開啟了 HSTS 的網站,瀏覽器連“繼續存取”的選項都不給。只有攻擊者控制了你的域名解析、能申請到正規證書時,HTTPS 才擋不住。
改 hosts 檔案能防 DNS 劫持嗎?
只能讓這一台電腦臨時繞過 DNS,網站換 IP 後要手動改,用了 CDN 的網站還會因為寫死一個節點而變慢或打不開,不適合作為長期方案。