diff --git a/conf/create_opendkim_key.conf.sample b/conf/create_opendkim_key.conf.sample index 92770d5..01c2ec8 100644 --- a/conf/create_opendkim_key.conf.sample +++ b/conf/create_opendkim_key.conf.sample @@ -24,8 +24,10 @@ dns_server="b.ns.oopen.de" # - # - Zone containing the DKIM TXT record. # - -# - Example: -# - update_zone="dkim.oopen.de" +# - Defaults to '_domainkey.' +# - +# - Note: +# - do NOT change/set this option unless you know what you do. # - #update_zone="" @@ -33,8 +35,10 @@ dns_server="b.ns.oopen.de" # - # - TTL for the DKIM TXT Record. # - -# - Defaults to "360" -#TTL=360 +# - Defaults to "" if update_dns=false +# - Defaults to "43200" if update_dns=true +# +#TTL="" # ---------- diff --git a/create_opendkim_key.sh b/create_opendkim_key.sh index 6df6d58..cb02657 100755 --- a/create_opendkim_key.sh +++ b/create_opendkim_key.sh @@ -18,7 +18,7 @@ log_file="${LOCK_DIR}/${script_name%%.*}.log" LOGGING=false BATCH_MODE=false DEFAULT_key_algo="hmac-sha256" -DEFAULT_ttl=360 +DEFAULT_ttl="43200" opendkim_dir="/etc/opendkim" @@ -83,11 +83,14 @@ usage() { -n Do \033[1mNOT\033[m set/update DNS TXT record for DKIM domain. The default is - to update DNS entry. + to update DNS entry. This option is ignored if flag \033[1m-n\033[m is set. -s Give the secret for the key used by nsupdate to create/update the DNS TXT record. + -t + Specify the TTL value for the DKIM TXT record. + -z The zone which is updated with the TXT entry for DKIM by using 'nsupdate'. @@ -113,32 +116,19 @@ clean_up() { exit $1 } - -containsElement () { - local e - for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done - return 1 -} - -# - Remove leading/trailling whitespaces -# - -trim() { - local var="$*" - var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters - var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace characters - echo -n "$var" -} - echononl(){ - echo X\\c > /tmp/shprompt$$ - if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then - echo -e -n "$*\\c" 1>&2 - else - echo -e -n "$*" 1>&2 + if $terminal ; then + echo X\\c > /tmp/shprompt$$ + if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then + echo -e -n " $*\\c" 1>&2 + else + echo -e -n " $*" 1>&2 + fi + rm /tmp/shprompt$$ fi - rm /tmp/shprompt$$ } + fatal(){ echo "" if $terminal ; then @@ -236,6 +226,14 @@ blank_line() { fi } +containsElement () { + local e + for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done + return 1 +} + +# - Remove leading/trailling whitespaces +# - trim() { local var="$*" var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters @@ -243,6 +241,23 @@ trim() { echo -n "$var" } +delete_generated_files() { + + for _file in ${generated_files_arr[@]} ; do + + echononl " Delete file \033[1m$_file\033[m .." + + rm "$_file" > $log_file 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + + done + +} @@ -382,14 +397,13 @@ if $update_dns && [[ -z "$update_zone" ]] && ! $BATCH_MODE ; then echo "" echo " Which zone should contain the DKIM TXT record?" echo "" + echo -e " Type \033[33m\033[m to use the default value \033[33m_domainkey.${dkim_domain}\033[m" echo "" - echononl " update Zone: " + echononl " update Zone [_domainkey.${dkim_domain}]: " read update_zone - while [ "X$update_zone" = "X" ] ; do - echo -e "\n\t\033[33m\033[1mEingabe erforderlich.\033[m\n" - echononl " update Zone: " - read update_zone - done + if [[ -z "$(trim $update_zone)" ]]; then + update_zone="_domainkey.${dkim_domain}" + fi elif $update_dns && $terminal ; then echo -e "\033[32m--\033[m" info "Zone \033[37m\033[1m$update_zone\033[m is used for DKIM TXT record" @@ -458,7 +472,7 @@ if [[ -z "$dkim_domain" ]] ; then fatal "Running in batch mode, but no domain was given!" fi if $update_dns && [[ -z "$update_zone" ]] ; then - fatal "No update-zone is given!" + update_zone="_domainkey.${dkim_domain}" fi if $update_dns && [[ -z "$key_secret" ]] ; then fatal "No secret for the update key used by nsupdate is given!" @@ -487,17 +501,21 @@ if $terminal ; then echo -e " \033[1m----------\033[m" echo " DKIM Domain......................: $dkim_domain" if $update_dns ; then - echo " Create/Update DKIM TXT record....: Yes" + echo -e " Create/Update DKIM TXT record....: \033[32mYes\033[m" echo " Domain used for DKIM TXT record..: $update_zone" echo " Secret for the update key........: $key_secret" echo " Algorithm used for the TSIG key..: $key_algo" echo " Name of the TSIG key.............: $key_name" else - echo " Create/Update DKIM TXT record....: No" + echo -e " Create/Update DKIM TXT record....: \033[33mNo\033[m" fi echo "" echo " DNS Server.......................: $dns_server" - echo " TTL for the DKIM TXT Record......: $ttl" + if [[ -z "$ttl" ]] || [[ "${ttl,,}" = "none" ]] ; then + echo -e " TTL for the DKIM TXT Record......: \033[33m- Not set -\033[m" + else + echo " TTL for the DKIM TXT Record......: $ttl" + fi echo "" echo " OpenDKIM's etc-directory.........: $opendkim_dir" echo " Key directory....................: ${key_base_dir}/${dkim_domain}" @@ -527,6 +545,37 @@ time_stamp=$(date +%s) key_dir=${key_base_dir}/${dkim_domain} dkim_domain_shortname="${dkim_domain%.*}" +declare -a generated_files_arr=() + +_wait=false +if $update_dns && [[ "$dkim_domain" != "$update_zone" ]] ; then + if ! $BATCH_MODE ; then + if [[ -z "$(dig +short ${update_zone}. NS)" ]] ; then + + _tmp_string="; ----- Delegation DKIM Keys ${dkim_domain}" + for _server in $(dig +short ${dkim_domain} NS) ; do + _tmp_string="$_tmp_string\n${update_zone}. IN NS $_server" + done + + + blank_line + todo "Create a delegation for zone \033[1m${update_zone}.\033[m\n\n$_tmp_string" + _wait=true + + echo "" + echo -e " After adjusting your nameserver continue with this script" + echo "" + echo -en " \033[33mType to continue or +C to abort:\033[m " + read OK + echo + + fi + else + if [[ -z "$(dig +short ${update_zone}. NS)" ]] ; then + fatal "No NS Record found for zone \033[1m${update_zone}.\033[m" + fi + fi +fi # - Generate private/public keys # - @@ -567,6 +616,8 @@ echononl " Generate private key for domain '$dkim_domain'.." opendkim-genkey -D $key_dir -d $dkim_domain -b 2048 -r -s $time_stamp > $log_file 2>&1 if [[ $? -eq 0 ]] ; then echo_ok + generated_files_arr+=("${key_dir}/${time_stamp}.private") + generated_files_arr+=("${key_dir}/${time_stamp}.txt") else echo_failed error "$(cat $log_file)" @@ -596,65 +647,13 @@ echononl " Print out public key key for domain '$dkim_domain'.." openssl rsa -in ${key_dir}/${time_stamp}.private -pubout -out ${key_dir}/${time_stamp}.public > $log_file 2>&1 if [[ $? -eq 0 ]] ; then echo_ok + generated_files_arr+=("${key_dir}/${time_stamp}.public ") else echo_failed error "$(cat $log_file)" fi -# - Configure OpenDKIM -# - -if $terminal ; then - echo "" - echo -e " \033[32mConfigure OpenDKIM for domain \033[37m\033[1m$dkim_domain\033[m" - echo "" -fi - - -# - Configure/Adjust the signing table -# - -echononl " Configure/Adjust the signing table.." -if grep -q -E "^\s*\*@$dkim_domain\s" $signing_table_file 2>/dev/null ; then - perl -i -n -p -e "s/^\*@$dkim_domain\s.*/*@$dkim_domain\t$dkim_domain_shortname/" $signing_table_file 2> $log_file - if [[ $? -eq 0 ]] ; then - echo_ok - else - echo_failed - error "$(cat $log_file)" - fi -else - echo -e "*@$dkim_domain\t$dkim_domain_shortname" >> $signing_table_file 2> $log_file - if [[ $? -eq 0 ]] ; then - echo_ok - else - echo_failed - error "$(cat $log_file)" - fi -fi - - -# - Configure/Adjust the key table -# - -echononl " Configure/Adjustkey table" -if grep -q -E "^\s*$dkim_domain_shortname\s" $key_table_file 2>/dev/null ; then - perl -i -n -p -e "s#^\s*$dkim_domain_shortname\s.*#${dkim_domain_shortname}\t\t${dkim_domain}:${time_stamp}:${key_dir}/${time_stamp}.private#" $key_table_file 2> $log_file - if [[ $? -eq 0 ]] ; then - echo_ok - else - echo_failed - error "$(cat $log_file)" - fi -else - echo -e "${dkim_domain_shortname}\t\t${dkim_domain}:${time_stamp}:${key_dir}/${time_stamp}.private" >> $key_table_file 2> $log_file - if [[ $? -eq 0 ]] ; then - echo_ok - else - echo_failed - error "$(cat $log_file)" - fi -fi - - # - Generate TXT record for use in bind9 # - if $terminal ; then @@ -683,6 +682,7 @@ while IFS='' read -r _line || [[ -n $_line ]] ; do done < "${key_dir}/${time_stamp}.public" echo " )" >> ${key_dir}/${time_stamp}.bind9 echo_ok +generated_files_arr+=("${key_dir}/${time_stamp}.bind9") # - Write TXT record as string for 'nsupdate' # - @@ -702,6 +702,22 @@ while IFS='' read -r _line || [[ -n $_line ]] ; do done < "${key_dir}/${time_stamp}.public" echo_ok +generated_files_arr+=("${key_dir}/${time_stamp}.nsupdate") + + + +if ! $update_dns ; then + blank_line + todo "Now you have to add the TXT Record to your zone file.\n\n Copy/Paste the following data:\n\n$(cat ${key_dir}/${time_stamp}.bind9)" + + echo "" + echo -e "After adjusting your nameserver continue with this script" + echo "" + echo -n "Type to continue: " + read OK + echo + +fi @@ -721,9 +737,42 @@ server $dns_server zone $update_zone key ${key_algo}:$key_name $key_secret update delete ${dkim_domain}.${update_zone}. -update add ${dkim_domain}.${update_zone}. $ttl TXT $(cat ${key_dir}/${time_stamp}.nsupdate) +update add ${time_stamp}.${update_zone}. $ttl IN TXT $(cat ${key_dir}/${time_stamp}.nsupdate) send EOF + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + delete_generated_files + clean_up 1 + fi +fi + + +# - Configure OpenDKIM +# - +if $terminal ; then + echo "" + echo -e " \033[32mConfigure OpenDKIM for domain \033[37m\033[1m$dkim_domain\033[m" + echo "" +fi + + +# - Configure/Adjust the signing table +# - +echononl " Configure/Adjust signing table.." +if grep -q -E "^\s*\*@$dkim_domain\s" $signing_table_file 2>/dev/null ; then + perl -i -n -p -e "s/^\*@$dkim_domain\s.*/*@$dkim_domain\t$dkim_domain_shortname/" $signing_table_file 2> $log_file + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo -e "*@$dkim_domain\t$dkim_domain_shortname" >> $signing_table_file 2> $log_file if [[ $? -eq 0 ]] ; then echo_ok else @@ -733,27 +782,30 @@ EOF fi -_wait=false -if ! $update_dns ; then - blank_line - todo "Now you have to add the TXT Record to your zone file.\n\n Copy/Paste the following data:\n\n$(cat ${key_dir}/${time_stamp}.bind9)" - _wait=true -elif [[ "$dkim_domain" != "$update_zone" ]]; then - if [[ -z "$(dig +short ${time_stamp}._domainkey.${dkim_domain}. CNAME)" ]]; then - blank_line - todo "Create a CNAME Record to your zone file.\n\n $cname_record" - _wait=true +# - Configure/Adjust the key table +# - +echononl " Configure/Adjust key table" +if grep -q -E "^\s*$dkim_domain_shortname\s" $key_table_file 2>/dev/null ; then + perl -i -n -p -e "s#^\s*$dkim_domain_shortname\s.*#${dkim_domain_shortname}\t\t${dkim_domain}:${time_stamp}:${key_dir}/${time_stamp}.private#" $key_table_file 2> $log_file + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo -e "${dkim_domain_shortname}\t\t${dkim_domain}:${time_stamp}:${key_dir}/${time_stamp}.private" >> $key_table_file 2> $log_file + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" fi fi -if ! $BATCH_MODE && $_wait ; then - echo "" - echo -e "After adjusting your nameserver continue with this script" - echo "" - echo -n "Type to continue: " - read OK - echo -fi +echononl " Adjust file ${key_dir}/generated_keys.selectors" +echo "${time_stamp}" >> ${key_dir}/generated_keys.selectors +echo_done # - Restart OpenDKIM @@ -787,6 +839,20 @@ if [[ -n "$log_file" ]]; then rm -f "$log_file" fi +if $terminal ; then + info "DKIM Key for domain \033[1m${dkim_domain}\033[m created/updated." + if $update_dns ; then + info "DKIM TXT Record with selector \033[1m$time_stamp\033[m created." + fi +else + echo "" + echo " [ Info ] DKIM Key for domain ${dkim_domain} created/updated." + echo "" + echo " [ Info ] DKIM TXT Record with selector $time_stamp created." + echo "" + +fi + blank_line clean_up 0