Bind9詳解


BIND9詳解

ISC的bind一直以來基本上都是DNS的工業標准,不過BIND一直是漏洞不斷,直到出了BIND9,isc的開發人員對bind9進行了重寫,才相對好了一點。

BIND9的安裝就不用多說了,這里使用最新版本9.2.3,說白了也就是需要named這個可執行文件就可以了,其他的配置文件完全可以自己來寫。如果需要進行服務的控制的話,則需要rndc這個文件了。named大約有4M多,strip一下也就1M多點,再裁減裁減完全可以做到400K的,做嵌入式的朋友也不妨考慮考慮這個了。

服務的啟動與停止可以完全自己來寫一個腳本來控制,啟動的話先判斷是否已經啟動,pidof named,如果已經啟動,則提示已經啟動,否則執行named –c /etc/named.conf,停止的時候先判斷是否已經啟動,是的話則killproc named,否的話提示沒有啟動,具體可在網上查找。

下面重點來說說BIND9的新功能.

name.conf

named.confbind9的最先讀取的一個文件,named支持如下語句:

  • Acl
  • Controls
  • Include
  • Key
  • Logging
  • Lwres
  • Options
  • Server
  • Trusted-keys
  • View
  • Zone

其中主要的是 aclcontrolsincludeloggingkeyoptionsviewzone其他的很少用到我們就來詳細的對這些進行解釋一下.

acl

acl 用來對bind的訪問進行限制,是一個全局的設置,前面配置的acl在整個bind中都適用,和路由器里面的access-list有同工之處,語法是

acl acl-name {
    address_match_list
};

其中的address_match_list是一個地址列表,如192.168.0.0/24;,記住最后一定得有分號,有多個的話中間用分號格開,如192.168.0.0/32;192.168.1.0/24;

bind內置了4個acl分別是:

  • any:對應所有的,也就是0.0.0.0/0.
  • none:對應為空.
  • localhost:對應本地機器.
  • localnets:對應本地網絡.

controls

controls主要用於對bind進行控制,如:

key "rndc-key" {
    algorithm hmac-md5;
    secret "VkMaNHXfOiPQqcMVYJRyjQ==";
};
controls {
    inet 127.0.0.1 port 953
    allow { 127.0.0.1; } keys { "rndc-key"; };
};

設置rndc控制的端口以及端口,keys用來設置控制的密鑰

include

include是一個非常有用的選項,如果需要寫程序來讀寫bind的配置文件,這個將會用到,因為bind的配置文件很不規則,但是用了include后,就可以變的很規則,就和數據庫一樣了,功用和c語言里面的include一樣。

用於導入拆分的配置文件。

options

options是用於設置bind的一些選項,我們將重點介紹,BING9支持的選項如下:

options {
	additional-from-auth boolean;
    additional-from-cache boolean;
    // *allow-recursion允許遞歸查詢的地址列表(allow-recursion):設置允許進行遞歸查詢的ip地址列表,缺省值是允許所有地址進行查詢,需要注意的是當設置了不允許遞歸查詢后,如果仍然能夠查詢部分外部的域名,那是因為dns的緩存在起作用,將緩存清除以后就可以了。
    allow-recursion { address_match_element; };
    allow-v6-synthesis { address_match_element; };
    // *allow-query 允許普通查詢的地址列表(allow-query):設置允許進行普通查詢的ip地址列表,在域中的設置將覆蓋全局設置,默認情況下是允許所有的地址進行普通查詢。
    allow-query { address_match_element; };
    // *allow-transfer允許服務器進行區域傳輸的地址列表(Allow-transfer):(注意的是視區和域中的設置將覆蓋全局設置)
    allow-transfer { address_match_element; ... };
    allow-update-forwarding { address_match_element; ... };
    // *allow-notify 允許更新通知的地址列表(allow-notify),當服務器作為輔助服務器的時候,設置這個可以對收到的更新通知進行判斷,只是接收該列表的更新通知.默認情況下,只是接收來自主服務器的更新通知。對於其他服務器的更新通知,會忽略掉.
    allow-notify { address_match_element; ... };
    // *auth-nxdomain 是否做為權威服務器回答域不存在(Auth-nxdomain)
如果設置為'yes',則允許服務器以權威性(authoritatively)的方式返回NXDOMAIN(該域不存在)的回答,否則就不會作權威性的回答,缺省值為”是”.
    auth-nxdomain boolean; // default changed
    
    // *blockhole 定義服務器不對查詢進行反應的地址列表,也就是”黑名單”,比如說3721的ip段:218.244.44.0/24,當設置了黑名單后,對於這個段的請求查詢,服務器將不會作出反應.
    blackhole { address_match_element; };
    
    coresize size;
    datasize size;
    deallocate-on-exit boolean; // obsolete
    // *directory 設置bind的數據文件的存放位置:如 directory “/var/named”.
    directory quoted_string;
    // *dump-file 設置當執行rndc dumpdb命令后的導出文件存放絕對路徑,如果沒有指定的話,缺省文件為named_dump.db,放在directory指定的目錄下面.
    dump-file quoted_string;
    fake-iquery boolean; // obsolete
    files size;
    has-old-clients boolean; // obsolete
    heartbeat-interval integer;
    host-statistics boolean; // not implemented

    // *interface-interval 設置bind檢查網卡變化的周期.
    interface-interval integer;
    // *listen-on 設置bind的綁定ip和端口,如listen-on 53 {192.168.0.1;};
    listen-on [ port integer ] { address_match_element; ... };
    listen-on-v6 [ port integer ] { address_match_element; ... };
    match-mapped-addresses boolean;
    memstatistics-file quoted_string; // not implemented
    multiple-cnames boolean; // obsolete
    named-xfer quoted_string; // obsolete

    // *pid-file 設置bind的進程號pid文件.
    pid-file quoted_string;
    port integer;
    random-device quoted_string;
    recursive-clients integer;
    rrset-order { [ class string ] [ type string ] [ name
    quoted_string ] string string; ... }; // not implemented
    serial-queries integer; // obsolete
    serial-query-rate integer;
    stacksize size;
    statistics-file quoted_string;
    statistics-interval integer; // not yet implemented
    tcp-clients integer;
    tkey-dhkey quoted_string integer;
    tkey-gssapi-credential quoted_string;
    tkey-domain quoted_string;
    transfers-per-ns integer;
    transfers-in integer;
    transfers-out integer;
    treat-cr-as-space boolean; // obsolete
    use-id-pool boolean; // obsolete
    use-ixfr boolean;

    // *version 設置客戶查詢DNS版本好的返回信息,如果不想讓客戶探測到當前的版本好,就用這個好了,如version mydns1.0;
    version quoted_string;
    sortlist { address_match_element; ... };
    topology { address_match_element; ... }; // not implemented

    minimal-responses boolean;

    // *recursion 是否允許遞規查詢(recursion)如果設置為”yes”,則允許服務器采用遞歸的方式進行查詢,也就是當要查詢的地址不在服務器的數據庫列表中時,服務器將一級一級的查詢,直到查到為止(一般對局域網都打開)。設置為”no”,並不意味着服務器對於請求的遞歸查詢不給予回答,而是對於請求的遞歸查詢,不再向上級服務器請求,也不緩存,如果不對請求的遞歸查詢回答,可以清空緩存,然后設置為“NO”。
    recursion boolean;
    provide-ixfr boolean;
    request-ixfr boolean;
    fetch-glue boolean; // obsolete
    rfc2308-type1 boolean; // not yet implemented
    query-source querysource4;
    query-source-v6 querysource6;
    cleaning-interval integer;
    min-roots integer; // not implemented
    lame-ttl integer;
    max-ncache-ttl integer;
    max-cache-ttl integer;
    transfer-format ( many-answers | one-answer );
    // *max-cache-size 設置最大緩存的大小,如max-cache-size 5M
    max-cache-size size_no_default;
    check-names string string; // not implemented
    cache-file quoted_string;

    // *notify 在主服務器更新時是否通知輔助服務器(notify)
如果設置為”yes”,則在主服務器區域數據發生變化時,就會向在域的”域名服務器“中列出的服務器和“亦通知”中列出的服務器發送更新通知。這些服務器接受到更新通知后,就會向主服務器發送請求傳輸的消息,然后區域文件得以更新。
    notify notifytype;
    notify-source ( ipv4_address | * ) [ port ( integer | * ) ];
    notify-source-v6 ( ipv6_address | * ) [ port ( integer | * ) ];
    // *also-notify 更新時亦通知下列地址(also-notify),設置發送更新通知的時候,不僅是域名服務器中列出的地址,亦通知此地址列表中的地址。
    also-notify [ port integer ] { ( ipv4_address | ipv6_address ) [ port integer ]; };
    dialup dialuptype;
    // *forward 值有first和only兩項, first則首先轉發到"forwarders"中的服務器,然后自己查詢,only則僅轉發到 "轉發服務器列表"中的服務器,不再自己查詢
    forward ( first | only );
    // *forwarders設置轉發服務器地址列表,語法同acl中的語法.
    forwarders [ port integer ] { ( ipv4_address | ipv6_address ) [ port integer ]; };
    maintain-ixfr-base boolean; // obsolete
    max-ixfr-log-size size; // obsolete
    transfer-source ( ipv4_address | * ) [ port ( integer | * ) ];
    transfer-source-v6 ( ipv6_address | * ) [ port ( integer | * ) ];
    max-transfer-time-in integer;
    max-transfer-time-out integer;
    max-transfer-idle-in integer;
    max-transfer-idle-out integer;
    max-retry-time integer;
    min-retry-time integer;
    max-refresh-time integer;
    min-refresh-time integer;
    sig-validity-interval integer;
    zone-statistics boolean;
};
  • obsolete是已經過時的選項,這里不用考慮,
  • not yet implemented是尚未完成的選項,這里也不用考慮,下面詳細介紹這里面的有用選項

注意,前面打*的為選項

view

view(視)是bind9中提出的一個新概念,在這里可以理解為”從不同的眼光來看dns”,在這里view這個詞可真是取的經典呀,具體而已,就是根據不同的源地址,目的地址,解析請求來判斷該給客戶提供什么樣的解析.其語法如下:

view string optional_class {
    match-clients { address_match_element; ... };
    match-destinations { address_match_element; ... };
    match-recursive-only boolean;
    key string {
        algorithm string;
        secret string;
    };

    zone string optional_class {
        type ( master | slave | stub | hint | forward );
        allow-update { address_match_element; };
        file quoted_string;
        ixfr-base quoted_string; // obsolete
        ixfr-tmp-file quoted_string; // obsolete
        masters [ port integer ] { ( ipv4_address |
            ipv6_address ) [ port integer ] [ key string ]; };
        pubkey integer integer integer quoted_string; // obsolete
        update-policy { ( grant | deny ) string ( name |
            subdomain | wildcard | self ) string rrtypelist; };
        database string;
        check-names string; // not implemented
        allow-query { address_match_element; ... };
        allow-transfer { address_match_element; ... };
        allow-update-forwarding { address_match_element; ... };
        allow-notify { address_match_element; ... };
        notify notifytype;
        notify-source ( ipv4_address | * ) [ port ( integer | * ) ];
        notify-source-v6 ( ipv6_address | * ) [ port ( integer | * ) ];
        also-notify [ port integer ] { ( ipv4_address | ipv6_address ) 
            [ port integer ]; };
        dialup dialuptype;
        forward ( first | only );
        forwarders [ port integer ] { ( ipv4_address |
        ipv6_address ) [ port integer ]; ... };
        maintain-ixfr-base boolean; // obsolete
        max-ixfr-log-size size; // obsolete
        transfer-source ( ipv4_address | * ) [ port ( integer | * ) ];
        transfer-source-v6 ( ipv6_address | * ) [ port (integer | * ) ];
        max-transfer-time-in integer;
        max-transfer-time-out integer;
        max-transfer-idle-in integer;
        max-transfer-idle-out integer;
        max-retry-time integer;
        min-retry-time integer;
        max-refresh-time integer;
        min-refresh-time integer;
        sig-validity-interval integer;
        zone-statistics boolean;
    };
    server {
        bogus boolean;
        provide-ixfr boolean;
        request-ixfr boolean;
        support-ixfr boolean; // obsolete
        transfers integer;
        transfer-format ( many-answers | one-answer );
        keys server_key;
        edns boolean;
    };
    trusted-keys { string integer integer integer
        quoted_string; };
    allow-recursion { address_match_element; ... };
    allow-v6-synthesis { address_match_element; ... };
    sortlist { address_match_element; ... };
    topology { address_match_element; ... }; // not implemented
    auth-nxdomain boolean; // default changed
    minimal-responses boolean;
    recursion boolean;
    provide-ixfr boolean;
    request-ixfr boolean;
    fetch-glue boolean; // obsolete
    rfc2308-type1 boolean; // not yet implemented
    additional-from-auth boolean;
    additional-from-cache boolean;
    query-source querysource4;
    query-source-v6 querysource6;
    cleaning-interval integer;
    min-roots integer; // not implemented
    lame-ttl integer;
    max-ncache-ttl integer;
    max-cache-ttl integer;
    transfer-format ( many-answers | one-answer );
    max-cache-size size_no_default;
    check-names string string; // not implemented
    cache-file quoted_string;
    allow-query { address_match_element; ... };
    allow-transfer { address_match_element; ... };
    allow-update-forwarding { address_match_element; ... };
    allow-notify { address_match_element; ... };
    notify notifytype;
    notify-source ( ipv4_address | * ) [ port ( integer | * ) ];
    notify-source-v6 ( ipv6_address | * ) [ port ( integer | * ) ];
    also-notify [ port integer ] { ( ipv4_address | ipv6_address
    ) [ port integer ]; ... };
    dialup dialuptype;
    forward ( first | only );
    forwarders [ port integer ] { ( ipv4_address | ipv6_address )
    [ port integer ]; ... };
    maintain-ixfr-base boolean; // obsolete
    max-ixfr-log-size size; // obsolete
    transfer-source ( ipv4_address | * ) [ port ( integer | * ) ];
    transfer-source-v6 ( ipv6_address | * ) [ port ( integer | * ) ];
    max-transfer-time-in integer;
    max-transfer-time-out integer;
    max-transfer-idle-in integer;
    max-transfer-idle-out integer;
    max-retry-time integer;
    min-retry-time integer;
    max-refresh-time integer;
    min-refresh-time integer;
    sig-validity-interval integer;
    zone-statistics boolean;
};

其中:

  • match-clients,指的是view對應的源地址,
  • match-destinations指的是view對應的目的地址,
  • match-recursive-only指的是view對應是否僅僅是遞歸請求。

BIND在收到DNS的解析請求后,會首先判斷該請求包的源地址和目標地址,然后根據視區里面的match-clientsmatch-destinationsmatch-recursive-only,判斷是否屬於第一個視區,符合的話就用第一個視區來進行解析,否則就判斷下一個視區。然后再進行解析。如果所有的視區都不能對應,則DNS將返回Query refused的消息。

這樣在防火牆的情況下,就有一個很好的解決辦法了,比如一個典型的網絡結構下,DMZ區全部在防火牆外網口上做的地址映射(DNAT),當DMZ區要訪問本地網絡的時候,單純用傳統的域名解析的話,是無法達到要求的,因為防火牆無法同時又做SNAT和DNAT,比如DMZ地址192.168.0.14映射到外部地址202.196.160.14,而域名服務器解析www.yourdomain.com202.196.160.14,則192.168.0.0/24的網絡將無法訪問www.yourdomain.com,但是當用了VIEW后,你可以對來自該網絡的解析請求將www.yourdomain.com直接解析到192.168.0.14,這樣就可以訪問了。

view里面可以包含zone,優先級是zoneviewoptionszone里面的選項好多和options里面一樣,不過它只是對本zone一樣,同樣view里面的選項也只是對本view有效。

zone是bind的一個重要選項,不過關於zone網上的文章很多,在這里只是補充幾點小技巧:

如何將域名直接解析為www服務器的地址,比如像freshmeat.net那樣直接解析freshmeat.netwww.freshmeat.net,這里可以在域的數據文件里面增加一個這樣的地址記錄:

@ IN A 202.196.160.14

這樣的主機記錄就可以實現了,202.196.160.14www服務器的ip地址。

常見故障釋疑

  1. 在用nslookup查詢域的時候出現如下錯誤:Can't find server name for address *.*.*.*: Non-existent domain,這種情況是沒有對域名服務器本身做反向地址解析造成的,給域名服務器增加一條反向地址解析就可以了。
  2. 在用nslookup時出現如下錯誤:DNS request timed out.timeout was 2 seconds.DNS request timed out.這種情況一般是在DNS進行遞歸查詢的時候,超時造成的,可能是由於網絡速度問題,也可能是路由等其他問題,或者對方域名服務器沒有響應造成的.
  3. 在用nslookup時出現如下錯誤:xxx dns.cbchen.com can't find www.ite.com: Non-existent domain,這種情況一般是域中沒有該地址記錄或沒有別名記錄.
  4. 在用nslookup時出現如下錯誤:***.server failed一般是配置問題,請檢測配置,或者是輔助域無法從主域中得到數據,再請求輔助域的時候會出現這種故障.

BIND的有用的網站:

強烈推薦BIND9解壓目錄下的/doc/arm管理員手冊
其他第三方DNS服務器軟件:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM