首页 > 学技术 > 技术网文 > DNS服务器 > 正文

[原创] [原創] 簡單建立 dns 的 shell script


来源 chinaunix.net 酷勤网整理

常碰到一些朋友抱怨說 linux 的  dns 很難設。
但經我個人觀察,90% 都是打錯字或格式疏忽而已~~~~  ^_^

這裡我寫了隻 shell script ,可以幫助建立簡單的正解及反解檔,
然後將剩下的"簡單"的部份,則自己來修改了...

download:
http://www.study-area.org/linux/src/sample_dns.sh.tgz

最後版原始碼:
#!/bin/bash

set -u

# purpose: make a sample dns for RedHat like system
# author: netman<netman@study-area.org>
# date: 2003-12-12
# version: v0.6

#-- CAVEATE --#
# 1) script has been tested only on RedHat 8.x/9.0 platform.
# 2) needs root privilege to run.
# 3) only one forward zone and one reverse zone will be created.
#       if no specified zone names are given, script will assume to
#       use the current DNS domain(using text.cxm instead if not found) for
#       forward zone's name, and the Class-C ipv4 subnet of current IP for
#       reverse zone's name.
# 4) the script can NOT determine whether you have the proper delegation,
#       you should manually delete ANY non-authorized zone settings.
# 5) only followint Resource Record will be create by this script:
#       * SOA (both forward & reverse)
#       * NS (both forward & reverse)
#       * MX (forward only)
#       * A (forward only)
#       * CNAME (www & ftp, forward only)
#       * PTR (reverse only)
# 6) a backup for named.conf and db directory will be made to /root/backup.
#       backup will be performed once during the first running only,
#       unless -b options is given.
# 7) absolutely NO WARRANTY while running this script.

#-- CHANGE LOG --#
# 1) 2003-12-05 v0.1 by netman
#       * first version.
# 2) 2003-12-06 v0.2 by netman
#       * improve options selection, and add:
#               -f, -r, -n
# 3) 2003-12-06 v0.3 by netman
#       * improve name server hostname determination
# 4) 2003-12-07 v0.4 by netman
#       * re-organize options dtermination, and add:
#               -c, -d, -e
# 5) 2003-12-10 v0.5 by netman
#       * bug-fixed to solve:
#               - ip alias address: have primary only
#               - no dns domain: set to test.cxm
#               - no hostname: set to ns1
# 6) 2003-12-12 v0.6 by netman
#       * bug-fixed to solve:
#               - backup dir detection


#-- setting default values --#
wtty=$(ps | grep $$ | tail -n 1 | awk '{print $2}')
interact=
test=
to_file=
backup=
update=

#-- print message --#
function print_usage {
        echo "-------------------------------------------------------------"
        echo "Script Name:"
        echo -e "\t${0##*/}"
        echo "Usage:"
        echo -e "\t${0##*/} [-h]"
        echo -en "\t${0##*/} [-g|-t] [-u] [-b] [-i|"
        echo -n "[-f fwd_zone] [-r rev_zone] [-n name_server]]"
        echo " [-c conf_file] [-d db_dir] [-e ether_if]"
        echo "Options:"
        echo -e "\t-h\tprint this help"
        echo -e "\t-g\trun the script"
        echo -e "\t-i\tspecify own names interactively"
        echo -e "\t-f\tname of forward zone"
        echo -e "\t-r\tname of reverse zone"
        echo -e "\t-n\tname of name-server"
        echo -e "\t-t\ttest only"
        echo -e "\t-u\tforce update db(s)"
        echo -e "\t-b\tforce backup"
        echo -e "\t-c\tpath of named.conf"
        echo -e "\t-d\tpath of named database directory"
        echo -e "\t-e\tethernet interface"
        echo "Example:"
        echo -e "\t# $0 -tu"
        echo -e "\t# $0 -g -f test.cxm -r 3.2.1.in-addr.arpa -n ns.test.cxm"
        echo "-------------------------------------------------------------"
        exit 0
}

#-- getting options --#
while getopts ":hgif:r:n:tubc:d:e:" opt; do
        case "$opt" in
                h) print_usage ;;
                g) : ;;
                f) fwd_zone=$OPTARG ;;
                r) rev_zone=$OPTARG ;;
                n) ns_host=$OPTARG ;;
                i) interact=true ;;
                t) test=true; to_file=/dev/$wtty ;;
                u) update=true ;;
                b) backup=true ;;
                c) named_conf=$OPTARG ;;
                d) db_dir=$OPTARG ;;
                e) host_if=$OPTARG ;;
                \?) print_usage ;;
        esac
done

#-- setting named info --#
named_conf=${named_conf:-/etc/named.conf}
db_dir=${db_dir:-/var/named}
bak_dir=${bak_dir:-/root/backup}

#-- setting zone info --#
fwd_zone=$(hostname -d)
fwd_zone=${fwd_zone:-test.cxm}
host_if=${host_if:-eth0}
host_ip=$(/sbin/ifconfig | grep -A1 $host_if[^:] | awk '/inet/{print $2}' | sed 's/^.*://')
host_ip=${host_ip:-192.168.1.1}
rev_fix=in-addr.arpa
rev_zone=${rev_zone:-$(echo ${host_ip%.*} | awk -F. '{print $3"."$2"."$1}').$rev_fix}
host_name=$(hostname -s)
host_name=${host_name:-ns1}
ns_host=${ns_host:-$host_name.$fwd_zone}
ns_ptr=${host_ip##*.}
serial_nu=$(date +%Y%m%d)01
opt_ttl=86400

#-- setting functions --#
function print_choice {
        echo
        echo "Please select one:"
        echo "h): to print HELP."
        echo "t): to TEST the script only."
        echo "q): to QUIT."
        echo -n 'Your choice? '
        read action
        case $action in
                h|H) print_usage ;;
                t|T) exec $0 -t ;;
                q|Q) echo; exit 0 ;;
                *) print_choice ;;
        esac
}

[ $# -eq 0 ] && {
        echo
        echo "${0##*/}: Error: missing argument."
        print_choice
}

function get_zone {
        echo
        echo "Which name you would like to assign to the $1 zone? "
        echo "(press Enter for '$2', or press 'n' for none): "
        read z_name
        echo $z_name | grep -q ' ' && {
                echo "Error: no space allowed in zone name."
                echo "  Press ctrl-c to abort or type again:"
                get_zone $1 $2
        }
        if [ -z "$z_name" ]; then
                z_name=$2
        elif [ "$z_name" = "n" ]; then
                z_name=
        fi
}

function run_intact {
        get_zone forward $fwd_zone
        fwd_zone=${z_name%.}
        get_zone reverse $rev_zone
        rev_zone=${z_name%.}
        echo
        echo "Give the FQDN of your name-server"
        echo "(or press Enter for system defaults '$ns_host'): "
        read _ns_host
        ns_host=${_ns_host:-$ns_host}
}

#-- prepare target dir --#
function pre_dir {
  for dir in $@; do
        if [ -e $dir -a ! -d $dir ]; then
                echo "${0##*/}: Error: $dir existed but is not a directory."
                exit 1
        else
                mkdir -p $dir || {
                        echo "${0##*/}: Error: Can't create dir: $dir !"
                        exit 1
                }
        fi
  done
}

[ "$test" = true ] || pre_dir ${bak_dir} ${named_conf%/*} $db_dir

#-- test permission --#
for target in $named_conf $db_dir $bak_dir; do
        [ -e $target ] || continue
        [ -w $target ] || {
                echo "${0##*/}: Error: you have no write perssion to $target"
                exit 2
        }
done

#-- make backup --#
function run_bak {
        [ -e $source -a -d $bak_dir ] && {
                cp -a $source $bak_dir || {
                        echo "${0##*/}: Error:can't make backup for $source "
                        exit 3
                }
        }
}
function do_backup {
  for source in $named_conf $db_dir; do
        [ "$backup" = true ] && op=';' || op='||'
        eval test -e $bak_dir/${source##*/} $op run_bak
  done
}

#-- create default settings if missing --#
function create_raw {

  test -e $named_conf || {
        echo "${0##*/}: WARNING: $named_conf seems missing!"
        echo -n "Do you want me to create it for you? (y/N): "
        read YN
        echo $YN | grep -Eq 'Y|y' || return 0

  cat > $named_conf <<END
// generated by ${0##*/} on $(date)

options {
        directory "$db_dir";
};
zone "." IN {
        type hint;
        file "named.ca";
};

zone "localhost" IN {
        type master;
        file "localhost.zone";
        allow-update { none; };
};

zone "0.0.127.in-addr.arpa" IN {
        type master;
        file "named.local";
        allow-update { none; };
};

END


test -e $db_dir/named.ca || {
  cat > $db_dir/named.ca <<END
;       This file holds the information on root name servers needed to
;       initialize cache of Internet domain name servers
;       (e.g. reference this file in the "cache  .  <file>"
;       configuration file of BIND domain name servers).
;
;       This file is made available by InterNIC
;       under anonymous FTP as
;           file                /domain/named.cache
;           on server           FTP.INTERNIC.NET
;
;       last update:    Nov 5, 2002
;       related version of root zone:   2002110501
;
;
.                        3600000  IN  NS    A.ROOT-SERVERS.NET.
A.ROOT-SERVERS.NET.      3600000      A     198.41.0.4
.                        3600000      NS    B.ROOT-SERVERS.NET.
B.ROOT-SERVERS.NET.      3600000      A     128.9.0.107
.                        3600000      NS    C.ROOT-SERVERS.NET.
C.ROOT-SERVERS.NET.      3600000      A     192.33.4.12
.                        3600000      NS    D.ROOT-SERVERS.NET.
D.ROOT-SERVERS.NET.      3600000      A     128.8.10.90
.                        3600000      NS    E.ROOT-SERVERS.NET.
E.ROOT-SERVERS.NET.      3600000      A     192.203.230.10
.                        3600000      NS    F.ROOT-SERVERS.NET.
F.ROOT-SERVERS.NET.      3600000      A     192.5.5.241
.                        3600000      NS    G.ROOT-SERVERS.NET.
G.ROOT-SERVERS.NET.      3600000      A     192.112.36.4
.                        3600000      NS    H.ROOT-SERVERS.NET.
H.ROOT-SERVERS.NET.      3600000      A     128.63.2.53
.                        3600000      NS    I.ROOT-SERVERS.NET.
I.ROOT-SERVERS.NET.      3600000      A     192.36.148.17
.                        3600000      NS    J.ROOT-SERVERS.NET.
J.ROOT-SERVERS.NET.      3600000      A     192.58.128.30
.                        3600000      NS    K.ROOT-SERVERS.NET.
K.ROOT-SERVERS.NET.      3600000      A     193.0.14.129
.                        3600000      NS    L.ROOT-SERVERS.NET.
L.ROOT-SERVERS.NET.      3600000      A     198.32.64.12
.                        3600000      NS    M.ROOT-SERVERS.NET.
M.ROOT-SERVERS.NET.      3600000      A     202.12.27.33
; End of File
END
}

test -e $db_dir/localhost.zone || {
  cat > $db_dir/localhost.zone <<END
\$TTL   86400
\$ORIGIN localhost.
@                       1D IN SOA       @ root (
                                        42              ; serial (d. adams)
                                        3H              ; refresh
                                        15M             ; retry
                                        1W              ; expiry
                                        1D )            ; minimum

                        1D IN NS        @
                        1D IN A         127.0.0.1

END
}
test -e $db_dir/named.local || {
  cat > $db_dir/named.local <<END
\$TTL   86400
@       IN      SOA     localhost. root.localhost.  (
                                      1997022700 ; Serial
                                      28800      ; Refresh
                                      14400      ; Retry
                                      3600000    ; Expire
                                      86400 )    ; Minimum
              IN      NS      localhost.

1       IN      PTR     localhost.

END
}

} # end of first test
} # end of function

#-- check named.conf --#
function check_conf {
  war_msg="${0##*/}: WARNING: \n\t$named_conf seems up-to-date. Nothing will be done. "
  adv_msg="If you really want to continue, you can:"
  for zone in $@; do
        [ -e $named_conf ] && grep -Eq "$zone" $named_conf && {
                echo -e "$war_msg"
                echo "$adv_msg"
                echo "1) delete '$fwd_zone' & '$rev_zone' sections from $named_conf."
                echo "   OR:"
                echo "2) run '${0##*/} -u' to override db files in $db_dir."
                echo -e "   Note: this option will not modify $named_conf."
                exit 4
        }
  done
}

#-- modify named.conf --#
function mod_conf {
  for zone in $@; do
        [ "$to_file" ] && {
                echo
                echo "Content will be written to $named_conf :"
                echo "----start-------------------------------------"
        }
        cat >> ${to_file:-$named_conf} <<END
zone "$zone" IN {
        type master;
        file "$zone";
};

END
        [ "$to_file" ] && {
                echo "----end---------------------------------------"
        }
  done
}

#-- modify rr db --#
function mod_rr {
  ns_host=${ns_host%.}
  echo $ns_host | grep -q '\.' || ns_host=$ns_host.$fwd_zone
  [ "$fwd_zone" ] && {
        [ "$to_file" ] && {
                echo
                echo "Content will be written to $db_dir/$fwd_zone :"
                echo "----start-------------------------------------"
        }
        cat > ${to_file:-$db_dir/$fwd_zone} <<END
\$TTL    $opt_ttl
@  IN  SOA $ns_host. root.$ns_host. (
                                      $serial_nu ; Serial
                                      28800      ; Refresh
                                      14400      ; Retry
                                      604800     ; Expire
                                      86400 )    ; Minimum
@   IN  NS  $ns_host.
@   IN  MX  10 $ns_host.

${ns_host%%.*}  IN A            $host_ip
www     IN CNAME        $ns_host.
ftp     IN CNAME        $ns_host.

END
        [ "$to_file" ] && {
                echo "----end---------------------------------------"
        }
  }

  [ "$rev_zone" ] && {
        [ "$to_file" ] && {
                echo
                echo "Content will be written to $db_dir/$rev_zone :"
                echo "----start-------------------------------------"
        }
        cat > ${to_file:-$db_dir/$rev_zone} <<END
\$TTL    $opt_ttl
@  IN  SOA $ns_host. root.$ns_host. (
                                      $serial_nu ; Serial
                                      28800      ; Refresh
                                      14400      ; Retry
                                      604800     ; Expire
                                      86400 )    ; Minimum
@   IN  NS  $ns_host.

$ns_ptr  IN  PTR $ns_host.

END
        [ "$to_file" ] && {
                echo "----end---------------------------------------"
        }
  } # end of test
} # end of function

#-- main script --#
do_backup
create_raw
[ "$interact" = true ] && run_intact
[ "$update" = true ] || { check_conf $fwd_zone $rev_zone; mod_conf $fwd_zone $rev_zone; }
mod_rr
[ "$test" = true ] || {
        echo "${0##*/}: Okay, all done!"
        echo "Don't forget to restart your named daemon and check log messages."
        echo "Enjoy!"
}

exit 0


[ 本帖最后由 網中人 于 2006-5-15 12:56 编辑 ]



 amanl 回复于:2003-12-06 08:32:43

好。帮你顶


 網中人 回复于:2003-12-06 19:53:22

更新:
# 2) 2003-12-06 v0.2 by netman
#       * improve options selection
# 3) 2003-12-06 v0.3 by netman
#     * improve name server hostname determination


download:
http://www.study-area.org/linux/src/sample_dns.sh.tgz

diff 結果(v0.1 - v0.3):
66,7c6,7

< # date:       2003-12-06
< # version: v0.3
---
>; # date:       2003-12-05
>; # version: v.0.1
32c32
< # 1) 2003-12-05 v0.1 by netman
---
>; # 1) 2003-12-05 v0.01 by netman
34,37d33
< # 2) 2003-12-06 v0.2 by netman
< #     * improve options selection
< # 3) 2003-12-06 v0.3 by netman
< #     * improve name server hostname determination
39,43c35
<
< interact=
< to_file=
< backup=
< update=
---
>; options=hrstbf
48a41,43
>; to_file=
>; backup=
>; update=
57d51
< ns_host=$(hostname -s).$fwd_zone
66,69d59
<       echo "Usage:"
<       echo -e "\t${0##*/} [-h]"
<       echo -en "\t${0##*/} [-g|-t] [-u] [-b] [-i|"
<       echo "[-f fwd_zone] [-r rev_zone] [-n name_server]]"
72,76c62,63
<       echo -e "\t-g\trun the script"
<       echo -e "\t-i\tspecify own names interactively"
<       echo -e "\t-f\tname of forward zone"
<       echo -e "\t-r\tname of reverse zone"
<       echo -e "\t-n\tname of name-server"
---
>;       echo -e "\t-r\trun the script with default values"
>;       echo -e "\t-s\tspecify your own zone names"
78d64
<       echo -e "\t-u\tforce update db(s)"
79a66
>;       echo -e "\t-f\tforce update db(s)"
81,82c68
<       echo -e "\t# $0 -tu"
<       echo -e "\t# $0 -g -f test.cxm -r 3.2.1.in-addr.arpa -n ns.test.cxm"
---
>;       echo -e "\troot_shell# $0 -tu"
103c89
< [ $# -eq 0 ] && {
---
>; echo $@ | grep -q "[^$options-]" || [ $# -eq 0 ] && {
105c91
<       echo "${0##*/}: Error: missing argument."
---
>;       echo "${0##*/}: missing argument or invalid options."
112c98
<       echo "(press Enter for '$2', or press 'n' for none): "
---
>;       echo "(or press Enter for none): "
117c103
<               get_zone $1 $2
---
>;               get_zone $1
119,123d104
<       if [ -z "$z_name" ]; then
<               z_name=$2
<       elif [ "$z_name" = "n" ]; then
<               z_name=
<       fi
126,127c107,108
< function run_intact {
<       get_zone forward $fwd_zone
---
>; function run_spec {
>;       get_zone forward
129c110
<       get_zone reverse $rev_zone
---
>;       get_zone reverse
133,135c114,115
<       echo "(or press Enter for system defaults '$ns_host'): "
<       read _ns_host
<       ns_host=${_ns_host:-$ns_host}
---
>;       echo "(or press Enter for system defaults): "
>;       read ns_host
293c273
<               echo "1) delete '$fwd_zone' & '$rev_zone' sections from $named_conf."
---
>;               echo "1) delete '$zone' sections from $named_conf."
295c275
<               echo "2) run '${0##*/} -u' to override db files in $db_dir."
---
>;               echo "2) run '${0##*/} -f' to override db files in $db_dir."
306,308c286
<               echo
<               echo "Content will be written to $named_conf :"
<               echo "----start-------------------------------------"
---
>;               echo "---->; Content will be written to $named_conf :"
317,319d294
<       [ "$to_file" ] && {
<               echo "----end---------------------------------------"
<       }
324a300
>;   ns_host=${ns_host:-$(hostname -s).$fwd_zone}
326d301
<   echo $ns_host | grep -q '\.' || ns_host=$ns_host.$fwd_zone
329,331c304
<               echo
<               echo "Content will be written to $db_dir/$fwd_zone :"
<               echo "----start-------------------------------------"
---
>;               echo "---->; Content will be written to $db_dir/$fwd_zone :"
349,351d321
<       [ "$to_file" ] && {
<               echo "----end---------------------------------------"
<       }
356,358c326
<               echo
<               echo "Content will be written to $db_dir/$rev_zone :"
<               echo "----start-------------------------------------"
---
>;               echo "---->; Content will be written to $db_dir/$rev_zone :"
373,375d340
<       [ "$to_file" ] && {
<               echo "----end---------------------------------------"
<       }
381c346
< while getopts ":hgif:r:n:tub" opt; do
---
>; while getopts ":$options" opt; do
384,388c349,350
<               g) : ;;
<               f) fwd_zone=$OPTARG ;;
<               r) rev_zone=$OPTARG ;;
<               n) ns_host=$OPTARG ;;
<               i) interact=true ;;
---
>;               r) : ;;
>;               s) run_spec ;;
390d351
<               u) update=true ;;
391a353
>;               f) update=true ;;
398,399c360,361
< [ "$interact" = true ] && run_intact
< [ "$update" = true ] || { check_conf $fwd_zone $rev_zone; mod_conf $fwd_zone $rev_zone; }
---
>;
>; test "$update" = true || { check_conf $fwd_zone $rev_zone; mod_conf $fwd_zone $rev_zone; }
401c363
< [ "$to_file" ] || {
---
>; test "$to_file" || {



 網中人 回复于:2003-12-12 21:26:58

#-- CHANGE LOG --#

# 1) 2003-12-05 v0.1 by netman
#       * first version.
# 2) 2003-12-06 v0.2 by netman
#       * improve options selection, and add:
#               -f, -r, -n
# 3) 2003-12-06 v0.3 by netman
#       * improve name server hostname determination
# 4) 2003-12-07 v0.4 by netman
#       * re-organize options dtermination, and add:
#               -c, -d, -e
# 5) 2003-12-10 v0.5 by netman
#       * bug-fixed to solve:
#               - ip alias address: have primary only
#               - no dns domain: set to test.cxm
#               - no hostname: set to ns1
# 6) 2003-12-12 v0.6 by netman
#       * bug-fixed to solve:
#               - backup dir detection



 supereyes 回复于:2003-12-13 13:32:17

好文!


 sunnycn 回复于:2004-11-03 13:17:05

k,很好用也。我试了一下。一定要好好的看看哟。


 redandblack007 回复于:2006-01-24 15:58:24

支持奉献


 fugangyun 回复于:2006-01-24 16:53:28

问一下楼主,这个脚本同时支持的BIND8  and 9?

我的DNS服务器,以前的DNS管理员只建立了正解,反解从来没更新过,这脚本能将正解转换成反解吗?

生产机,我不敢测试!

行的话,就太感谢你了!


 網中人 回复于:2006-01-24 23:45:23

呵...
1) 千萬別在 production 機器跑!
2) 其實 script 是幫助那些常"打錯字"的朋友, 若細心, 可以不必參考.
3) script 只是給個 sample, 有很多還要改. 
4) 還是要懂得原理才能改的哦.
5) 沒照顧到 chroot 環境, 要自己改哦.
6) bind8 我不清楚, 我當初是在 RH9 上面開發的, 所以針對  bind9.
7) 歡迎改善!  ^_^


 bitterness 回复于:2006-12-12 15:17:21

太強了,佩服佩服


 marion 回复于:2007-03-02 23:31:52

高人,学习中.


 yuhuohu 回复于:2007-03-20 16:00:58

佩服 哥们真厉害


 ljily000 回复于:2007-04-13 10:31:44

Good!


 xiaodong 回复于:2007-04-15 00:16:15

非常感谢楼主的贡献!!!!!




原文链接:http://bbs.chinaunix.net/viewthread.php?tid=217331
转载请注明作者名及原文出处



收藏本页到: