【问题标题】:Bind9 DNS Zone Transfer Script - Bash script to avoid duplicatesBind9 DNS 区域传输脚本 - 避免重复的 Bash 脚本
【发布时间】:2010-09-20 13:26:28
【问题描述】:

我创建了一个 bash 脚本来在我的主 DNS 服务器和辅助 DNS 服务器之间传输我的区域。 它从主要区域下载我的区域列表并检查任何新区域,然后下载这些区域文件并将其插入区域目录和 .local 文件中以进行绑定。

我遇到的问题是,如果区域文件不存在,无论此配置是否已存在,脚本都会将详细信息输入 .local。

谁能帮我区分已经存在的区域并简单地下载区域文件。 我在下面粘贴了我的脚本,如果有人对它的工作原理有任何疑问,请随时提问。 (有人可以包装代码吗,它在我尝试的任何浏览器中都无法正常工作!)

#!/bin/sh
NAMED="/etc/bind/named.conf.local"
TMPNAMED="/tmp/zns-441245.temp"
TMPZONEFILE="/tmp/zones.txt"
TMP="/tmp/zns-732.temp"
ZONELOCATION="/var/cache/bind"
IGNORE=`cat ignore.txt`

logger DNS Update script running...
echo -n "Checking for new named.conf... "
wget -q http://91.121.75.205:10801/named/named.conf -O $TMPNAMED
if [ -e $TMPNAMED ]
then
        echo "done."
else
        echo "no new data!"
        exit
fi
echo -n "Generating zone names... "

grep "^zone" $TMPNAMED | cut -d " " -f "2" | cut -d "\"" -f 2 > $TMPZONEFILE
sed '1,5d' $TMPZONEFILE > $TMP
mv $TMP $TMPZONEFILE

echo "done. ("$TMPZONEFILE")"

echo "Generating zone info... "

grep -vf ignore.txt $TMPZONEFILE | while read ZONE; do

echo -n "Checking for $ZONELOCATION/$ZONE.db "

 if [ -e $ZONELOCATION/$ZONE.db ]
 then
  echo "[ exists ]"
 else
  export updates="yes"
  echo "[ doesn't exist ]"
  echo "New zone available ($ZONE)... "
  echo "zone \"$ZONE\" {
  type slave;
  file \"$ZONELOCATION/$ZONE.db\";
  masters { 91.121.75.205; };
  allow-notify { 91.121.75.205; };
  };" >> $NAMED
 fi

 done

 echo "Updating Bind configuration... "
 /etc/init.d/bind9 restart

rm $TMPZONEFILE
rm $TMPNAMED

【问题讨论】:

  • 你的问题被标记为[bash],但你的shebang却是#!/bin/sh。是哪个?

标签: bash dns bind transfer zone


【解决方案1】:

一个问题可能是您的wget 会创建一个文件,而不管是否有源文件,因此检查是否存在总是正确的。

if [ -s $TMPNAMED ]
then
    echo "done."    # file exists AND has data
else
    echo "no new data!" 
    exit
fi

将测试它是否为空或不存在,如果是则退出。这也可能是您的if [ -e $ZONELOCATION/$ZONE.db ] 的问题。

sedawk 可以在一行中完成所有这些操作:

grep "^zone" $TMPNAMED | cut -d " " -f "2" | cut -d "\"" -f 2 > $TMPZONEFILE
sed '1,5d' $TMPZONEFILE > $TMP

但我需要查看一些示例数据才能提供解决方案。

简化引用:

echo "done. ($TMPZONEFILE)"

您没有使用IGNORE 变量或updates 变量。我看不出有任何出口的理由。此外,如果您在其他地方依赖它,那么一旦while 循环退出,它的值将无法生存,因为将某些东西(在这种情况下为grep)传递到while 会设置一个子shell。执行以下操作之一可能会更好:

重击:

while ...
do
    ...
done <(grep -vf ignore.txt $TMPZONEFILE)

嘘:

grep -vf ignore.txt $TMPZONEFILE > tmp.out
while ...
do
    ...
done < tmp.out

顺便说一下,我建议使用mktemptempfile 创建临时文件。

这可能更具可读性,并且允许您包含引号而不必转义它们:

cat << EOF >> "$NAMED"
zone "$ZONE" {
  type slave;
  file "$ZONELOCATION/$ZONE.db";
  masters { 91.121.75.205; };
  allow-notify { 91.121.75.205; };
  };
EOF

引用包含文件名的变量总是一个好习惯。

【讨论】:

  • 这是非常解释性的,我将不得不通过它并测试你概述的方法,看看它是如何进行的。我对 linux 中的脚本编写非常陌生,除了我必须做的事情之外,我从来没有真正学到过任何东西。
【解决方案2】:

如果您在同步named.conf 时遇到了所有麻烦,那么您不妨 rsync 整个配置包括区域文件,而不必费心在主要和次要之间使用区域传输。

从服务器使用 AXFR 绝不是强制性的。如果您对某个区域的所有服务器拥有管理控制权,那么将它们都视为主服务器是完全可以接受的。

【讨论】:

  • 这是一个非常好的主意,我什至没有考虑过。我将研究如何设置此方法。我唯一的区别是绑定的区域文件的位置在两台服务器上都不相同,所以我需要使用某种形式的脚本来更改它?
  • 你可以只添加一个符号链接,使你的主 master 的 named.conf 中的(缺失的)目录指向真正的目录。
猜你喜欢
  • 2012-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-17
  • 1970-01-01
  • 2020-11-03
  • 2014-06-02
相关资源
最近更新 更多