常碰到一些朋友抱怨說 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
非常感谢楼主的贡献!!!!!
|