我使用 1 台运行 cPanel/WHM 的服务器和 4 台仅运行 cPanel DNS 的服务器(ns1-ns4)运行自己的 DNS 集群。
我刚刚添加了第 4 个 DNS 服务器(ns4.domain.com),但问题是我当前的所有 200 个区域文件都不包含新添加的名称服务器。
因此,即使我的所有 4 个名称服务器都具有适当的区域文件来为我的所有域提供 DNS 查询,但每个区域文件仅列出我的 3 个名称服务器,如下所示:
example.com. 86400 IN SOA ns1.domain.com. domains.domain.com. (
2013081402 ;Serial Number
86400 ;refresh
7200 ;retry
2419200 ;expire
86400 ;minimum
)
example.com. 86400 IN NS ns1.domain.com.
example.com. 86400 IN NS ns2.domain.com.
example.com. 86400 IN NS ns3.domain.com.
example.com. 3600 IN A 11.22.33.44
localhost 3600 IN A 127.0.0.1
example.com. 14400 IN MX 0 example.com.
mail 14400 IN CNAME example.com.
www 14400 IN CNAME example.com.
ftp 14400 IN CNAME example.com.
我希望能够批量编辑/添加我的新名称服务器 (ns4.domain.com) 到 /var/named/*.db 中的所有区域文件,因此所有区域文件都应具有如下 NS 记录
example.com. 86400 IN NS ns1.domain.com.
example.com. 86400 IN NS ns2.domain.com.
example.com. 86400 IN NS ns3.domain.com.
example.com. 86400 IN NS ns4.domain.com.
唯一的问题是我不确定如何将这行文本添加到所有区域文件中。我知道如何替换,并正在考虑按照以下方法操作,但我认为这不会起作用,因为没有新行。
replace "example.com. 86400 IN NS ns3.domain.com." "example.com. 86400 IN NS ns3.domain.com.
example.com. 86400 IN NS ns4.domain.com." -- /var/named/*.db
答案1
区域文件中资源记录的顺序大多是任意的,只需将新记录附加在末尾即可。
但是不要忘记更新序列号!
答案2
这将以某种方式操作区域文件,使其添加正确的序列号并附加正确的名称服务器。
您需要为每个区域文件调用该脚本。您可以使用find
glob 的 shell 循环来执行此操作。
这依赖于序列号的格式,即行中包含“;序列号”。它还要求域名被声明为第一行的第一个单词。最后,它要求在“$LASTNS”中声明的名称服务器在那里。不过,您可以在运行脚本之前更改该值。
哦,对已由该脚本操作的区域文件运行此脚本会破坏区域文件。有一个简单的测试可以修复此问题,但需要您自己解决。
#!/bin/bash
set -e
LASTNS="ns3.domain.com."
NEWNS="ns4.domain.com."
WORKDIR=$(mktemp -d /tmp/addns.XXXXXXXX)
function cleanup
{
if [ -n "${WORKDIR}" -a -d "${WORKDIR}" ]; then
rm -fr "${WORKDIR}"
fi
}
function new_serial_no
{
local old=$1
local olddate="${old:0:8}"
local newdate=$(date "+%Y%m%d")
## Figure out if the revision number needs to be bumped or if we override
## with a new date.
if [[ $olddate == $newdate ]]; then
newdate="${newdate}"$(printf "%02d" "$((${old:8:2}+1))")
echo $newdate
else
echo ${newdate}00
fi
}
trap cleanup EXIT
ZONEFILE=$1
if [ -z "${ZONEFILE}" -o ! -f "${ZONEFILE}" ]; then
echo "Requires a zonefile as input" >&2
exit 1
fi
DOMAIN=$(head -n1 "${ZONEFILE}" | cut -d " " -f1)
SERIAL=$(grep ";Serial Number" "${ZONEFILE}" | egrep -o "[0-9]+")
NEWSERIAL=""
if [ -z "${DOMAIN}" -o -z "${SERIAL}" ]; then
echo "Could not find matching domain or serial number" >&2
exit 1
fi
NEWSERIAL=$(new_serial_no "${SERIAL}")
if [ -z "${NEWSERIAL}" ]; then
echo "Could not determine new serial number" >&2
exit 1
fi
## Have enough now to manipulate the file
cp -p "${ZONEFILE}" "${WORKDIR}/zone"
sed -ie "/${LASTNS}/a${DOMAIN} 86400 IN NS ${NEWNS}" "${WORKDIR}/zone"
sed -ie "s/${SERIAL}/${NEWSERIAL}/" "${WORKDIR}/zone"
NEWZONE=$(mktemp -u "${ZONEFILE}.XXXXXXX")
cp -p "${WORKDIR}/zone" "${NEWZONE}"
mv "${NEWZONE}" "${ZONEFILE}"