all-in-one 4.2 (ปรับปรุง zone generator script)

 

ปรับสคริปต์นิดหน่อย

# vi /usr/local/sbin/d.bind-genzone
#!/bin/bash
# GENERATE ZONE FILE [AND REVERSE ZONE FILE IF ADD OPTION -b]
# READ DATA FROM DATAFILE IN FORMAT
#     zone:ZONENAME:IP_D:CNAME1 CNAME2 ...:SERIAL:IP_ABC
#     ns:NAMESERVER1 NAMESERVER2
#     mx:MAILSERVER1,RR1 MAILSERVER2,RR2
#     IP_D:NAME CNAME1 CNAME2 ...
#     ...
# EXAMPLE:
#     zone:example.com:1:server1 ns1 mail www ftp:43:192.168.1
#     ns:ns1 ns2
#     mx:mail,10 mail2,20
#     2:ns2
#     101:work1
#     102:work2
#     ...

#GLOBAL VAR
TTL=86400
BINDUSER="bind"
BINDGROUP="bind"

#FUNTION
function usage {
    cat << EOF

Script to generate zone file and reverse zone file
USAGE: $0 [-b] DATAFILE
OPTIONS:
  -b = both, generate both forward and reverse zone file,
       only generate forward zone file, if omitted
ARGUMENT:
  DATAFILE : datafile in format:-
     zone:ZONENAME:IP_D:CNAME1 CNAME2 ...:SERIAL:IP_ABC
    [ns:NAMESERVER1 NAMESERVER2]
    [mx:MAILSERVER1,RR1 MAILSERVER2,RR2]
     IP_D:NAME CNAME1 CNAME2 ... 
     ...
  EXAMPLE OF DATAFILE:
  example1:
     zone:example.com:1:server1 ns1 mail www ftp:43:192.168.1
     ns:ns1 ns2
     mx:mail,10 mail2,20
     2:ns2
     101:work1
     102:work2
     192.168.5.1:router
     ...
  example2:
     zone:ns2.example.org:2::44:192.168.1
     ns:ns1 ns2

EOF
}

function gen_header {
    Z=$1
    S=$2
    cat << EOF
\$TTL   $TTL
@       IN      SOA $Z. root.$Z. (
                        $S      ; serial (d. adams)
                        3H      ; refresh
                        15M     ; retry
                        1W      ; expiry
                        1D )    ; minimum
EOF
}

function gen_ns {
    H=$1
    cat << EOF
@               NS      $H
EOF
}

function gen_mx {
    H=$1
    R=$2
    cat << EOF
@               MX      $R $H
EOF
}

function gen_name {
    N=$1
    I=$2
    cat << EOF
$N      IN      A       $I
EOF
}

function gen_ptr {
    I=$1
    N=$2
    cat << EOF
$I      IN      PTR     $N.$ZONENAME.
EOF
}

function gen_cname {
    C=$1
    N=$2
    cat << EOF
$C      IN      CNAME   $N.
EOF
}
function get_ip {
    I1="$1."      #input ip     
    I2="$2."      #$IP_ABC      
    A=$(echo "$I1" | cut -d. -f1)
    B=$(echo "$I1" | cut -d. -f2)
    C=$(echo "$I1" | cut -d. -f3)
    D=$(echo "$I1" | cut -d. -f4)
    W=$(echo "$I2" | cut -d. -f1)
    X=$(echo "$I2" | cut -d. -f2)
    Y=$(echo "$I2" | cut -d. -f3)
    Z=$(echo "$I2" | cut -d. -f4)
    if [ ! "$B" ]; then
        echo "$W.$X.$Y.$A"; return
    elif [ ! "$C" ]; then
        echo "$W.$X.$A.$B"; return
    elif [ ! "$D" ]; then
        echo "$W.$A.$B.$C"; return
    else
        echo "$I1"      
    fi
}

#BEGIN MAIN
DATAFILE=""
WITHREVERSE=""

while getopts "b" ARGS; do
    case "$ARGS" in
        b) WITHREVERSE="true"; shift $(($OPTIND - 1)) ;;
    esac
done

DATAFILE=$1
shift
while getopts "b" ARGS; do
    case "$ARGS" in
        b) WITHREVERSE="true"; shift $(($OPTIND - 1)) ;;
    esac
done

if [ ! "$DATAFILE" ] || [ ! -f "$DATAFILE" ]; then
    usage
    exit 1
fi

ZONENAME=""
SERIAL=""
IP_ABC=""
ZONEFILE=""
REVERSEFILE=""

cat $DATAFILE | grep -v "#" | while read DATA; do
    #ZONE HEADER
    if [ "${DATA:0:5}" == "zone:" ]; then
        ZONENAME=$(echo $DATA | cut -d: -f2)
        IP_D=$(echo $DATA | cut -d: -f3)
        CNAMES=$(echo $DATA | cut -d: -f4)
        SERIAL=$(echo $DATA | cut -d: -f5)
        IP_ABC=$(echo $DATA | cut -d: -f6)

        #FORWARD ZONE FILE
        ZONEFILE="$ZONENAME.zone"
        if [ -f "$ZONEFILE" ]; then
            mv "$ZONEFILE" "$ZONEFILE.bak"
        fi
        FULL_IP=`get_ip $IP_D $IP_ABC`
        gen_header $ZONENAME $SERIAL > $ZONEFILE
        chown $BINDUSER:$BINDGROUP $ZONEFILE
        gen_name "@" $FULL_IP >> $ZONEFILE
        for i in $CNAMES; do
            gen_cname $i $ZONENAME >> $ZONEFILE
        done

        if [ "$WITHREVERSE" ]; then
            #REVERSE ZONE FILE
            REVERSEFILE="$ZONENAME.reverse"
            if [ -f "$REVERSEFILE" ]; then
                mv "$REVERSEFILE" "$REVERSEFILE.bak"
            fi
            gen_header $ZONENAME $SERIAL > $REVERSEFILE
            chown $BINDUSER:$BINDGROUP $REVERSEFILE
            gen_ptr $IP_D "" >> $REVERSEFILE

            echo "Generate $ZONEFILE and $REVERSEFILE ..."
        else
            echo "Generate $ZONEFILE ..."
        fi

    #NS 
    elif [ "${DATA:0:3}" == "ns:" ] && [ "$ZONENAME" ]; then
        for i in $(echo $DATA | cut -d: -f2); do
            gen_ns $i >> $ZONEFILE
            if [ "$WITHREVERSE" ]; then
                gen_ns $i >> $REVERSEFILE
            fi
        done

    #MX
    elif [ "${DATA:0:3}" == "mx:" ] && [ "$ZONENAME" ]; then
        for i in $(echo $DATA | cut -d: -f2); do
            $MAILNAME=$(echo $i | cut -d, -f1)
            $RRPRIORITY=$(echo $i | cut -d, -f2)
            gen_mx $MAILNAME $RRPRIORITY >> $ $ZONEFILE
        done

    #DATA
    elif [ "$DATA" ]; then
        RAW_IP=$(echo $DATA | cut -d: -f1)
        FULL_IP=`get_ip $RAW_IP $IP_ABC`
        NAMES=$(echo $DATA | cut -d: -f2)
        FIRSTNAME=$(echo $NAMES | cut -d\  -f1)
        echo "gen_name $FIRSTNAME $FULL_IP  $ZONEFILE"
        gen_name $FIRSTNAME $FULL_IP >> $ZONEFILE
        if [ "$WITHREVERSE" ]; then
            gen_ptr $RAW_IP $FIRSTNAME >> $REVERSEFILE
        fi
        for i in $NAMES; do
            if [ "$i" != "$FIRSTNAME" ]; then
                gen_cname $i $FIRSTNAME >> $ZONEFILE
            fi
        done
    fi

done