PowerDNS 是一款支持多個後端的 DNS 服務端軟件,本次搭建基於 Debian 9,配置 PowerDNS 權威 DNS,使用 Mariadb 和 geoip 後端,並使用 lua 記錄實現按地區解析。

本文假設擁有一個 example.com 域名,本台機的主機名為 ns1.example.com,ns1 管理員郵箱為 [email protected]

1. 安裝軟件

導入 PowerDNS repo [1],安裝最新版 PowerDNS 及後端

1.1. 新增 /etc/apt/sources.list.d/pdns.list 文件,填入如下內容。請根據閣下的發行版相應更改。

1.2. 新增 /etc/apt/preferences.d/pdns 文件,並填入如下內容。

1.3. 導入 key 並安裝,此處安裝 powerdns mysql 和 geoip 後端。

1.4. 安裝 Mariadb,在此過程中可能需要設定 MySQL root 密碼。

 

2. 設定數據庫

新建新的用戶、數據庫供 PowerDNS 使用,並且導入基礎數據表結構。

2.1. 新建一個用戶、數據庫。此處用戶名、數據庫名為 dns,密碼為 PASSWORD。請根據實際需求更改。

2.2. 導入數據庫表結構,並設定外鍵。以下是官方文檔 [2] 提供的表結構,閣下可以根據需求進行修改。

2.3. 插入測試域名

插入域名,設定 SOA 記錄,NS 記錄,以及主機 www 的 A 記錄為 1.1.1.1

此處需要注意格式。domain_id 的值為 domains 表新增的域名 id。name 的值需為完整域名,結尾不需加 "."

同樣,SOA 記錄的 ns 和郵箱結尾不需要加點,郵箱的 "@" 需要替代為 "."。NS 記錄的內容結尾也不需要加。 [5]

 

3. 設定 PowerDNS

本節新增 PowerDNS 配置文件,配置 MySQL 及 GeoIP 後端。請新開一個 Shell 進行以下操作。

3.1. 下載 geoip 數據庫,用來分區域解析。

雖然官方說明支持 geoip2 數據庫,但是測試過程中啓動失敗。因此此處採用 maxmind 的 geoip 數據庫,由第三方提供轉換。

3.2. 清空並編輯 /etc/powerdns/pdns.conf 文件。

開啓 lua 記錄,開啓 MySQL 及 GeoIP 後端並設定。此處 MySQL 訊息需與 2.1 的設定一致。此處 geoip 數據庫路徑需與 3.1 的文件路徑相同。

 

4. 啓動 PowerDNS 進行測試

4.1. 在前臺啓動 PowerDNS,方便 debug

出現類似以下的 log 即代表開啓成功。

4.2. 新開一個 Shell,使用 dig 進行測試。

若一切正常,將查詢出 1.1.1.1

 

5. 設定 LUA 記錄動態更改解析

PowerDNS 自帶 LUA 記錄 [3],可以根據 LUA 代碼動態返回解析結果。同時預設了多個 LUA 方法[4]。

  • country(2位地區代碼)

如果請求 IP 屬於這個地區,返回 true。可傳遞 list

  • continent(2位大洲代碼)

如果請求 IP 屬於這個大洲,返回 true。可傳遞 list

  • pickrandom(IP地址 list)

隨機返回該 list 的一個 IP 地址

  • ifportup(端口號, IP 地址 list)

如果該 IP 地址指定端口號開啓,則返回。可配合選擇方案

本 LUA 例子為判斷地區/大洲,然後返回相應的 A 記錄。開頭先說明返回的記錄為 A,後面跟 LUA 代碼。如果國家為 新加坡、日本,返回3.3.3.3,如果大洲為歐洲,返回 4.4.4.4,其他(默認)情況返回1.1.1.1。由於 LUA 本身不支持 switch 語法,此處使用多個 if。

5.1. 在第二步的 MySQL Shell 窗口插入這條記錄。如果覺得這樣不好睇,可以選擇在圖形化 MySQL 客戶端上操作,如 Navicat。

5.2. 從上述地區發出 dig 請求,測試是否返回相應的記錄。

 

6. 設定多臺 NS 服務器,並同步數據

6.1. 在 ns1 上導出數據庫。

6.2. 傳輸此sql文件到其他服務器(ns2),在ns2上重複上述步驟 1,3。第 2 步 只需要執行創建數據庫部分,然後導入 ns1 的數據庫。

6.3. 在 ns2 中執行步驟 4 進行測試。

測試成功後,將 ns2 的數據庫設定為 slave 模式,使用 MySQL 主從複製 同步數據 [6]。

需要增加記錄時,更改 ns1 的 MySQL 數據庫即可。

 

7. 在域名註冊商處增加相應膠水記錄 (glue record)

新增膠水記錄,將 ns1.example.com 指向 ns1 IP 地址,ns2.example.com 指向 ns2 IP 地址等。不同域名商可能有不同的叫法,如 register name server 等。

接下來將其他域名的 nameserver 指定到以上 ns 域名即可。

 

參考資料

[1] PowerDNS repo,根據不同系統選擇不同的 repo
[2] 基礎數據庫設定,可根據業務需要更改表結構
[3] LUA 記錄例子
[4] LUA 預設變量和方法
[5] PowerDNS 支持的記錄及格式

 

後記

在選用 PowerDNS 之前,我也測試過以下權威DNS軟件。

gdnsd. 輕巧,文件存儲。由於需要先定義數據中心,在域名多、區域解析多的情況下不太方便。不支持 DNSSEC。

bind9. 事實上的 DNS 標準。官方沒有提供 MySQL 的表結構,測試起身麻煩,先放棄。

   

已有 5 條評論

  1. R 4 年前 (2020-07-09)
    @

    主要是,mmdb格式只能单独在geoip.conf配置似乎,而且不能搭配mysql,只能配置zone files

  2. R 4 年前 (2020-07-08)
    @

    你好,请问下博主配置成功mmdb格式了吗?我测试了好一会,发现mmdb无法正常工作(结合mysql)

    • Jerry 4 年前 (2020-07-09)
      @

      没有喔,之前配置不成功,我就没有再尝试mmdb了。网上有转换mmdb为dat的代码,可以尝试下。

  3. Andy 4 年前 (2020-05-10)
    @

    你好,请教个问题,pdns授權DNS支援MySQL geoip lua後端同時工作麼?
    為什麼我按照博主的博客操作進行,但不能實現不同地區解析得到不同的ip呢?

    • Jerry 4 年前 (2020-05-10)
      @

      你好,支持的,我现在就在用。

      如果你配置了lua记录,能正常得到解析结果,但是没有地区解析效果,可能是geoip数据库没弄好。