create_opendkim_key.sh: Support custom selector; some changes on script output.

This commit is contained in:
Christoph 2024-03-29 13:33:48 +01:00
parent f76103664e
commit 4788537cd9

View File

@ -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 <return> 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 <return> 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 ""
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
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
else
echo_failed
error "$(cat $log_file)"
fi
else
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 <<END
cat <<EOF | nsupdate -v -L3
server $dns_dkim_zone_master_server
zone $update_zone
key ${key_algo}:$key_name $key_secret
update delete ${dkim_selector}.${update_zone}.
update add ${dkim_selector}.${update_zone}. $ttl IN TXT $(cat ${key_dir}/${dkim_selector}.nsupdate)
send
EOF
END
echo ""
echo -e "After adjusting your nameserver continue with this script"
echo "Add the TXT record printed above to the relevant name servers"
echo "and enter 'yes' to continue. "
echo ""
echo -n "Type <return> to continue: "
echo "To cancel at this point, enter 'no' or press Ctrl-C."
echo ""
echo -n "Continue? [yes/no]: "
read OK
echo
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 <<EOF | nsupdate -v -L3
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
END
cat <<END > ${key_dir}/${time_stamp}.nsupdate.command
cat <<END > ${key_dir}/${dkim_selector}.nsupdate.command
cat <<EOF | nsupdate -v -L3
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
@ -1253,8 +1367,8 @@ cat <<EOF | nsupdate -v -L3
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
END
@ -1313,7 +1427,7 @@ fi
# -
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
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\""