之前詳細介紹了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地址相比於之前更多了.