全部產品
Search
文件中心

HTTPDNS:CEF架構接入DoH最佳實務

更新時間:Oct 10, 2025

本文檔介紹如何在CEF架構中接入DoH。

1. 前言

CEF(Chromium Embedded Framework)是一個基於Chromium的開源架構,廣泛應用於需要嵌入Web瀏覽功能的傳統型應用程式中。在CEF架構的應用情境中,尤其是在涉及敏感性資料互動或高安全性要求的環境中,傳統DNS解析方式可能無法滿足安全需求。DoH通過HTTPS加密通道傳輸DNS查詢和響應,能夠有效防止中間人攻擊、DNS劫持以及流量嗅探,從而提升應用的安全性和使用者隱私保護能力。通過將DoH整合到CEF架構中,開發人員可以在不改變原有應用邏輯的前提下,顯著提升嵌入式瀏覽器的安全性和使用者體驗。

2. 前提條件

在CEF架構接入 DoH 前,請您確保已經完成配置DoH服務

說明
  • CEF 會使用內建的探測網域名稱 google.com 對 DoH 可用性檢查,在探測完成前,DoH 被視為“未確定可用”,為保證 DoH 服務正常工作,請確保 google.com 網域名稱添加到解析列表中或允許所有網域名稱解析

  • CEF版本要求:建議使用115或更高版本(對應Chromium 115+)

3 接入步驟

CEF架構接入DoH主要包含三個核心步驟:首先需要配置獨立的應用級緩衝路徑以避免配置衝突;然後通過Preferences API設定DoH模板和模式以啟用加密DNS服務;最後實現自動降級機制以保障服務的穩定性。以下將詳細介紹每個步驟的具體實現方法。

3.1 配置CEF應用緩衝路徑

本方案需要主動配置應用級的緩衝路徑。若未主動設定緩衝路徑而使用預設路徑,其他CEF應用可能會汙染本應用緩衝,導致DoH配置失效或被覆蓋。

在初始化CEF時,可以通過CefSettings對象來設定緩衝路徑,同時確保應用有許可權訪問此緩衝路徑。以下為範例程式碼:

void ConfigureCachePath(CefSettings& settings) {
    // 設定根緩衝路徑
    std::string cache_path;
    
#if defined(OS_MAC)
    cache_path = std::string("/Users/") + getenv("USER") + "/Library/Application Support/YourAppName/cache";
#elif defined(OS_WIN)
    cache_path = std::string(getenv("LOCALAPPDATA")) + "\\YourAppName\\cache";
#else
    cache_path = std::string(getenv("HOME")) + "/.cache/YourAppName";
#endif
    
    CefString(&settings.root_cache_path) = cache_path;
    CefString(&settings.cache_path) = cache_path;
}

// 在main函數中使用
int main(int argc, char* argv[]) {
    CefSettings settings;

    // 其他參數配置
    // ...
    
    ConfigureCachePath(settings);
    
    // 初始化CEF
    CefInitialize(main_args, settings, app.get(), nullptr);
    // ...
}

3.2 通過Preferences配置DoH

使用CefPreferenceManager來配置DoH。以下為範例程式碼:

void UpdateDnsOverHttpsTemplate(const std::string& new_template) {
    // 擷取全域的 CefPreferenceManager 執行個體
    CefRefPtr<CefPreferenceManager> pref_manager = 
        CefPreferenceManager::GetGlobalPreferenceManager();
    
    // 設定DoH模板
    CefRefPtr<CefValue> template_value = CefValue::Create();
    template_value->SetString(new_template);
    
    // 設定DoH模式為"secure"
    CefRefPtr<CefValue> mode_value = CefValue::Create();
    mode_value->SetString("secure");
    
    // 應用設定
    CefString error;
    pref_manager->SetPreference("dns_over_https.mode", mode_value, error);
    pref_manager->SetPreference("dns_over_https.templates", template_value, error);
}

// 在應用初始化時調用
void OnContextInitialized(CefRefPtr<ClientAppBrowser> app) override {
    // 在此處更換為自己的專屬DoH存取點
    UpdateDnsOverHttpsTemplate("https://1xxxx3.aliyunhttpdns.com/dns-query");
}

3.3 實現自動降級機制

CEF支援以下DoH模式:

  • secure: 強制使用DoH,不允許回退到普通DNS。

  • automatic: 自動模式,允許在DoH失敗時回退到普通DNS。

  • off: 關閉DoH。

為了提高應用的可用性,可以實現自動降級機制:在DoH解析失敗時自動切換到本地DNS。以下是一個實現樣本:

void ClientHandler::OnLoadError(CefRefPtr<CefBrowser> browser,
                                CefRefPtr<CefFrame> frame,
                                ErrorCode errorCode,
                                const CefString& errorText,
                                const CefString& failedUrl) {
  // 檢測DNS相關錯誤
  if (errorCode == ERR_NAME_NOT_RESOLVED ||
      errorCode == ERR_NAME_RESOLUTION_FAILED) {
    LOG(ERROR) << "DNS resolution failed for URL: " << failedUrl.ToString()
              << ". Error code: " << errorCode
              << ". Switching to Local DNS...";

    // 擷取全域preference manager
    CefRefPtr<CefPreferenceManager> pref_manager =
        CefPreferenceManager::GetGlobalPreferenceManager();

    // 切換到automatic模式,允許使用本地DNS
    CefRefPtr<CefValue> new_mode = CefValue::Create();
    new_mode->SetString("automatic");

    CefString error;
    if (pref_manager->SetPreference("dns_over_https.mode", new_mode, error)) {
      // 重試載入失敗的頁面
      frame->LoadURL(failedUrl);
      return;
    }
  }
  // 處理其他錯誤...
}

4. 總結

通過本文檔介紹的步驟,您可以成功在CEF架構中整合DNS over HTTPS (DoH)功能,從而顯著提升應用程式的安全性和使用者隱私保護能力。配置後可通過網路抓包查看 HTTPS 請求、檢查 DNS 日誌或進行網路故障測試來驗證 DoH 接入成功。推薦使用 automatic 模式並配置多個 DoH 伺服器以確保生產環境的穩定性。