Compare commits

..

11 Commits

6 changed files with 1168 additions and 134 deletions

619
add_cname_for_dkim_entry.sh Executable file
View File

@@ -0,0 +1,619 @@
#!/usr/bin/env bash
script_name="$(basename $(realpath $0))"
working_dir="$(dirname $(realpath $0))"
conf_file="${working_dir}/conf/${script_name%%.*}.conf"
LOCK_DIR="/tmp/$(basename $0).$$.LOCK"
log_file="${LOCK_DIR}/${script_name%%.*}.log"
# ----------
# Base Function(s)
# ----------
usage() {
[[ -n "$1" ]] && error "$1"
[[ $terminal ]] && echo -e "
\033[1mUsage:\033[m
$(basename $0) [OPTION [OPTION ..
\033[1mDescription\033[m
<Some Description>
\033[1mOptions\033[m
<List Options>
\033[1mFiles\033[m
$conf_file: Configuration file
\033[1mExample:\033[m
<description example>
$(basename $0) .. <comand example>
<description another example>
$(basename $0) .. <command another example>
"
clean_up 1
}
clean_up() {
# Perform program exit housekeeping
rm -rf "$LOCK_DIR"
blank_line
exit $1
}
echononl(){
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
}
fatal(){
echo ""
if $terminal ; then
echo -e " [ \033[31m\033[1mFatal\033[m ]: $*"
echo ""
echo -e " \033[31m\033[1mScript was interupted\033[m!"
else
echo " [ Fatal ]: $*"
echo ""
echo " Script was terminated...."
fi
echo ""
clean_up 1
}
error (){
echo ""
if $terminal ; then
echo -e " [ \033[31m\033[1mError\033[m ]: $*"
else
echo " [ Error ]: $*"
fi
echo ""
}
warn (){
if $terminal ; then
echo ""
echo -e " [ \033[33m\033[1mWarning\033[m ]: $*"
echo ""
fi
}
info (){
if $terminal ; then
echo ""
echo -e " [ \033[32m\033[1mInfo\033[m ]: $*"
echo ""
fi
}
ok (){
if $terminal ; then
echo ""
echo -e " [ \033[32m\033[1mOk\033[m ] $*"
echo ""
fi
}
echo_done() {
if $terminal ; then
echo -e "\033[95G[ \033[32mdone\033[m ]"
fi
}
echo_ok() {
if $terminal ; then
echo -e "\033[95G[ \033[32mok\033[m ]"
fi
}
echo_warn() {
if $terminal ; then
echo -e "\033[95G[ \033[33mwarn\033[m ]"
fi
}
echo_failed(){
if $terminal ; then
echo -e "\033[95G[ \033[1;31mfailed\033[m ]"
fi
}
echo_skipped() {
if $terminal ; then
echo -e "\033[95G[ \033[90m\033[1mskipped\033[m ]"
fi
}
echo_wait(){
if $terminal ; then
echo -en "\033[95G[ \033[5m\033[1m...\033[m ]"
fi
}
trim() {
local var="$*"
var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters
var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace characters
echo -n "$var"
}
blank_line() {
if $terminal ; then
echo ""
fi
}
# ----------
# - Jobhandling
# ----------
# - Run 'clean_up' for signals SIGHUP SIGINT SIGTERM
# -
trap clean_up SIGHUP SIGINT SIGTERM
# - Create lock directory '$LOCK_DIR"
#
mkdir "$LOCK_DIR"
# ----------
# - Some checks ..
# ----------
# - Running in a terminal?
# -
if [[ -t 1 ]] ; then
terminal=true
else
terminal=false
fi
# -------------
# - Default values
# -------------
# - Give your default values here
# -
DEFAULT_DNS_DKIM_ZONE_MASTER_SERVER="b.ns.oopen.de"
DEFAULT_TTL="3600"
DEFAULT_KEY_ALGO="hmac-sha256"
DEFAULT_KEY_NAME="update-dkim"
DEFAULT_DKIM_TYPE="DKIM1"
DEFAULT_KEY_TYPE="rsa"
DEFAULT_SERVICE_TYPE="email"
DEFAULT_DKIM_SELECTOR=""
if [[ -f "$conf_file" ]]; then
source "$conf_file"
else
warn "No configuration file '$conf_file' present.\n
Loading default values.."
fi
if [[ -n "$(trim "$DNS_DKIM_ZONE_MASTER_SERVER")" ]] ; then
DEFAULT_DNS_DKIM_ZONE_MASTER_SERVER="${DNS_DKIM_ZONE_MASTER_SERVER}"
DNS_DKIM_ZONE_MASTER_SERVER=""
fi
if [[ -n "$(trim "$KEY_ALGO")" ]] ; then
DEFAULT_KEY_ALGO="${KEY_ALGO}"
KEY_ALGO=""
fi
if [[ -n "$(trim "$KEY_NAME")" ]] ; then
DEFAULT_KEY_NAME="${KEY_NAME}"
KEY_NAME=""
fi
if [[ -n "$(trim "$KEY_SECRET")" ]] ; then
DEFAULT_KEY_SECRET="${KEY_SECRET}"
KEY_SECRET=""
fi
if $terminal ; then
echo ""
echo -e "\033[32m--\033[m"
echo ""
echo " Insert the domain name for which DKIM CNAME entry should be configured."
echo ""
echo ""
echononl " DKIM domain: "
read DKIM_DOMAIN
while [ "X$DKIM_DOMAIN" = "X" ] ; do
echo -e "\n\t\033[33m\033[1mEingabe erforderlich.\033[m\n"
echononl " DKIM domain: "
read DKIM_DOMAIN
done
DEFAULT_DKIM_UPDATE_ZONE="_domainkey.${DKIM_DOMAIN}"
echo -e "\033[32m--\033[m"
echo ""
echo " Insert zone which should be updated with the new DKIM CNAME."
echo ""
echo ""
echononl " DKIM Zone [${DEFAULT_DKIM_UPDATE_ZONE}]: "
read DKIM_UPDATE_ZONE
if [[ "X$DKIM_UPDATE_ZONE" = "X" ]] ; then
DKIM_UPDATE_ZONE="${DEFAULT_DKIM_UPDATE_ZONE}"
fi
echo ""
echo -e "\033[32m--\033[m"
echo ""
echo " Insert Hostname of CNAME Reccord"
echo ""
echo " Note: "
echo ""
echo -e " \033[33mOnly a hostname of Zone '${DKIM_UPDATE_ZONE}' is possible.\033[m"
echo ""
echo -e " If FQN of Entry is \033[1mbrevo1.${DKIM_UPDATE_ZONE}\033[m then enter"
echo ""
echo -e " Hostname: \033[1mbrevo1\033[m"""
echo ""
echononl " Hostname: "
read HOSTNAME
while [ "X$HOSTNAME" = "X" ] ; do
echo -e "\n\t\033[33m\033[1mEingabe erforderlich.\033[m\n"
echononl " :Hostname "
read Hostname
done
echo ""
echo -e "\033[32m--\033[m"
echo ""
echo " Insert FQN of CNAME entry"
echo ""
echo ""
echononl " CNAME: "
read CNAME
while [ "X$CNAME" = "X" ] ; do
echo -e "\n\t\033[33m\033[1mEingabe erforderlich.\033[m\n"
echononl " CNAME: "
read CNAME
done
if [[ ${CNAME} != *"." ]]; then
CNAME="${CNAME}."
fi
echo ""
echo -e "\033[32m--\033[m"
echo ""
echo " Insert Key name"
echo ""
echo ""
echononl " Key name [${DEFAULT_KEY_NAME}]: "
read KEY_NAME
if [[ "X$KEY_NAME" = "X" ]] ; then
KEY_NAME="${DEFAULT_KEY_NAME}"
fi
echo ""
echo -e "\033[32m--\033[m"
echo ""
echo " Insert Key secret"
echo ""
echo ""
if [[ -n "${DEFAULT_KEY_SECRET}" ]] ; then
echononl " Key secret [${DEFAULT_KEY_SECRET}]: "
read KEY_SECRET
if [[ "X$KEY_SECRET" = "X" ]] ; then
KEY_SECRET="${DEFAULT_KEY_SECRET}"
fi
else
echononl " Key secret: "
read KEY_SECRET
while [[ "X$KEY_SECRET" = "X" ]] ; do
echo -e "\n\t\033[33m\033[1mEingabe erforderlich.\033[m\n"
echononl " Key secret: "
read KEY_SECRET
done
fi
echo ""
echo -e "\033[32m--\033[m"
echo ""
echo -e " Insert DNS master server for domain \033[1m$DKIM_UPDATE_ZONE\033[m"
echo ""
echo ""
if [[ -n "${DEFAULT_DNS_DKIM_ZONE_MASTER_SERVER}" ]] ; then
echononl " DNS master server [${DEFAULT_DNS_DKIM_ZONE_MASTER_SERVER}]: "
read DNS_DKIM_ZONE_MASTER_SERVER
if [[ "X$DNS_DKIM_ZONE_MASTER_SERVER" = "X" ]] ; then
DNS_DKIM_ZONE_MASTER_SERVER="${DEFAULT_DNS_DKIM_ZONE_MASTER_SERVER}"
fi
else
echononl " DNS master server: "
read DNS_DKIM_ZONE_MASTER_SERVER
while [[ "X$DNS_DKIM_ZONE_MASTER_SERVER" = "X" ]] ; do
echo -e "\n\t\033[33m\033[1mEingabe erforderlich.\033[m\n"
echononl " DNS master server: "
read KEY_SECRET
done
fi
echo ""
echo -e "\033[32m--\033[m"
echo ""
echo " Specifies the algorithm to use for the TSIG key."
echo ""
if [[ "hmac-md5" = "${DEFAULT_KEY_ALGO}" ]] ; then
echo -e " [1] \033[37m\033[1m${DEFAULT_KEY_ALGO}\033[m"
else
echo " [1] hmac-md5"
fi
if [[ "hmac-sha1" = "${DEFAULT_KEY_ALGO}" ]] ; then
echo -e " [2] \033[37m\033[1m${DEFAULT_KEY_ALGO}\033[m"
else
echo " [2] hmac-sha1"
fi
if [[ "hmac-sha224" = "${DEFAULT_KEY_ALGO}" ]] ; then
echo -e " [3] \033[37m\033[1m${DEFAULT_KEY_ALGO}\033[m"
else
echo " [3] hmac-sha224"
fi
if [[ "hmac-sha256" = "${DEFAULT_KEY_ALGO}" ]] ; then
echo -e " [4] \033[37m\033[1m${DEFAULT_KEY_ALGO}\033[m"
else
echo " [4] hmac-sha256"
fi
if [[ "hmac-sha384" = "${DEFAULT_KEY_ALGO}" ]] ; then
echo -e " [5] \033[37m\033[1m${DEFAULT_KEY_ALGO}\033[m"
else
echo " [5] hmac-sha384"
fi
if [[ "hmac-sha512" = "${DEFAULT_KEY_ALGO}" ]] ; then
echo -e " [6] \033[37m\033[1m${DEFAULT_KEY_ALGO}\033[m"
else
echo " [6] hmac-sha512"
fi
echo ""
echo " Type a number or press <RETURN> to choose highlighted value"
echo ""
echononl " Key algorithm [${DEFAULT_KEY_ALGO}]: "
while [[ "$KEY_ALGO" != "hmac-md5" ]] \
&& [[ "$KEY_ALGO" != "hmac-sha1" ]] \
&& [[ "$KEY_ALGO" != "hmac-sha224" ]] \
&& [[ "$KEY_ALGO" != "hmac-sha256" ]] \
&& [[ "$KEY_ALGO" != "hmac-sha384" ]] \
&& [[ "$KEY_ALGO" != "hmac-sha512" ]] ; do
read OPTION
case $OPTION in
1) KEY_ALGO="hmac-md5" ;;
2) KEY_ALGO="hmac-sha1" ;;
3) KEY_ALGO="hmac-sha224" ;;
4) KEY_ALGO="hmac-sha256" ;;
5) KEY_ALGO="hmac-sha384" ;;
6) KEY_ALGO="hmac-sha512" ;;
'') KEY_ALGO="${DEFAULT_KEY_ALGO}" ;;
*) echo ""
echo -e " \033[33m\033[1mFalsche Eingabe ! [ 1 = hmac-md5 | 2 = hmac-sha1 | .. ]\033[m"
echo ""
echononl " Key algorithm [hmac-sha256]:"
;;
esac
done
echo ""
echo -e "\033[32m--\033[m"
echo ""
echo " Insert TTL for dns entry"
echo ""
echo ""
echononl " TTL [${DEFAULT_TTL}]: "
read TTL
if [[ "X$TTL" = "X" ]] ; then
TTL="${DEFAULT_TTL}"
fi
fi
if [[ -z "$(trim "${DKIM_DOMAIN}")" ]]; then
fatal "Variable \033[1mDKIM_DOMAIN\033[m not set!"
fi
if [[ -z "$(trim "${DKIM_UPDATE_ZONE}")" ]]; then
fatal "Variable \033[1mDKIM_UPDATE_ZONE\033[m not set!"
fi
if [[ -z "$(trim "${KEY_SECRET}")" ]]; then
fatal "Variable \033[1mKEY_SECRET\033[m not set!"
fi
blank_line
blank_line
declare -i length_dkim_key=${#DKIM_KEY}
if [[ "${SERVICE_TYPE,,}" = "none" ]] ; then
_intro="v=${DKIM_TYPE}; k=${KEY_TYPE};"
else
_intro="v=${DKIM_TYPE}; k=${KEY_TYPE}; s=${SERVICE_TYPE};"
fi
declare -i length_intro=${#_intro}
declare -i total_length=$((length_intro + length_dkim_key))
echononl "Create (splitted) 'p' value of DNS record.."
if [[ ${total_length} -gt 255 ]] ; then
TMP_DKIM_KEY="$DKIM_KEY"
p_val=""
_length=64
declare -i index=1
while [ -n "$TMP_DKIM_KEY" ]; do
if [[ index -eq 1 ]]; then
p_val="\"${TMP_DKIM_KEY:0:$_length}\""
else
p_val+=" \"${TMP_DKIM_KEY:0:$_length}\""
fi
TMP_DKIM_KEY="${TMP_DKIM_KEY:$_length}"
(( ++index ))
done
echo_done
# Note:
# !! closing quotation marks are already included !!
#
txt_val="\"${_intro} p=\" ${p_val}"
else
echo_skipped
p_val="${DKIM_KEY}"
txt_val="\"${_intro} p=${p_val}\""
fi
if $terminal ; then
echo ""
echo ""
echo -e " \033[1m----------\033[m"
echo " DKIM Domain......................: $DKIM_DOMAIN"
echo ""
echo " Name of the CNAME Record.........: $HOSTNAME"
echo " Target of the CNAMER Record......: $CNAME"
echo ""
echo " Domain used for DKIM TXT record..: $DKIM_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"
echo ""
echo " DNS Master Server................: $DNS_DKIM_ZONE_MASTER_SERVER"
if [[ -z "$TTL" ]] || [[ "${TTL,,}" = "none" ]] ; then
echo -e " TTL for the CNAME TXT Record.....: \033[33m- Not set -\033[m"
else
echo " TTL for the CNAMR TXT Record.....: $TTL"
fi
echo ""
echo -e " \033[1m----------\033[m"
echo ""
echo -e " DNS Record to add:\n\n\033[33m${DKIM_SELECTOR}.${DKIM_UPDATE_ZONE}. ${TTL} IN TXT ${txt_val}\033[m"
echo ""
echo -e "\n\n The following 'nsupdate'command will be used:"
cat <<END
cat <<EOF | nsupdate -v -L3
server $DNS_DKIM_ZONE_MASTER_SERVER
zone $DKIM_UPDATE_ZONE
key ${KEY_ALGO}:$KEY_NAME $KEY_SECRET
update delete ${HOSTNAME}.${DKIM_UPDATE_ZONE}.
update add ${HOSTNAME}.${DKIM_UPDATE_ZONE}. $TTL IN CNAME ${CNAME}
send
EOF
END
echo ""
echo -n " Type upper case 'YES' to start: "
read OK
if [[ "$OK" != "YES" ]] ; then
fatal "Abort by user request - Answer iwas not 'YES'"
fi
echo ""
fi
if $terminal ; then
echo ""
echo -e " \033[32mUpdate Zone \033[37m\033[1m${DKIM_UPDATE_ZONE}\033[m\033[32m DNS Server \033[37m\033[1m${DNS_DKIM_ZONE_MASTER_SERVER}\033[m"
echo ""
fi
echononl " Add CNAME entry for \033[1m${CNAME}\033[m .."
cat <<EOF | nsupdate -v -L3 > $log_file 2>&1
zone $DKIM_UPDATE_ZONE
key ${KEY_ALGO}:$KEY_NAME $KEY_SECRET
update delete ${HOSTNAME}.${DKIM_UPDATE_ZONE}.
update add ${HOSTNAME}.${DKIM_UPDATE_ZONE}. $TTL IN CNAME ${CNAME}
send
EOF
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
cat <<END
Command was:
cat <<EOF | nsupdate -v -L3
cat <<EOF | nsupdate -v -L3 > $log_file 2>&1
zone $DKIM_UPDATE_ZONE
key ${KEY_ALGO}:$KEY_NAME $KEY_SECRET
update delete ${HOSTNAME}.${DKIM_UPDATE_ZONE}.
update add ${HOSTNAME}.${DKIM_UPDATE_ZONE}. $TTL IN CNAME ${CNAME}
send
EOF
END
error "$(cat $log_file)"
fi
info "Flush update data from .jnl files of domain \033[1m${DKIM_UPDATE_ZONE}\033[m back to the zone file:
rndc freeze <zone> - \033[1mrndc freeze ${DKIM_UPDATE_ZONE}\033[m
rndc thaw <zone - \033[1mrndc thaw ${DKIM_UPDATE_ZONE}\033[m"
clean_up 0

View File

@@ -209,6 +209,8 @@ DEFAULT_KEY_NAME="update-dkim"
DEFAULT_DKIM_TYPE="DKIM1"
DEFAULT_KEY_TYPE="rsa"
DEFAULT_SERVICE_TYPE="email"
DEFAULT_DKIM_SELECTOR=""
@@ -288,6 +290,7 @@ if $terminal ; then
done
echo ""
echo -e "\033[32m--\033[m"
echo ""
@@ -303,61 +306,6 @@ if $terminal ; then
done
blank_line
blank_line
echononl " Create (splitted 'p' value of DNS record.."
length="${#DKIM_KEY}"
declare -i pos_begin=0
declare -i pos_end=64
_failed=false
p_val=""
while [[ $pos_end -lt $length ]] ; do
p_val+="\"$(echo "${DKIM_KEY:$pos_begin:64}")\" "
[[ $? -gt 0 ]] && _failed=true
pos_begin=$pos_end
pos_end=$(expr $pos_end + 64)
[[ $? -gt 0 ]] && _failed=true
done
p_val+="\"$(echo "${DKIM_KEY:$pos_begin}")\""
[[ $? -gt 0 ]] && _failed=true
if $_failed ; then
echo_failed
fatal "Cannot create p vaalue of DNS Record"
else
echo_ok
fi
echo ""
echo -e "\033[32m--\033[m"
echo ""
echo -e " Insert DNS master server for domain \033[1m$DKIM_UPDATE_ZONE\033[m"
echo ""
echo ""
if [[ -n "${DEFAULT_KEY_SECRET}" ]] ; then
echononl " DNS master server [${DEFAULT_DNS_DKIM_ZONE_MASTER_SERVER}]: "
read DNS_DKIM_ZONE_MASTER_SERVER
if [[ "X$DNS_DKIM_ZONE_MASTER_SERVER" = "X" ]] ; then
DNS_DKIM_ZONE_MASTER_SERVER="${DEFAULT_DNS_DKIM_ZONE_MASTER_SERVER}"
fi
else
echononl " DNS master server: "
read KEY_SECRET
while [[ "X$KEY_SECRET" = "X" ]] ; do
echo -e "\n\t\033[33m\033[1mEingabe erforderlich.\033[m\n"
echononl " Key secret: "
read KEY_SECRET
done
fi
echo ""
echo -e "\033[32m--\033[m"
@@ -396,6 +344,75 @@ if $terminal ; then
fi
echo ""
echo -e "\033[32m--\033[m"
echo ""
echo -e " Insert DNS master server for domain \033[1m$DKIM_UPDATE_ZONE\033[m"
echo ""
echo ""
if [[ -n "${DEFAULT_DNS_DKIM_ZONE_MASTER_SERVER}" ]] ; then
echononl " DNS master server [${DEFAULT_DNS_DKIM_ZONE_MASTER_SERVER}]: "
read DNS_DKIM_ZONE_MASTER_SERVER
if [[ "X$DNS_DKIM_ZONE_MASTER_SERVER" = "X" ]] ; then
DNS_DKIM_ZONE_MASTER_SERVER="${DEFAULT_DNS_DKIM_ZONE_MASTER_SERVER}"
fi
else
echononl " DNS master server: "
read DNS_DKIM_ZONE_MASTER_SERVER
while [[ "X$DNS_DKIM_ZONE_MASTER_SERVER" = "X" ]] ; do
echo -e "\n\t\033[33m\033[1mEingabe erforderlich.\033[m\n"
echononl " DNS master server: "
read KEY_SECRET
done
fi
echo ""
echo -e "\033[32m--\033[m"
echo ""
echo " Specifies Service type (Flag 's=')"
echo ""
if [[ "email" = "${DEFAULT_SERVICE_TYPE}" ]] ; then
echo -e " [1] \033[37m\033[1ms=email\033[m"
else
echo -e " [1] s=email"
fi
if [[ "*" = "${DEFAULT_SERVICE_TYPE}" ]] ; then
echo -e " [2] \033[37m\033[1ms=*\033[m"
else
echo -e " [2] s=*"
fi
if [[ "" = "${DEFAULT_SERVICE_TYPE}" ]] || [[ "none" = "${DEFAULT_SERVICE_TYPE,,}" ]]; then
echo -e " [3] \033[37m\033[1mDo not include flag for Service Type\033[m"
else
echo -e " [3] Do not include flag for Service Type"
fi
echo ""
echo " Type a number or press <RETURN> to choose highlighted value"
echo ""
echononl " Service type [\033[37m\033[1m${DEFAULT_SERVICE_TYPE}\033[m]: "
while [[ "$SERVICE_TYPE" != "email" ]] \
&& [[ "$SERVICE_TYPE" != "*" ]] \
&& [[ "$SERVICE_TYPE" != "None" ]] ; do
read OPTION
case $OPTION in
1) SERVICE_TYPE="s=email" ;;
2) SERVICE_TYPE="s=*" ;;
3) SERVICE_TYPE="None" ;;
'') SERVICE_TYPE="${DEFAULT_SERVICE_TYPE}" ;;
*) echo ""
echo -e " \033[33m\033[1mFalsche Eingabe ! [ 1 = s=email | 2 = s=* | 3 Omit Service Type ]\033[m"
echo ""
echononl " Service type [\033[37m\033[1m${DEFAULT_SERVICE_TYPE}\033[m]:"
;;
esac
done
echo ""
echo -e "\033[32m--\033[m"
echo ""
@@ -501,6 +518,7 @@ if $terminal ; then
fi
if [[ -z "$(trim "${DKIM_DOMAIN}")" ]]; then
fatal "Variable \033[1mDKIM_DOMAIN\033[m not set!"
fi
@@ -522,6 +540,58 @@ if [[ -z "$(trim "${KEY_SECRET}")" ]]; then
fi
blank_line
blank_line
declare -i length_dkim_key=${#DKIM_KEY}
if [[ "${SERVICE_TYPE,,}" = "none" ]] ; then
_intro="v=${DKIM_TYPE}; k=${KEY_TYPE};"
else
_intro="v=${DKIM_TYPE}; k=${KEY_TYPE}; s=${SERVICE_TYPE};"
fi
declare -i length_intro=${#_intro}
declare -i total_length=$((length_intro + length_dkim_key))
echononl "Create (splitted) 'p' value of DNS record.."
if [[ ${total_length} -gt 255 ]] ; then
TMP_DKIM_KEY="$DKIM_KEY"
p_val=""
_length=64
declare -i index=1
while [ -n "$TMP_DKIM_KEY" ]; do
if [[ index -eq 1 ]]; then
p_val="\"${TMP_DKIM_KEY:0:$_length}\""
else
p_val+=" \"${TMP_DKIM_KEY:0:$_length}\""
fi
TMP_DKIM_KEY="${TMP_DKIM_KEY:$_length}"
(( ++index ))
done
echo_done
# Note:
# !! closing quotation marks are already included !!
#
txt_val="\"${_intro} p=\" ${p_val}"
else
echo_skipped
p_val="${DKIM_KEY}"
txt_val="\"${_intro} p=${p_val}\""
fi
if $terminal ; then
echo ""
@@ -545,10 +615,30 @@ if $terminal ; then
echo ""
echo " DKIM Type........................: $DKIM_TYPE"
echo " Key Type.........................: $KEY_TYPE"
if [[ "${SERVICE_TYPE,,}" = "none" ]] ; then
echo -e " Service Type.....................: \033[33m- Not set -\033[m"
else
echo " Service Type.....................: ${SERVICE_TYPE}"
fi
echo ""
echo " DKIM Key.........................: $DKIM_KEY"
echo -e " \033[1m----------\033[m"
echo ""
echo -e " DNS Record to add:\n\n\033[33m${DKIM_SELECTOR}.${DKIM_UPDATE_ZONE}. ${TTL} IN TXT \"v=${DKIM_TYPE}; k=${KEY_TYPE}; s=email p=\" ${p_val}\033[m"
echo -e " DNS Record to add:\n\n\033[33m${DKIM_SELECTOR}.${DKIM_UPDATE_ZONE}. ${TTL} IN TXT ${txt_val}\033[m"
echo ""
echo -e "\n\n The following 'nsupdate'command will be used:"
cat <<END
cat <<EOF | nsupdate -v -L3
server $DNS_DKIM_ZONE_MASTER_SERVER
zone $DKIM_UPDATE_ZONE
key ${KEY_ALGO}:$KEY_NAME $KEY_SECRET
update delete ${DKIM_SELECTOR}.${DKIM_UPDATE_ZONE}.
update add ${DKIM_SELECTOR}.${DKIM_UPDATE_ZONE}. $TTL IN TXT ${txt_val}
send
EOF
END
echo ""
echo -n " Type upper case 'YES' to start: "
@@ -572,7 +662,7 @@ server $DNS_DKIM_ZONE_MASTER_SERVER
zone $DKIM_UPDATE_ZONE
key ${KEY_ALGO}:$KEY_NAME $KEY_SECRET
update delete ${DKIM_SELECTOR}.${DKIM_UPDATE_ZONE}.
update add ${DKIM_SELECTOR}.${DKIM_UPDATE_ZONE}. ${TTL} IN TXT "v=${DKIM_TYPE}; k=${KEY_TYPE}; s=email; p=" ${p_val}
update add ${DKIM_SELECTOR}.${DKIM_UPDATE_ZONE}. ${TTL} IN TXT ${txt_val}
send
EOF
if [[ $? -eq 0 ]] ; then
@@ -589,7 +679,7 @@ server $DNS_DKIM_ZONE_MASTER_SERVER
zone $DKIM_UPDATE_ZONE
key ${KEY_ALGO}:$KEY_NAME $KEY_SECRET
update delete ${DKIM_SELECTOR}.${DKIM_UPDATE_ZONE}.
update add ${DKIM_SELECTOR}.${DKIM_UPDATE_ZONE}. $TTL IN TXT "v=${DKIM_TYPE}; k=${KEY_TYPE}; s=email; p=" ${p_val}
update add ${DKIM_SELECTOR}.${DKIM_UPDATE_ZONE}. $TTL IN TXT ${txt_val}
send
EOF
END

View File

@@ -0,0 +1,71 @@
# --------------------------------------------------------------
# - Parameter Settings for script 'add_cname_for_dkim_entry.sh'.
# --------------------------------------------------------------
# ----------
# DNS Server
# ----------
# - DNS_DKIM_ZONE_MASTER_SERVER
# -
# - The DNS Server who is serving the update zone and is used
# - for the dynamic updates (nsupdate)
# -
# - Example:
# -
# - DNS_DKIM_ZONE_MASTER_SERVER="b.ns.oopen.de"
# - DNS_DKIM_ZONE_MASTER_SERVER="dns0.warenform.de"
#
#DNS_DKIM_ZONE_MASTER_SERVER=""
# - TTL
# -
# - TTL for the DKIM TXT Record.
# -
# - Defaults to "3600" if update_dns=true
# -
#TTL=3600
# ----------
# TSIG Key
# ----------
# - KEY_SECRET
# -
# - Sectret Key used by 'nsupdate' to create/update the
# - DKIM TXT record.
# -
# - Example:
# -
# - # Key b.ns.oopen.de
# - KEY_SECRET="4woPu0jqf9Jp1IX+gduJ3BVW/1ZMeyCPTQMqEsMXLFw="
# -
# - # Key dns0.warenform.de
# - KEY_SECRET="qG9e/gOucCXcwVUTU+uewU0Yth1iJh2JHgnogrHvh2A="
# -
#KEY_SECRET=""
# - KEY_ALGO
# -
# - The key algorithm used for key creation. Available choices are: hmac-md5,
# - hmac-sha1, hmac-sha224, hmac-sha256, hmac-sha384 and hmac-sha512. The
# - default is hmac-sha256. Options are case-insensitive.
# -
# - Example:
# - KEY_ALGO="hmac-md5"
# -
# - Defaults to 'hmac-sha256'
# -
#KEY_ALGO="hmac-sha256"
# - KEY_NAME
# -
# - Name of the Key
# -
# - Defaults to "$update_zone"
# -
#KEY_NAME="update-dkim"

View File

@@ -18,6 +18,8 @@ log_file="${LOCK_DIR}/${script_name%%.*}.log"
LOGGING=false
BATCH_MODE=false
CONTINUE_WITHOUT_RESPONSIBLE_ZONE=false
DEFAULT_dns_dkim_zone_master_server="b.ns.oopen.de"
DEFAULT_key_algo="hmac-sha256"
DEFAULT_key_name="update-dkim"
@@ -523,7 +525,7 @@ 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
elif [[ -z "$key_secret" ]] ; then
key_secret="${DEFAULT_key_secret}"
fi
if $update_dns && [[ -z "$key_algo" ]]; then
@@ -691,9 +693,44 @@ if $found ; then
info "Found responsible zone for '${dkim_domain}': \033[37m\033[1m${zone}\033[m"
else
echo_failed
fatal "No responsible zone for '${dkim_domain}' found!"
if [[ -n "${dns_main_zone_master_server}" ]] ; then
blank_line
warn "No responsible zone for '${dkim_domain}' found!"
echo " Continue with the following settings:"
echo -e " DNS master for Domain ${dkim_domain}: \033[70G\033[33m${dns_main_zone_master_server}\033[m"
echo -e " DNS slave for Domain ${dkim_domain}: \033[70G\033[33m${dns_dkim_zone_master_server}\033[m"
echo -e " DNS master for Domain ${update_zone}: \033[70G\033[33m${dns_dkim_zone_master_server}\033[m"
echo ""
echo -n " Type upper case 'YES' to start: "
read OK
if [[ "$OK" != "YES" ]] ; then
fatal "Abort by user request - Answer was not 'YES'"
fi
blank_line
CONTINUE_WITHOUT_RESPONSIBLE_ZONE=true
dns_dkim_zone_slave_server_arr+=("${dns_main_zone_master_server}")
_dns_master="${dns_main_zone_master_server}"
_dns_slave="${dns_dkim_zone_master_server}"
if [[ -z "$(dig @${_dns_master} +short ${update_zone}. NS)" ]] ; then
_create_delegation=true
else
_create_delegation=false
fi
else
fatal "No responsible zone for '${dkim_domain}' found!"
fi
fi
if ! ${CONTINUE_WITHOUT_RESPONSIBLE_ZONE} ; then
for _server in $(dig +short ${zone} NS) ; do
# - Eliminate trailing '.' character(s)
# -
@@ -756,6 +793,7 @@ if $update_dns && [[ "$dkim_domain" != "$update_zone" ]] ; then
_create_delegation=false
fi
fi
fi
if $_create_delegation ; then
@@ -769,6 +807,9 @@ if $_create_delegation ; then
fi
echononl "Determin DNS master of '${zone}'.."
if [[ -n "${_dns_master}" ]] ; then
echo_skipped
else
_dns_master="$(dig +short ${zone} SOA 2>/dev/null | awk '{print$1}' | sed 's/\.$//')"
if [[ -z "$_dns_master" ]]; then
echo_failed
@@ -782,6 +823,7 @@ if $_create_delegation ; then
else
echo_ok
fi
fi
# - Check if Nameserver is accessable via ssh
@@ -966,7 +1008,15 @@ if $_create_dkim_zone ; then
$dns_ssh_user@$dns_dkim_zone_master_server "sudo $add_dkim_zone_master_script check" > /dev/null 2>&1
if [[ $? -gt 0 ]] ;then
echo_failed
fatal "Script '$add_dkim_zone_master_script' is NOT accessable via ssh!"
echo -e "\n command was:
ssh -q -p $dns_ssh_port \\
-o BatchMode=yes \\
-o StrictHostKeyChecking=no \\
-i $dns_ssh_key \\
$dns_ssh_user@$dns_dkim_zone_master_server \"sudo $add_dkim_zone_master_script check\"\n"
fatal "Script '$add_dkim_zone_master_script' is NOT accessable via ssh at ${dns_dkim_zone_master_server}!"
else
echo_ok
fi
@@ -1001,12 +1051,21 @@ if $_create_dkim_zone ; then
fi
echononl "Create zone '${update_zone}' at dns master '${dns_dkim_zone_master_server}'.."
echo_wait
if ${CONTINUE_WITHOUT_RESPONSIBLE_ZONE} ; then
ssh -q -p $dns_ssh_port \
-o BatchMode=yes \
-o StrictHostKeyChecking=no \
-i $dns_ssh_key \
$dns_ssh_user@$dns_dkim_zone_master_server "sudo $add_dkim_zone_master_script $dkim_domain -m $_dns_master -s $_dns_slave" > /dev/null 2>&1
ret_val=$?
else
ssh -q -p $dns_ssh_port \
-o BatchMode=yes \
-o StrictHostKeyChecking=no \
-i $dns_ssh_key \
$dns_ssh_user@$dns_dkim_zone_master_server "sudo $add_dkim_zone_master_script $dkim_domain" > /dev/null 2>&1
ret_val=$?
fi
case $ret_val in
0) $terminal && echo_ok
if $terminal ; then
@@ -1210,6 +1269,20 @@ else
error "$(cat $log_file)"
fi
echononl " Print out public key as one line.."
: > ${key_dir}/${dkim_selector}.public.one-line
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}/${dkim_selector}.public.one-line
done < "${key_dir}/${dkim_selector}.public"
echo_ok
generated_files_arr+=("${key_dir}/${dkim_selector}.public.one-line")
# - Generate TXT record for use in bind9
# -
@@ -1236,6 +1309,7 @@ while IFS='' read -r _line || [[ -n $_line ]] ; do
echo "" >> ${key_dir}/${dkim_selector}.bind9
echo -n " \"$_line\"" >> ${key_dir}/${dkim_selector}.bind9
done < "${key_dir}/${dkim_selector}.public"
echo " )" >> ${key_dir}/${dkim_selector}.bind9
echo_ok

154
dmarc-test.sh Executable file
View File

@@ -0,0 +1,154 @@
#!/bin/bash
#
# Einfaches DMARC-Testskript für Postfix + OpenDMARC
# --------------------------------------------------
# Es simuliert eine eingehende Verbindung über 127.0.0.1:10025
# und setzt via XFORWARD eine beliebige Absender-IP.
#
# MODI:
# 1) Presets:
# dmarc-test.sh crsend
# dmarc-test.sh google
#
# 2) Frei:
# dmarc-test.sh IP MAIL_FROM RCPT_TO [FROM_HEADER] [SUBJECT]
#
# Beispiele:
# dmarc-test.sh crsend
# dmarc-test.sh google
#
# dmarc-test.sh 178.77.121.168 newsletter@cadus.org newsletter@cadus.org
# dmarc-test.sh 2607:f8b0:4864:20::114a feray@cadus.org ckubu@cadus.org "Feray <feray@cadus.org>" "Google DMARC Test"
#
SERVER="127.0.0.1"
PORT="10025"
# Pfad zum Mail-Log anpassen, falls bei dir anders
LOGFILE="/var/log/mail.log"
preset="$1"
if [ -z "$preset" ]; then
echo "Usage:"
echo " $0 crsend"
echo " $0 google"
echo " $0 IP MAIL_FROM RCPT_TO [FROM_HEADER] [SUBJECT]"
exit 1
fi
# === Presets auflösen =====================================================
case "$preset" in
crsend)
IP="178.77.121.168"
MAIL_FROM="newsletter@cadus.org"
RCPT_TO="newsletter@cadus.org"
FROM_HEADER="CRSend Test <newsletter@cadus.org>"
SUBJECT="CRSend DMARC Test"
echo "[Preset] CRSend gewählt."
;;
google)
# Beispiel-IP aus deinem Log:
# mail-yw1-x114a.google.com[2607:f8b0:4864:20::114a]
IP="2607:f8b0:4864:20::114a"
MAIL_FROM="feray@cadus.org"
RCPT_TO="ckubu@cadus.org"
FROM_HEADER="Feray <feray@cadus.org>"
SUBJECT="Google Workspace DMARC Test"
echo "[Preset] Google Workspace gewählt."
;;
*)
# Freier Modus
IP="$1"
MAIL_FROM="$2"
RCPT_TO="$3"
FROM_HEADER="$4"
SUBJECT="$5"
;;
esac
# === Argumente im freien Modus prüfen ======================================
if [ "$preset" != "crsend" ] && [ "$preset" != "google" ]; then
if [ -z "$IP" ] || [ -z "$MAIL_FROM" ] || [ -z "$RCPT_TO" ]; then
echo "Usage:"
echo " $0 crsend"
echo " $0 google"
echo " $0 IP MAIL_FROM RCPT_TO [FROM_HEADER] [SUBJECT]"
exit 1
fi
fi
# Defaults setzen, falls leer
if [ -z "$FROM_HEADER" ]; then
FROM_HEADER="$MAIL_FROM"
fi
if [ -z "$SUBJECT" ]; then
SUBJECT="DMARC test from $IP"
fi
if [ ! -f "$LOGFILE" ]; then
echo "WARN: Logfile $LOGFILE existiert nicht. Bitte Pfad im Skript anpassen."
exit 1
fi
echo
echo "== DMARC-Test =="
echo " IP : $IP"
echo " MAIL FROM : $MAIL_FROM"
echo " RCPT TO : $RCPT_TO"
echo " From-Header: $FROM_HEADER"
echo " Subject : $SUBJECT"
echo " Server : $SERVER:$PORT"
echo
# Startposition im Log merken
START_LINES=$(wc -l < "$LOGFILE" 2>/dev/null || echo 0)
# Einzigartige Test-ID für die Mail (zum Wiederfinden im Log, falls nötig)
TEST_ID="DMARC-TEST-$(date +%s)-$$"
# SMTP-Dialog bauen
TMP=$(mktemp)
{
echo "EHLO dmarc-test"
echo "XFORWARD ADDR=$IP NAME=test PROTO=ESMTP HELO=test"
echo "MAIL FROM:<$MAIL_FROM>"
echo "RCPT TO:<$RCPT_TO>"
echo "DATA"
echo "Subject: $SUBJECT"
echo "From: $FROM_HEADER"
echo
echo "$TEST_ID"
echo "Dieser Text ist ein DMARC-Testlauf am $(date)."
echo "."
echo "QUIT"
} > "$TMP"
echo "== Sende Test-Mail über nc …"
nc "$SERVER" "$PORT" < "$TMP"
NC_RC=$?
rm -f "$TMP"
if [ "$NC_RC" -ne 0 ]; then
echo "FEHLER: nc konnte nicht erfolgreich mit $SERVER:$PORT sprechen (rc=$NC_RC)."
exit 1
fi
# Kurz warten, damit Logs geschrieben sind
sleep 2
echo
echo "== OpenDMARC-Logzeilen seit Start des Tests =="
echo "(aus $LOGFILE, gefiltert auf 'opendmarc' und die Queue-ID/Testzeit)"
echo
tail -n +"$((START_LINES+1))" "$LOGFILE" | grep opendmarc || echo "Keine neuen opendmarc-Zeilen gefunden."
echo
echo "Hinweis: Falls du die Mail selbst im Log genauer suchen willst, nutze z.B.:"
echo " grep \"$TEST_ID\" $LOGFILE"

26
resolve-spf-ips.sh Executable file
View File

@@ -0,0 +1,26 @@
#!/usr/bin/env bash
#
# resolve-spf-ips.sh
# ------------------
# Holt alle ip4:/ip6:-Einträge aus dem SPF-TXT-Record
# einer Domain (z.B. spf.crsend.com).
#
# Usage:
# resolve-spf-ips.sh spf.crsend.com
set -e
DOMAIN="$1"
if [[ -z "$DOMAIN" ]]; then
echo "Usage: $0 <domain>" >&2
exit 1
fi
dig +short TXT "$DOMAIN" \
| tr -d '"' \
| sed -n 's/.*v=spf1 //p' \
| tr ' ' '\n' \
| grep -E '^(ip4|ip6):' \
| sed -E 's/^ip[46]://' \
| sort -u