diff --git a/create_opendkim_key.sh b/create_opendkim_key.sh index 4d83282..916a02e 100755 --- a/create_opendkim_key.sh +++ b/create_opendkim_key.sh @@ -17,7 +17,11 @@ log_file="${LOCK_DIR}/${script_name%%.*}.log" # - LOGGING=false BATCH_MODE=false + +DEFAULT_dns_dkim_zone_master_server="b.ns.oopen.de" DEFAULT_key_algo="hmac-sha256" +DEFAULT_key_name="update-dkim" +DEFAULT_key_secret="4woPu0jqf9Jp1IX+gduJ3BVW/1ZMeyCPTQMqEsMXLFw=" DEFAULT_ttl="43200" DEFAULT_dns_ssh_user="manage-bind" @@ -29,11 +33,12 @@ DEFAULT_create_dkim_delegation_script="/root/bin/bind/bind_create_dkim_delegatio DEFAULT_add_dkim_zone_master_script="/root/bin/bind/bind_add_dkim_zone_master.sh" DEFAULT_add_dkim_zone_slave_script="/root/bin/bind/bind_add_dkim_zone_slave.sh" -opendkim_dir="/etc/opendkim" -signing_table_file="${opendkim_dir}/signing.table" -key_table_file="${opendkim_dir}/key.table" -key_base_dir=${opendkim_dir}/keys +# - We use actual timestamp as DEKIM Selector +# - +DEFAULT_dkim_selector=$(date +%s) + +DEFAULT_opendkim_dir="/etc/opendkim" @@ -119,7 +124,25 @@ usage() { clean_up() { + # SIGHUP SIGINT SIGTERM + if is_number ${1} && [[ ${1} -eq 127 ]] ; then + + blank_line + + if [[ -n "${key_dir}" ]] && [[ -d "${key_dir}" ]] ; then + echononl "Clean up OpenDKIM key directory \033[1m${key_dir}\033[m .." + if [[ -f "${key_dir}/${dkim_selector}.*" ]]; then + rm -f "${key_dir}/${dkim_selector}.*" + echo_ok + else + echo_skipped + fi + fi + blank_line + fi + # Perform program exit housekeeping + rm -rf "$LOCK_DIR" blank_line exit $1 @@ -241,6 +264,17 @@ containsElement () { return 1 } +# Check for positive number +is_number() { + + return $(test ! -z "${1##*[!0-9]*}" > /dev/null 2>&1); + + # - also possible + # - + #[[ ! -z "${1##*[!0-9]*}" ]] && return 0 || return 1 + #return $([[ ! -z "${1##*[!0-9]*}" ]]) +} + # - Remove leading/trailling whitespaces # - trim() { @@ -276,7 +310,7 @@ delete_generated_files() { # - Run 'clean_up' for signals SIGHUP SIGINT SIGTERM # - -trap clean_up SIGHUP SIGINT SIGTERM +trap 'clean_up 127' SIGHUP SIGINT SIGTERM # - Create lock directory '$LOCK_DIR" # @@ -418,6 +452,8 @@ 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" fi +else + update_zone="_domainkey.${dkim_domain}" fi @@ -487,15 +523,23 @@ if $update_dns && [[ -z "$update_zone" ]] ; then fi if $update_dns && [[ -z "$key_secret" ]] ; then fatal "No secret for the update key used by nsupdate is given!" +else + key_secret="${DEFAULT_key_secret}" fi if $update_dns && [[ -z "$key_algo" ]]; then key_algo="$DEFAULT_key_algo" +else + key_algo="${DEFAULT_key_algo}" fi if $update_dns && [[ -z "$key_name" ]]; then - key_name="$update_zone" + key_name="${DEFAULT_key_name}" +else + key_name="${DEFAULT_key_name}" fi if $update_dns && [[ -z "$ttl" ]]; then ttl="$DEFAULT_ttl" +else + ttl="$DEFAULT_ttl" fi if $update_dns && [[ -z "$dns_dkim_zone_master_server" ]]; then fatal "No DNS server for updating given!" @@ -521,17 +565,46 @@ fi blank_line +echo "" +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo " Insert DKIM selector or type using actual timestamp ." +echo "" +echo "" +while [[ -z "${dkim_selector}" ]]; do + echononl " DKIM selector [ \033[1m${DEFAULT_dkim_selector}\033[m ]: " + read dkim_selector + if [[ -z "$(trim ${dkim_selector})" ]] ; then + dkim_selector=${DEFAULT_dkim_selector} + fi +done -# - We use actual timestamp as DEKIM Selector -# - -time_stamp=$(date +%s) +echo "" +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo " Insert OpenDKIM directory or type using idefault ." +echo "" +echo "" +while [[ -z "${opendkim_dir}" ]]; do + echononl " DKIM (base) directory [ \033[1m${DEFAULT_opendkim_dir}\033[m ]: " + read opendkim_dir + if [[ -z "$(trim ${opendkim_dir})" ]] ; then + opendkim_dir=${DEFAULT_opendkim_dir} + fi +done + +signing_table_file="${opendkim_dir}/signing.table" +key_table_file="${opendkim_dir}/key.table" +key_base_dir=${opendkim_dir}/keys if $terminal ; then echo "" echo -e " \033[1m----------\033[m" echo " DKIM Domain......................: $dkim_domain" - echo " DKIM Selector....................: $time_stamp" + echo " DKIM Selector....................: $dkim_selector" if $update_dns ; then echo -e " Create/Update DKIM TXT record....: \033[32mYes\033[m" echo " Domain used for DKIM TXT record..: $update_zone" @@ -542,7 +615,11 @@ if $terminal ; then echo -e " Create/Update DKIM TXT record....: \033[33mNo\033[m" fi echo "" - echo " DNS Master Server................: $dns_dkim_zone_master_server" + if [[ -z "${dns_dkim_zone_master_server}" ]] ; then + echo -e " DNS Master Server................: \033[33m- Updating DNS was not requested -\033[m" + else + echo " DNS Master Server................: $dns_dkim_zone_master_server" + fi if [[ -z "$ttl" ]] || [[ "${ttl,,}" = "none" ]] ; then echo -e " TTL for the DKIM TXT Record......: \033[33m- Not set -\033[m" else @@ -1066,7 +1143,7 @@ fi # - echononl " Create Key Directory '${key_dir}'" if [[ ! -d "$key_dir" ]]; then - mkdir $key_dir 2> $log_file + mkdir -p $key_dir 2> $log_file if [[ $? -eq 0 ]] ; then echo_ok else @@ -1089,11 +1166,11 @@ fi # - 'bind' nameservers (TXT recors are restricted to 255 characters) # - 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 +opendkim-genkey -D $key_dir -d $dkim_domain -b 2048 -r -s $dkim_selector > $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") + generated_files_arr+=("${key_dir}/${dkim_selector}.private") + generated_files_arr+=("${key_dir}/${dkim_selector}.txt") else echo_failed error "$(cat $log_file)" @@ -1101,16 +1178,20 @@ fi # - Set up ownership an permissions # - -echononl " Set ownership on '${key_dir}/${time_stamp}.private'" -chown opendkim ${key_dir}/${time_stamp}.private > $log_file 2>&1 -if [[ $? -eq 0 ]] ; then - echo_ok +echononl " Set ownership on '${key_dir}/${dkim_selector}.private'" +if id -u "opendkim" >/dev/null 2>&1; then + chown opendkim ${key_dir}/${dkim_selector}.private > $log_file 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi else - echo_failed - error "$(cat $log_file)" + echo_skipped fi -echononl " Set permissions on '${key_dir}/${time_stamp}.private'" -chmod 600 ${key_dir}/${time_stamp}.private > $log_file 2>&1 +echononl " Set permissions on '${key_dir}/${dkim_selector}.private'" +chmod 600 ${key_dir}/${dkim_selector}.private > $log_file 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else @@ -1120,10 +1201,10 @@ fi echononl " Print out public key for domain '$dkim_domain'.." -openssl rsa -in ${key_dir}/${time_stamp}.private -pubout -out ${key_dir}/${time_stamp}.public > $log_file 2>&1 +openssl rsa -in ${key_dir}/${dkim_selector}.private -pubout -out ${key_dir}/${dkim_selector}.public > $log_file 2>&1 if [[ $? -eq 0 ]] ; then echo_ok - generated_files_arr+=("${key_dir}/${time_stamp}.public ") + generated_files_arr+=("${key_dir}/${dkim_selector}.public ") else echo_failed error "$(cat $log_file)" @@ -1143,22 +1224,22 @@ fi if $terminal ; then echo " Write bind9 dekim TXT record to file" fi -echononl " '${key_dir}/${time_stamp}.bind9'" -echo "; ----- DKIM key $time_stamp for ${dkim_domain}" > ${key_dir}/${time_stamp}.bind9 -echo -n "${time_stamp}._domainkey.${dkim_domain}. $ttl IN TXT ( \"v=DKIM1; k=rsa; s=email; p=\"" >> ${key_dir}/${time_stamp}.bind9 +echononl " '${key_dir}/${dkim_selector}.bind9'" +echo "; ----- DKIM key $dkim_selector for ${dkim_domain}" > ${key_dir}/${dkim_selector}.bind9 +echo -n "${dkim_selector}._domainkey.${dkim_domain}. $ttl IN TXT ( \"v=DKIM1; k=rsa; s=email; p=\"" >> ${key_dir}/${dkim_selector}.bind9 while IFS='' read -r _line || [[ -n $_line ]] ; do if echo "$_line" | grep -i -q -E "^---" 2> /dev/null ; then continue fi - echo "" >> ${key_dir}/${time_stamp}.bind9 - echo -n " \"$_line\"" >> ${key_dir}/${time_stamp}.bind9 + echo "" >> ${key_dir}/${dkim_selector}.bind9 + echo -n " \"$_line\"" >> ${key_dir}/${dkim_selector}.bind9 -done < "${key_dir}/${time_stamp}.public" -echo " )" >> ${key_dir}/${time_stamp}.bind9 +done < "${key_dir}/${dkim_selector}.public" +echo " )" >> ${key_dir}/${dkim_selector}.bind9 echo_ok -generated_files_arr+=("${key_dir}/${time_stamp}.bind9") +generated_files_arr+=("${key_dir}/${dkim_selector}.bind9") # - Write TXT record as string for 'nsupdate' # - @@ -1166,32 +1247,65 @@ if $terminal ; then echo " Write TXT record as string for 'nsupdate' to file" fi -echononl " '${key_dir}/${time_stamp}.nsupdate'" -echo -n "\"v=DKIM1; k=rsa; s=email; p=\"" >> ${key_dir}/${time_stamp}.nsupdate +echononl " '${key_dir}/${dkim_selector}.nsupdate'" +echo -n "\"v=DKIM1; k=rsa; s=email; p=\"" >> ${key_dir}/${dkim_selector}.nsupdate while IFS='' read -r _line || [[ -n $_line ]] ; do if echo "$_line" | grep -i -q -E "^---" 2> /dev/null ; then continue fi - echo -n " \"$_line\"" >> ${key_dir}/${time_stamp}.nsupdate + echo -n " \"$_line\"" >> ${key_dir}/${dkim_selector}.nsupdate -done < "${key_dir}/${time_stamp}.public" +done < "${key_dir}/${dkim_selector}.public" echo_ok -generated_files_arr+=("${key_dir}/${time_stamp}.nsupdate") +generated_files_arr+=("${key_dir}/${dkim_selector}.nsupdate") if ! $update_dns ; then + + [[ -z "${dns_dkim_zone_master_server}" ]] && dns_dkim_zone_master_server=${DEFAULT_dns_dkim_zone_master_server} + 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)" + 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}/${dkim_selector}.bind9)" + echo "" + echo -e "\n\n If you can use 'nsupdate', then issue the following command:\n\n" + cat < to continue: " - read OK - echo + echo -n "Continue? [yes/no]: " + read OK + while [[ "${OK,,}" != "yes" ]] && [[ "${OK,,}" != "no" ]] ; do + echononl "Wrong entry! - Continue? [yes/no]: " + read OK + done + + if [[ ${OK,,} = "yes" ]] ; then + blank_line + else + delete_generated_files + clean_up 1 + fi + + fi @@ -1212,8 +1326,8 @@ if $update_dns ; then server $dns_dkim_zone_master_server zone $update_zone key ${key_algo}:$key_name $key_secret -update delete ${time_stamp}.${update_zone}. -update add ${time_stamp}.${update_zone}. $ttl IN TXT $(cat ${key_dir}/${time_stamp}.nsupdate) +update delete ${dkim_selector}.${update_zone}. +update add ${dkim_selector}.${update_zone}. $ttl IN TXT $(cat ${key_dir}/${dkim_selector}.nsupdate) send EOF if [[ $? -eq 0 ]] ; then @@ -1225,21 +1339,21 @@ cat < ${key_dir}/${time_stamp}.nsupdate.command + cat < ${key_dir}/${dkim_selector}.nsupdate.command cat </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 + perl -i -n -p -e "s#^\s*$dkim_domain_shortname\s.*#${dkim_domain_shortname}\t\t${dkim_domain}:${dkim_selector}:${key_dir}/${dkim_selector}.private#" $key_table_file 2> $log_file if [[ $? -eq 0 ]] ; then echo_ok else @@ -1321,7 +1435,7 @@ if grep -q -E "^\s*$dkim_domain_shortname\s" $key_table_file 2>/dev/null ; then 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 + echo -e "${dkim_domain_shortname}\t\t${dkim_domain}:${dkim_selector}:${key_dir}/${dkim_selector}.private" >> $key_table_file 2> $log_file if [[ $? -eq 0 ]] ; then echo_ok else @@ -1331,7 +1445,7 @@ else fi echononl " Adjust file ${key_dir}/generated_keys.selectors" -echo "${time_stamp}" >> ${key_dir}/generated_keys.selectors +echo "${dkim_selector}" >> ${key_dir}/generated_keys.selectors echo_done @@ -1370,13 +1484,13 @@ 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." + info "DKIM TXT Record with selector \033[1m$dkim_selector\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 " [ Info ] DKIM TXT Record with selector $dkim_selector created." echo "" fi @@ -1386,7 +1500,7 @@ clean_up 0 -#txt_record="$(cat ${key_dir}/${time_stamp}.txt | awk -F'"' '{print $2}' | tr -d '\n')" +#txt_record="$(cat ${key_dir}/${dkim_selector}.txt | awk -F'"' '{print $2}' | tr -d '\n')" #txt_record_1=${txt_record:0:255} #txt_record_2=${txt_record:255} #new_txt_record="\"$txt_record_1\"\"$txt_record_2\""