DNS之BIND使用小結(Forward轉發)

散盡浮華發表於2018-07-24

 

之前詳細介紹了DNS及其在linux下的部署過程,今天再說下DNS的BIND高階特性-forwarder轉發功能。比如下面一個案例:
1)已經在測試環境下部署了兩臺內網DNS環境,DNS的zone域名為kevin.cn:http://www.cnblogs.com/kevingrace/p/5570312.html
2)測試機器的DNS地址已經調整為這兩臺DNS地址,所以測試機訪問kevin.cn域名是沒有問題的。
由於業務需求,需要測試機器能訪問grace.cn域名(grace.cn域名是使用別的DNS地址解析的),這就用到了DNS的BIND中的forwarder轉發功能了。
通過BIND的forwarder轉發功能,將測試機訪問的非kevin.cn的域名都轉向forwarder指定的DNS地址上。

forwarder轉發功能只需要在named.conf中配置即可:
[root@uatdns01 ~]# cat /etc/named/named.conf
options {
             listen-on port 53 { any; };
             listen-on-v6 port 53 { ::1; };
             directory "/var/named";
             dump-file "/var/named/data/cache_dump.db";
             statistics-file "/var/named/data/named_stats.txt";
              memstatistics-file "/var/named/data/named_mem_stats.txt";
              allow-query { any; };
              recursion yes;
              forward first;
              forwarders {            #即訪問非kevin.cn域名時將解析轉發到這幾個DNS地址(分別為阿里的DNS、google的DNS)上進行解析。
                     223.5.5.5;          #注意這裡轉發的是DNS地址,沒有指定DNS轉發域名。
                     223.6.6.6;
                     8.8.8.8;
                     8.8.4.4;
               };
               };

logging {
             channel default_debug {
             file "data/named.run";
             severity dynamic;
             };
};

zone "." {
              type hint;
              file "named.ca";
};

zone "kevin.cn" {
              type master;
              file "kevin.cn_zone";
};
zone "51.168.192.in-addr.arpa" {
              type master;
              file "192.168.51.zone";
};

zone "50.168.192.in-addr.arpa" {
              type master;
              file "192.168.50.zone";
};

zone "104.168.192.in-addr.arpa" {
              type master;
              file "192.168.104.zone";
};
zone "grace.cn" {                       #訪問grace.cn域名時,將解析請求轉到192.168.51.39(即grace.cn域名的DNS地址),注意這個不能寫在上面的forwarder處,否則轉發無效!
              type forward;                #注意這裡轉發配置中制定了轉發的域名,即forwad轉發區(forward zone)設定,這是bind9之後的新特性。
              forwarders { 192.168.51.39; };
};

========================================================================
嘗試了下,無法在一個named.conf裡同時配置兩個或多個域的zone(即正向解析的zone),配置好並重啟named伺服器後,多出的那個域名解析無效。
比如內網有兩個域名:kevin.cn和grace.cn,要做這兩個域名的DNS解析環境,實現方案如下:

1)分別針對kevin.cn和grace.cn部署兩套DNS環境
2)在其中一個域名的DNS環境中使用forwadr轉發,比如在kevin.cn域名的named.conf配置中新增:
     zone "grace.cn" {                       
              type forward;                
              forwarders { 192.168.51.39; };           # 該ip為grace.cn域名的DNS伺服器地址
     };
3)將客戶機的DNS(/etc/resolv.conf)配置成kevin.cn域名的DNS地址,這樣該客戶機對於kevin.cn和grace.cn域名都可以解析。

===========================BIND之forwarder轉發功能小結======================
forward first | only;
forward指令用於設定DNS轉發的工作方式:
1)forward first設定優先使用forwarders DNS伺服器做域名解析,如果查詢不到再使用本地DNS伺服器做域名解析。
2)forward only設定只使用forwarders DNS伺服器做域名解析,如果查詢不到則返回DNS客戶端查詢失敗。

最新版的BIND提供了很多非常好的DNS新特性,其中一個就是Forwarder轉發功能:

總所周知,某些網路連線是不鼓勵向本地以外傳送很大的資料流量的,因為網路連線是按流量計費的,並且網路連線本身是頻寬不足。在這樣的情況下,如果想將發往外部的DNS流量限制到儘可能的小,就需要使用BIND的轉發機制。或者網路中只有一臺機器能連線到Internet ,而在這臺機器上執行了 BIND ,那麼可以將這臺BIND作為內部網路中的其他BIND的轉發器,使得其他DNS也能查詢Internet域名。
BIND的forward轉發機制的這樣的:
當設定了forwarders轉發器後,所有非本域的和在快取中無法找到的域名查詢都將轉發到設定的DNS轉發器上,由這臺DNS來完成解析工作並做快取,因此這臺轉發器的快取中記錄了豐富的域名資訊。因而對非本域的查詢,很可能轉發器就可以在快取中找到答案,避免了再次向外部傳送查詢,減少了流量

轉發器的配置格式是:
options {
            forwarders { 192.168.10.35; 192.168.10.36; };
};

這裡需要注意的是:
轉發器本身不用做任何設定,而是對需要轉發器的其他DNS server做以上配置。還有,如果該DNS Server無法聯絡到轉發器,那麼BIND會自己嘗試解析。

如果要禁止BIND在無法聯絡到轉發器時不做任何操作,那麼還可以使用forward only命令,這樣BIND只能使用區的權威資料和快取來響應查詢了(在連線不到轉發器的情況下)。
options {
            forwarders { 192.168.10.35; 192.168.10.36; };
            forward only;
};

=======================================================================
在BIND8.2以後引入了一個新的特性:轉發區(forward zone),它允許把DNS配置成只有查詢特定域名的時候才使用轉發器( BIND 9從9.1.0才開始有轉發區功能 )例如,你可以使你的伺服器將所有對 kevin.cn 結尾的域名查詢都轉發給 kevin.cn 的兩臺名字伺服器:
zone "kevin.cn" {
          type forward;
          forwarders { 110.50.80.208; 110.50.80.209; };
};

這樣的功能有什麼用呢?
假設kevin.cn和你的網路有一個私有的連線,而kevin.cn又沒有連線上Internet ,那麼你從Internet 是無法查到 kevin.cn 字尾的域名的,這時你就要使用轉發區的功能了。

還有一種轉發區設定和剛才的設定剛好相反,它允許設定什麼樣的查詢將不被轉發,當然這隻適用於在options語句中指定了轉發器的DNS 。配置如下:
options {
            directory "/var/named";
            forwarders { 192.168.10.35; 192.168.10.36; };
};

zone "kevin.cn" {
          type master;
          file "zone.kevin.cn";
          forwarders {};
};

這樣寫有人可能會問為什麼要在自己的權威區裡禁止轉發?難道不是自己回答查詢而不使用轉發器嗎?
這是因為有這樣一種情況:在 kevin.cn這個區中,你授權了幾個子域,例如:zx.kevin.cn、lab.kevin.cn 等,那麼在kevin.cn的權威伺服器上設定轉發後,因為對 zx.kevin.cn、lab.kevin.cn 這幾個子域不是權威,那麼如果有對www.zx.kevin.cn這樣的子域的域名查詢,伺服器也將轉發。這完全是沒有必要的,因為伺服器上就有zx.kevin.cn 子域的NS記錄,何須再轉發。

假設我的DNS伺服器 192.168.1.10,在BIND中有這麼一個配置
forward only;
             forwarders {
            192.168.1.12;
};

這裡的192.168.1.10解析不了的,就會被轉發到192.168.1.12這就是DNS轉發器。
說到這裡就不得不說下BIND的遞迴功能了。

=====================BIND遞迴查詢功能小結====================
預設 Resolver 發出的是遞迴查詢,而且預設 BIND name server 也處理所有的遞迴請求。

遞迴查詢的工作方式
遞迴查詢是最常見的查詢方式,域名伺服器將代替提出請求的客戶機(下級DNS伺服器)進行域名查詢,若域名伺服器不能直接回答,則域名伺服器會在域各樹中的各分支的上下進行遞迴查詢,最終將返回查詢結果給客戶機,在域名伺服器查詢期間,客戶機將完全處於等待狀態。
示例: (紅色為查詢,藍色為迭代查詢返回的提示資訊,棕色為遞迴查詢返回的IP資訊)

示例說明:
A向B傳送遞迴查詢請求,B向C傳送迭代查詢請求,得到C給出的提示後,B向D傳送迭代查詢請求,得到D給出的提示後,B向E發出迭代請求,得到E給出的提示後,B向F發出迭代查詢請求,得到F給出的提示後,B得到了F返回G的IP地址,B向A返回G的IP地址,整個查詢結束。

迭代查詢的工作方式
迭代查詢又稱重指引,當伺服器使用迭代查詢時能夠使其他伺服器返回一個最佳的查詢點提示或主機地址,若此最佳的查詢點中包含需要查詢的主機地址,則返回主機地址資訊,若此時伺服器不能夠直接查詢到主機地址,則是按照提示的指引依次查詢,直到伺服器給出的提示中包含所需要查詢的主機地址為止,一般的,每次指引都會更靠近根伺服器(向上),查尋到根域名伺服器後,則會再次根據提示向下查詢。從上節的圖中可以知道,B訪問C、D、E、F、G,都是迭代查詢,首先B訪問C,得到了提示訪問D的提示資訊後,開始訪問D,這時因為是迭代查詢,D又返回給B提示資訊,告訴B應該訪問E,依次類推。

說明:假設你要尋找一家你從未去過的公司,你會有2種解決方案:
1)找一個人替你問路,那可能是你的助手
2)自己問路,每走過一個路口,就問一個人,這就好比遞迴查詢和迭代查詢,遞迴查詢在這裡代表你的第1種解決方案,而迭代則是第2種解決方案。

但某些情況下,伺服器應該被配置為不接受遞迴請求,例如根域伺服器。根域伺服器不接受遞迴請求的原因 :
1)因為根域伺服器太忙了,它們沒有精力來回答遞迴查詢。
2)接受遞迴請求將會建立快取,如此根域伺服器的快取將會變得十分巨大

關於遞迴/非遞迴方面的配置語句有recursion no和 allow-recursion 語句,兩者都只能放在options或者view語句中;
recursion no只對外部域名有效,如果查詢的是本地zone域名(僅限於該 name server 上所定義的 zone,不包括下級子域)則可以回答。因為解析外部域名需要查詢外部 name server ,這才是 recursion no 控制和關心的部分,如果查詢的是本地 zone 的資料,當然不需要擔心本地 name server 被誘導,可以直接返回答案。

需要注意以下幾點;
1)保證該非遞迴伺服器不出現在客戶機的 /etc/resolv.conf 的
2)證該非遞迴伺服器不被其他 name server 當成轉發器 (forwarder)
3)推薦使用 allow-recursion 而不是 recursion
4)該非遞迴伺服器可以出現在 zone data file 的 NS 記錄中。它可以正常的接收其他 name server 發來的查詢
5)外部 name server 是通過上級域的 Referral 訊息找到該非遞迴伺服器的
6)外部 name server 在得到上級域的 Referral 訊息後,向該非遞迴伺服器傳送的查詢是 iterative query ,而不是 recusive query ,所以該非遞迴伺服器仍然可以回答那些它所權威的 zone 的查詢。但不能用於查詢外部域名了。

============================BIND配置語法小結============================
下面羅列出/etc/named/named.conf 中使用的常用配置語句。named.conf 中使用的常用配置語句:

acl 定義訪問控制列表,參考 acl
controls 定義 rndc 命令使用的控制通道,若省略此句,則只允許經過 rndc.key 認證的 127.0.0.1 的 rndc 控制,參考 rndc
include 將其他檔案包含到本配置檔案當中
key 定義用於 TSIG 的授權金鑰
logging 定義日誌的記錄規範,參考 BIND 9 的高階配置 的 “BIND 日誌部分”
lwres 將 named 同時配置成一個輕量級的解析器
options 定義全域性配置選項
trusted-keys 為伺服器定義 DNSSEC 加密金鑰
server 設定每個伺服器的特有的選項
view 定義域名空間的一個檢視,參考 BIND 9 的高階配置 的 “View 語句部分”
zone 定義一個區宣告

下面對named.conf中常用的語句作進一步的說明。

include
include 語句的功能為:將指定的檔案引入 named.conf 主配置檔案。語法為:

include "path";
建議使用絕對路徑
若使用相對路徑,則相對於 directory 選項指定的目錄
options
options 用於定義全域性配置選項,語法為:

options {
         配置子句;
         配置子句;
};

下面列出一些常用的全域性配置子句。

子句說明
directory “path” 定義伺服器區資料庫檔案的工作目錄,配置檔案中所有使用的相對路徑,指的都是在這裡配置的目錄下。Ubuntu 預設為 /var/cache/bind
notify yes/no 若 named 是主伺服器,當區資料庫變化時將自動通知相應區的從伺服器,預設為 yes
recursion yes/no 是否使用遞迴式 DNS 伺服器,預設為 yes
transfer-format one-answer/many-anser 設定從主伺服器向從伺服器複製資料的方式,使用在主域名伺服器上,是否允許在一條訊息中放入多條應答資訊,預設值為 many-answer
forwarders {IPaddrs} 設定全域性轉發器,列出要用作轉發器的伺服器 IP 地址
forward only/first 若值為 only,則伺服器快取資料並查詢轉發器,但從不查詢其他的任何伺服器,若轉發器不能響應查詢則查詢失敗;若值為 first,則在轉發查詢失敗或沒有查到結果時,會在本地發起正常查詢。預設為 first

zone 區宣告是配置檔案中最重要的部分。Zone 語句的格式為:
zone "zone-name" IN {
         type 子句;
         file 子句;
         其他子句;
};

下面列出一些常用的 zone 配置子句。

子句說明
type master/slave/hint/forward 說明一個區的型別。master:說明一個區為主域名伺服器;slave說明一個區為輔助域名伺服器;hint:說明一個區為根伺服器的線索;forward:說明一個區為轉發區
file “filename” 說明一個區的域資訊源資料庫資訊檔名

DNS 資料庫
一個域的 DNS 資料庫是由這個域的主域名伺服器的管理員所維護的文字檔案的集合。這些檔案經常被稱為區檔案,區檔案定義了一個區的域名資訊。Ubuntu 預設將區檔案存放在 /var/cache/bind 目錄下。

每個區檔案都是由若干個資源記錄(RR,resource records)和分析器指令所組成。

資源記錄簡介
標準資源記錄的基本格式是:
[name] [ttl] [class] type data

各個欄位之間由空格或製表符分隔,欄位可以包含如下的特殊字元:
; — 引出註釋
@ — 表示當前域
() — 允許資料跨行,通常用於 SOA 記錄
* — 僅用於 name 欄位的萬用字元

name 欄位
name 欄位說明資源記錄引用的物件名,可以是一臺單獨的主機也可以是個域名。
物件名可以是相對域名或全域名,全域名應該以“.”結束
若幾條連續的 RR 記錄涉及同一個物件名,則第一條 RR 記錄後的 RR 記錄可以省略物件名
若出現欄位名欄位,則必須出現在第一個欄位
關於相對域名和全域名:舉例來說,在 ubuntu.org.cn 域中,相對域名 osmond 與全域名 osmond.ubuntu.org.cn. 等效;而 osmond.ubuntu.org.cn 由於沒有以“.”結尾,被認為是一個相對域名,與其等效的全域名為 osmond.ubuntu.org.cn.ubuntu.org.cn.。因此在書寫物件名時要特別小心。

ttl 欄位
ttl(time to live) 欄位是一個壽命欄位。它以秒為單位定義該資源記錄中的資訊存放在快取記憶體中的時間長度。通常省略該欄位,而使用位於檔案開始處的 $TTL 語句所指定值。

class 欄位
class 欄位用於指定網路型別,可選的值有:IN、CH 和 HS,其中 IN (Internet)是廣泛使用的一種。雖然 IN 是該欄位的預設值,但通常我們會顯示地指出。

type 欄位
type 欄位用於說明 RR 的型別。常用的 RR 型別如下:

關於RR 的書寫順序
SOA RR 應該放在最前面
通常 NS RR 緊跟在 SOA RR 之後
其他記錄的順序無關緊要

data 欄位
data 欄位的內容取決於 RR 的型別欄位。

常用的資源記錄
SOA 資源記錄
SOA RR 用於標示一個區的開始,其格式如下:

zone IN SOA Hostname Contact (
              SerialNumber
              Refresh
              Retry
              Expire
              Minimum )

SOA 記錄的資料說明
Hostname
存放本 Zone 的域名伺服器的主機名
Contact
管理域的管理員的郵件地址
SerialNumber
本區配置資料的序列號,用於從伺服器判斷何時獲取最新的區資料
Refresh
輔助域名伺服器多長時間更新資料庫
Retry
若輔助域名伺服器更新資料失敗,多長時間再試
Expire
若輔助域名伺服器無法從主伺服器上更新資料,原有的資料何時失效
Minimum
設定被快取的否定回答的存活時間

如下示例:

kevin.cn.     IN      SOA   wang.kevin.cn.  root.wang.kevin.cn. (
                              2006063000       ;序列號
                              3H               ;3小時後重新整理
                              15M              ;15分鐘後重試
                              1W               ;1星期後過期
                              1D )             ;否定快取TTL為1天

對 Contact 來說,因為“@”在檔案中有特殊含義,所以郵件地址 root@wang.kevin.cn 寫為 root.wang.kevin.cn.
對 SerialNumber 來說,它可以是 32 位的任何整數,每當更新區檔案時都應該增加此序列號的值,否則 named 將不會把區的更新資料傳送到從伺服器
快取時間欄位 Refresh、Retry、Expire、Minimum 可以使用時間單位字元 m、h、d、w 分別表示分鐘、小時、天、星期。
各個快取時間欄位的經驗值為:
Refresh — 1 到 6 小時
Retry — 20 到 60 分鐘
Expire — 1 周 到 1 月
Minimum — 1 到 3 小時
Minimum 設定被快取的否定回答的存活時間,而肯定回答(即真實記錄)的預設值是在區檔案開始處用 $TTL 語句設定的。

NS 資源記錄
NS RR 用於標識一個區的權威伺服器(包括主伺服器和從伺服器),並將子域授權賦予其他伺服器,其格式如下:
zone    [ttl]    IN    NS    hostname

示例如下:

kevin.cn.          IN    NS    wang.kevin.cn.             #指定 kevin.cn. 的主伺服器
kevin.cn.          IN    NS    dapper.kevin.cn.           #指定 kevin.cn. 的從伺服器
osmond.kevin.cn.   IN    NS    ubuntu.osmond.kevin.cn.    #指定委派域 osmond.kevin.cn. 的主伺服器
osmond.kevin.cn.   IN    NS    dapper.osmond.kevin.cn.    #指定委派域 osmond.kevin.cn. 的從伺服器

若上面的記錄緊跟在 SOA 記錄後,也可以寫成如下的形式:

IN    NS    wang.kevin.cn.                    #指定 kevin.cn. 的主伺服器
          IN    NS    dapper.kevin.cn.        #指定 kevin.cn. 的從伺服器
osmond    IN    NS    ubuntu.osmond.kevin.cn. #指定委派域 osmond.kevin.cn. 的主伺服器
osmond    IN    NS    dapper.osmond.kevin.cn. #指定委派域 osmond.kevin.cn. 的從伺服器

A 資源記錄
A RR 是 DNS 資料庫的核心,它提供了主機名到 IP 地址的對映。其格式為:
hostname    [ttl]     IN     A     IPAddress

對於 kevin.cn 區來說, 如下示例:

wang            IN    A      192.168.0.251
dapper          IN    A      192.168.0.252
wang.osmond     IN    A      192.168.1.251
dapper.osmond   IN    A      192.168.1.252

也可以寫成如下的形式

wang.kevin.cn.            IN    A      192.168.0.251
dapper.kevin.cn.          IN    A      192.168.0.252
wang.osmond.kevin.cn.     IN    A      192.168.1.251
dapper.osmond.kevin.cn.   IN    A      192.168.1.252

對於有多個網路介面的計算機來說,可以使用多條 A RR 分別設定每個網路介面上的主機名與 IP 地址的對映。當然多個 IP 地址也可以關聯同一個主機名。類似地,也可以使用多條 PTR RR 分別設定每個網路介面上的 IP 地址與主機名的對映。

PTR 資源記錄
PTR RR 提供了 IP 地址到主機名的對映。其格式為:
IPAddress     [ttl]    IN    PTR    hostname

例如: 在 168.192.in-addr.arpa 區中,前面的 wang.kevin.cn. 和 dapper.kevin.cn. 所對應的 PTR 記錄為:

251.0          IN    PTR      wang.kevin.cn.
252.0          IN    PTR      dapper.kevin.cn.

而在 0.168.192.in-addr.arpa 區中,前面的 wang.kevin.cn. 和 dapper.kevin.cn. 所對應的 PTR 記錄為:

251          IN    PTR      wang.kevin.cn.
252          IN    PTR      dapper.kevin.cn.

在 1.168.192.in-addr.arpa 區中,前面的 wang.osmond.kevin.cn. 和 dapper.osmond.kevin.cn. 所對應的 PTR 記錄為:

251          IN    PTR      wang.osmond.kevin.cn.
252          IN    PTR      dapper.osmond.kevin.cn.

在 PTR RR 中 hostname 應該使用全域名。例如 osmond.kevin.cn 域的主機 wang 應該寫為 wang.osmond.kevin.cn. 。而 wang.osmond.kevin.cn 將被解析為 wang.osmond.kevin.cn.1.168.192.in-addr.arpa. 。
PTR RR 所提供的反向解析能夠為任何對進入網路的請求進行認證的程式所使用,這些程式包括:sshd、tcpd、sendmail、syslogd 等。

MX 資源記錄
MX RR 用於郵件系統實現郵件路由 。 其格式為:
zone    [ttl]   IN   MX   preference   host

其中 preference 是優先順序欄位,數值越小優先順序越高。
示例如下:

kevin.cn.          IN    MX     5     wang.kevin.cn.
kevin.cn.          IN    MX     10    wang.kevin.cn.

CNAME 資源記錄
CNAME RR 用於設定主機的別名。 其格式為:
nikename   [ttl]   IN   CNAME    hostname

示例如下:

wang            IN    A      192.168.0.251
www             IN    CNAME  wang
ftp             IN    CNAME  wang

檔案內必須有規範名字的 A RR。

分析器指令
在區檔案中還可以使用分析器指令,分析器指令可以為 RR 的輸入提供方便。

$ORIGIN — 設定預設域(或初始域)
$TTL — 為沒有定義精確的生存期的 RR 定義預設的 TTL 值 

                                                                 遇到過一個DNS的forwarders轉發設定的問題                                                         

IDC機房伺服器上部署了內網DNS環境, 線上各伺服器的/etc/resolv.conf檔案裡均配置了該DNS地址. 後來在其中過的一臺伺服器上去wget下載一個客戶方的地址, 有時好有時壞, 由於該客戶方的這個url裡的域名採用了CDN加速, 所以在機房的這臺伺服器上"nslookup 該域名" 解析這個客戶方的域名的ip是隨時變的 (即解析到的都是CDN那邊的地址池裡的地址), 有時會解析不到這個域名的地址. 這是為什麼呢?

發現是因為該機房DNS配置 (/etc/named/named.conf)裡的forwarders轉發到的NS伺服器地址問題導致的. 因為之前配置的forwarders是:

      forwarders {
            223.5.5.5;
            223.6.6.6;
            8.8.8.8;
            8.8.4.4;
          };

即之前通過forwarders轉發的NS地址是阿里雲和谷歌的DNS地址.  後來又加上聯通的DNS地址並放在了前面 (這幾個DNS地址在forwarders轉發時是輪詢關係)就解決了上面問題:

      forwarders {
            114.114.114.114;
            202.106.0.20;
            223.5.5.5;
            223.6.6.6;
            8.8.8.8;
            8.8.4.4;
          };

如上新增後, 在機房的那臺伺服器上通過"nslookup 客戶域名" 解析出來的ip地址相比於之前更多了.

相關文章