Compare commits

...

13 Commits

Author SHA1 Message Date
b7efde6828 Add script 'dmarc-test.sh'. 2025-11-25 22:44:23 +01:00
bbc25bb1a2 Add script 'resolve-spf-ips.sh'. 2025-11-25 15:18:35 +01:00
b1ca260660 create_opendkim_key.sh: adding DKIM key even if zone is not yet official responsible. 2025-11-05 22:12:32 +01:00
d285b19ab6 Add script 'add_cname_for_dkim_entry.sh'.. 2025-08-23 12:45:34 +02:00
846356d677 add_dkim_key.sh: add support for userdefined 's'-flag - including omittpng it. 2025-06-23 01:04:42 +02:00
9ca9c86b22 add_dkim_key.sh: fix error in setting DNS Master Server. 2025-02-28 00:16:12 +01:00
78a1610517 add_dkim_key.sh: fix error in case long keys (i.e.2048 bit). 2025-02-18 17:57:27 +01:00
e4c9a4fc8f create_opendkim_key.sh: some minor changes in script output. 2025-01-24 02:11:17 +01:00
3019f2d27a create_opendkim_key.sh: fix error: don't ignore secret key from configuration file; add file with public dkim key as one-liner. 2024-06-15 14:58:40 +02:00
1a4ed0053d : s=email; get rid of 's=email; ' inside DKIM TXT record. 2024-03-29 15:56:30 +01:00
20cc3cdc2d add_dkim_key.sh: Don't split txt value if its length is lower than '255'. 2024-03-29 15:19:28 +01:00
ed3c51946a get_number_of_deferred_mailqueue.sh: change default warn warn value. 2024-03-29 13:34:50 +01:00
4788537cd9 create_opendkim_key.sh: Support custom selector; some changes on script output. 2024-03-29 13:33:48 +01:00
7 changed files with 1342 additions and 194 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_DKIM_TYPE="DKIM1"
DEFAULT_KEY_TYPE="rsa" DEFAULT_KEY_TYPE="rsa"
DEFAULT_SERVICE_TYPE="email"
DEFAULT_DKIM_SELECTOR="" DEFAULT_DKIM_SELECTOR=""
@@ -288,6 +290,7 @@ if $terminal ; then
done done
echo "" echo ""
echo -e "\033[32m--\033[m" echo -e "\033[32m--\033[m"
echo "" echo ""
@@ -303,61 +306,6 @@ if $terminal ; then
done 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 ""
echo -e "\033[32m--\033[m" echo -e "\033[32m--\033[m"
@@ -396,6 +344,75 @@ if $terminal ; then
fi 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 ""
echo -e "\033[32m--\033[m" echo -e "\033[32m--\033[m"
echo "" echo ""
@@ -501,6 +518,7 @@ if $terminal ; then
fi fi
if [[ -z "$(trim "${DKIM_DOMAIN}")" ]]; then if [[ -z "$(trim "${DKIM_DOMAIN}")" ]]; then
fatal "Variable \033[1mDKIM_DOMAIN\033[m not set!" fatal "Variable \033[1mDKIM_DOMAIN\033[m not set!"
fi fi
@@ -522,6 +540,58 @@ if [[ -z "$(trim "${KEY_SECRET}")" ]]; then
fi 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 if $terminal ; then
echo "" echo ""
@@ -545,10 +615,30 @@ if $terminal ; then
echo "" echo ""
echo " DKIM Type........................: $DKIM_TYPE" echo " DKIM Type........................: $DKIM_TYPE"
echo " Key Type.........................: $KEY_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 -e " \033[1m----------\033[m"
echo "" 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 ""
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 ""
echo -n " Type upper case 'YES' to start: " echo -n " Type upper case 'YES' to start: "
@@ -572,7 +662,7 @@ server $DNS_DKIM_ZONE_MASTER_SERVER
zone $DKIM_UPDATE_ZONE zone $DKIM_UPDATE_ZONE
key ${KEY_ALGO}:$KEY_NAME $KEY_SECRET key ${KEY_ALGO}:$KEY_NAME $KEY_SECRET
update delete ${DKIM_SELECTOR}.${DKIM_UPDATE_ZONE}. 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 send
EOF EOF
if [[ $? -eq 0 ]] ; then if [[ $? -eq 0 ]] ; then
@@ -589,7 +679,7 @@ server $DNS_DKIM_ZONE_MASTER_SERVER
zone $DKIM_UPDATE_ZONE zone $DKIM_UPDATE_ZONE
key ${KEY_ALGO}:$KEY_NAME $KEY_SECRET key ${KEY_ALGO}:$KEY_NAME $KEY_SECRET
update delete ${DKIM_SELECTOR}.${DKIM_UPDATE_ZONE}. 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 send
EOF EOF
END 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

@@ -17,7 +17,13 @@ log_file="${LOCK_DIR}/${script_name%%.*}.log"
# - # -
LOGGING=false LOGGING=false
BATCH_MODE=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_algo="hmac-sha256"
DEFAULT_key_name="update-dkim"
DEFAULT_key_secret="4woPu0jqf9Jp1IX+gduJ3BVW/1ZMeyCPTQMqEsMXLFw="
DEFAULT_ttl="43200" DEFAULT_ttl="43200"
DEFAULT_dns_ssh_user="manage-bind" DEFAULT_dns_ssh_user="manage-bind"
@@ -29,11 +35,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_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" 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" # - We use actual timestamp as DEKIM Selector
key_table_file="${opendkim_dir}/key.table" # -
key_base_dir=${opendkim_dir}/keys DEFAULT_dkim_selector=$(date +%s)
DEFAULT_opendkim_dir="/etc/opendkim"
@@ -119,7 +126,25 @@ usage() {
clean_up() { 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 # Perform program exit housekeeping
rm -rf "$LOCK_DIR" rm -rf "$LOCK_DIR"
blank_line blank_line
exit $1 exit $1
@@ -241,6 +266,17 @@ containsElement () {
return 1 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 # - Remove leading/trailling whitespaces
# - # -
trim() { trim() {
@@ -276,7 +312,7 @@ delete_generated_files() {
# - Run 'clean_up' for signals SIGHUP SIGINT SIGTERM # - 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" # - Create lock directory '$LOCK_DIR"
# #
@@ -418,6 +454,8 @@ elif $update_dns && $terminal ; then
echo -e "\033[32m--\033[m" echo -e "\033[32m--\033[m"
info "Zone \033[37m\033[1m${update_zone}\033[m is used for DKIM TXT record" info "Zone \033[37m\033[1m${update_zone}\033[m is used for DKIM TXT record"
fi fi
else
update_zone="_domainkey.${dkim_domain}"
fi fi
@@ -487,15 +525,23 @@ if $update_dns && [[ -z "$update_zone" ]] ; then
fi fi
if $update_dns && [[ -z "$key_secret" ]] ; then if $update_dns && [[ -z "$key_secret" ]] ; then
fatal "No secret for the update key used by nsupdate is given!" fatal "No secret for the update key used by nsupdate is given!"
elif [[ -z "$key_secret" ]] ; then
key_secret="${DEFAULT_key_secret}"
fi fi
if $update_dns && [[ -z "$key_algo" ]]; then if $update_dns && [[ -z "$key_algo" ]]; then
key_algo="$DEFAULT_key_algo" key_algo="$DEFAULT_key_algo"
else
key_algo="${DEFAULT_key_algo}"
fi fi
if $update_dns && [[ -z "$key_name" ]]; then if $update_dns && [[ -z "$key_name" ]]; then
key_name="$update_zone" key_name="${DEFAULT_key_name}"
else
key_name="${DEFAULT_key_name}"
fi fi
if $update_dns && [[ -z "$ttl" ]]; then if $update_dns && [[ -z "$ttl" ]]; then
ttl="$DEFAULT_ttl" ttl="$DEFAULT_ttl"
else
ttl="$DEFAULT_ttl"
fi fi
if $update_dns && [[ -z "$dns_dkim_zone_master_server" ]]; then if $update_dns && [[ -z "$dns_dkim_zone_master_server" ]]; then
fatal "No DNS server for updating given!" fatal "No DNS server for updating given!"
@@ -521,17 +567,46 @@ fi
blank_line 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 echo ""
# - echo ""
time_stamp=$(date +%s) 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 if $terminal ; then
echo "" echo ""
echo -e " \033[1m----------\033[m" echo -e " \033[1m----------\033[m"
echo " DKIM Domain......................: $dkim_domain" echo " DKIM Domain......................: $dkim_domain"
echo " DKIM Selector....................: $time_stamp" echo " DKIM Selector....................: $dkim_selector"
if $update_dns ; then if $update_dns ; then
echo -e " Create/Update DKIM TXT record....: \033[32mYes\033[m" echo -e " Create/Update DKIM TXT record....: \033[32mYes\033[m"
echo " Domain used for DKIM TXT record..: $update_zone" echo " Domain used for DKIM TXT record..: $update_zone"
@@ -542,7 +617,11 @@ if $terminal ; then
echo -e " Create/Update DKIM TXT record....: \033[33mNo\033[m" echo -e " Create/Update DKIM TXT record....: \033[33mNo\033[m"
fi fi
echo "" 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 if [[ -z "$ttl" ]] || [[ "${ttl,,}" = "none" ]] ; then
echo -e " TTL for the DKIM TXT Record......: \033[33m- Not set -\033[m" echo -e " TTL for the DKIM TXT Record......: \033[33m- Not set -\033[m"
else else
@@ -614,69 +693,105 @@ if $found ; then
info "Found responsible zone for '${dkim_domain}': \033[37m\033[1m${zone}\033[m" info "Found responsible zone for '${dkim_domain}': \033[37m\033[1m${zone}\033[m"
else else
echo_failed 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 fi
for _server in $(dig +short ${zone} NS) ; do if ! ${CONTINUE_WITHOUT_RESPONSIBLE_ZONE} ; then
# - Eliminate trailing '.' character(s) for _server in $(dig +short ${zone} NS) ; do
# - # - Eliminate trailing '.' character(s)
_server="${_server%"${_server##*[!\.]}"}" # -
_server="${_server%"${_server##*[!\.]}"}"
[[ "$_server" = "$dns_dkim_zone_master_server" ]] && continue [[ "$_server" = "$dns_dkim_zone_master_server" ]] && continue
dns_dkim_zone_slave_server_arr+=("$_server") dns_dkim_zone_slave_server_arr+=("$_server")
done done
_wait=false _wait=false
if $update_dns && [[ "$dkim_domain" != "$update_zone" ]] ; then if $update_dns && [[ "$dkim_domain" != "$update_zone" ]] ; then
if [[ -z "$(dig +short ${update_zone}. NS)" ]] ; then if [[ -z "$(dig +short ${update_zone}. NS)" ]] ; then
warn "No Subdomain delegation for zone '$update_zone' found!" warn "No Subdomain delegation for zone '$update_zone' found!"
if ! $BATCH_MODE ; then if ! $BATCH_MODE ; then
echo "" echo ""
echo -e "\033[32m--\033[m" echo -e "\033[32m--\033[m"
echo "" echo ""
echononl "Create Subdomain delegation for zone '$update_zone'? (yes/no) [yes]: " echononl "Create Subdomain delegation for zone '$update_zone'? (yes/no) [yes]: "
read _create_delegation read _create_delegation
if [[ -z "$(trim $_create_delegation)" ]] ; then if [[ -z "$(trim $_create_delegation)" ]] ; then
_create_delegation=true _create_delegation=true
elif [[ "${_create_delegation,,}" = "yes" ]] || [[ "${_create_delegation,,}" = "true" ]] ; then elif [[ "${_create_delegation,,}" = "yes" ]] || [[ "${_create_delegation,,}" = "true" ]] ; then
_create_delegation=true _create_delegation=true
else
_create_delegation=false
fi
if ! $_create_delegation ; then
_tmp_string="; ----- Delegation DKIM Keys ${dkim_domain}"
for _server in $(dig +short ${dkim_domain} NS) ; do
# - Eliminate trailing '.' character(s)
# -
_server="${_server%"${_server##*[!\.]}"}"
_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 <return> to continue or <CTRL>+C to abort:\033[m "
read OK
echo
fi
else else
_create_delegation=false _create_delegation=true
fi
if ! $_create_delegation ; then
_tmp_string="; ----- Delegation DKIM Keys ${dkim_domain}"
for _server in $(dig +short ${dkim_domain} NS) ; do
# - Eliminate trailing '.' character(s)
# -
_server="${_server%"${_server##*[!\.]}"}"
_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 <return> to continue or <CTRL>+C to abort:\033[m "
read OK
echo
fi fi
else else
_create_delegation=true _create_delegation=false
fi fi
else
_create_delegation=false
fi fi
fi fi
@@ -692,18 +807,22 @@ if $_create_delegation ; then
fi fi
echononl "Determin DNS master of '${zone}'.." echononl "Determin DNS master of '${zone}'.."
_dns_master="$(dig +short ${zone} SOA 2>/dev/null | awk '{print$1}' | sed 's/\.$//')" if [[ -n "${_dns_master}" ]] ; then
if [[ -z "$_dns_master" ]]; then echo_skipped
echo_failed
if $terminal ; then
fatal "Determin DNS master of '${zone}' failed!"
else
echo -e " [ Fatal ] Found responsible zone for '${dkim_domain}' (${zone}), but"
echo -e " cannot determin master dns server for '${zone}'!"
clean_up 1
fi
else else
echo_ok _dns_master="$(dig +short ${zone} SOA 2>/dev/null | awk '{print$1}' | sed 's/\.$//')"
if [[ -z "$_dns_master" ]]; then
echo_failed
if $terminal ; then
fatal "Determin DNS master of '${zone}' failed!"
else
echo -e " [ Fatal ] Found responsible zone for '${dkim_domain}' (${zone}), but"
echo -e " cannot determin master dns server for '${zone}'!"
clean_up 1
fi
else
echo_ok
fi
fi fi
@@ -889,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 $dns_ssh_user@$dns_dkim_zone_master_server "sudo $add_dkim_zone_master_script check" > /dev/null 2>&1
if [[ $? -gt 0 ]] ;then if [[ $? -gt 0 ]] ;then
echo_failed 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 else
echo_ok echo_ok
fi fi
@@ -924,12 +1051,21 @@ if $_create_dkim_zone ; then
fi fi
echononl "Create zone '${update_zone}' at dns master '${dns_dkim_zone_master_server}'.." echononl "Create zone '${update_zone}' at dns master '${dns_dkim_zone_master_server}'.."
echo_wait echo_wait
ssh -q -p $dns_ssh_port \ if ${CONTINUE_WITHOUT_RESPONSIBLE_ZONE} ; then
-o BatchMode=yes \ ssh -q -p $dns_ssh_port \
-o StrictHostKeyChecking=no \ -o BatchMode=yes \
-i $dns_ssh_key \ -o StrictHostKeyChecking=no \
$dns_ssh_user@$dns_dkim_zone_master_server "sudo $add_dkim_zone_master_script $dkim_domain" > /dev/null 2>&1 -i $dns_ssh_key \
ret_val=$? $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 case $ret_val in
0) $terminal && echo_ok 0) $terminal && echo_ok
if $terminal ; then if $terminal ; then
@@ -1066,7 +1202,7 @@ fi
# - # -
echononl " Create Key Directory '${key_dir}'" echononl " Create Key Directory '${key_dir}'"
if [[ ! -d "$key_dir" ]]; then if [[ ! -d "$key_dir" ]]; then
mkdir $key_dir 2> $log_file mkdir -p $key_dir 2> $log_file
if [[ $? -eq 0 ]] ; then if [[ $? -eq 0 ]] ; then
echo_ok echo_ok
else else
@@ -1089,11 +1225,11 @@ fi
# - 'bind' nameservers (TXT recors are restricted to 255 characters) # - 'bind' nameservers (TXT recors are restricted to 255 characters)
# - # -
echononl " Generate private key for domain '$dkim_domain'.." 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 if [[ $? -eq 0 ]] ; then
echo_ok echo_ok
generated_files_arr+=("${key_dir}/${time_stamp}.private") generated_files_arr+=("${key_dir}/${dkim_selector}.private")
generated_files_arr+=("${key_dir}/${time_stamp}.txt") generated_files_arr+=("${key_dir}/${dkim_selector}.txt")
else else
echo_failed echo_failed
error "$(cat $log_file)" error "$(cat $log_file)"
@@ -1101,16 +1237,20 @@ fi
# - Set up ownership an permissions # - Set up ownership an permissions
# - # -
echononl " Set ownership on '${key_dir}/${time_stamp}.private'" echononl " Set ownership on '${key_dir}/${dkim_selector}.private'"
chown opendkim ${key_dir}/${time_stamp}.private > $log_file 2>&1 if id -u "opendkim" >/dev/null 2>&1; then
if [[ $? -eq 0 ]] ; then chown opendkim ${key_dir}/${dkim_selector}.private > $log_file 2>&1
echo_ok if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else else
echo_failed echo_skipped
error "$(cat $log_file)"
fi fi
echononl " Set permissions on '${key_dir}/${time_stamp}.private'" echononl " Set permissions on '${key_dir}/${dkim_selector}.private'"
chmod 600 ${key_dir}/${time_stamp}.private > $log_file 2>&1 chmod 600 ${key_dir}/${dkim_selector}.private > $log_file 2>&1
if [[ $? -eq 0 ]] ; then if [[ $? -eq 0 ]] ; then
echo_ok echo_ok
else else
@@ -1120,15 +1260,29 @@ fi
echononl " Print out public key for domain '$dkim_domain'.." 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 if [[ $? -eq 0 ]] ; then
echo_ok echo_ok
generated_files_arr+=("${key_dir}/${time_stamp}.public ") generated_files_arr+=("${key_dir}/${dkim_selector}.public ")
else else
echo_failed echo_failed
error "$(cat $log_file)" error "$(cat $log_file)"
fi 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 # - Generate TXT record for use in bind9
# - # -
@@ -1143,22 +1297,23 @@ fi
if $terminal ; then if $terminal ; then
echo " Write bind9 dekim TXT record to file" echo " Write bind9 dekim TXT record to file"
fi fi
echononl " '${key_dir}/${time_stamp}.bind9'" echononl " '${key_dir}/${dkim_selector}.bind9'"
echo "; ----- DKIM key $time_stamp for ${dkim_domain}" > ${key_dir}/${time_stamp}.bind9 echo "; ----- DKIM key $dkim_selector for ${dkim_domain}" > ${key_dir}/${dkim_selector}.bind9
echo -n "${time_stamp}._domainkey.${dkim_domain}. $ttl IN TXT ( \"v=DKIM1; k=rsa; s=email; p=\"" >> ${key_dir}/${time_stamp}.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 while IFS='' read -r _line || [[ -n $_line ]] ; do
if echo "$_line" | grep -i -q -E "^---" 2> /dev/null ; then if echo "$_line" | grep -i -q -E "^---" 2> /dev/null ; then
continue continue
fi fi
echo "" >> ${key_dir}/${time_stamp}.bind9 echo "" >> ${key_dir}/${dkim_selector}.bind9
echo -n " \"$_line\"" >> ${key_dir}/${time_stamp}.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 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' # - Write TXT record as string for 'nsupdate'
# - # -
@@ -1166,32 +1321,65 @@ if $terminal ; then
echo " Write TXT record as string for 'nsupdate' to file" echo " Write TXT record as string for 'nsupdate' to file"
fi fi
echononl " '${key_dir}/${time_stamp}.nsupdate'" echononl " '${key_dir}/${dkim_selector}.nsupdate'"
echo -n "\"v=DKIM1; k=rsa; s=email; p=\"" >> ${key_dir}/${time_stamp}.nsupdate echo -n "\"v=DKIM1; k=rsa; s=email; p=\"" >> ${key_dir}/${dkim_selector}.nsupdate
while IFS='' read -r _line || [[ -n $_line ]] ; do while IFS='' read -r _line || [[ -n $_line ]] ; do
if echo "$_line" | grep -i -q -E "^---" 2> /dev/null ; then if echo "$_line" | grep -i -q -E "^---" 2> /dev/null ; then
continue continue
fi 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 echo_ok
generated_files_arr+=("${key_dir}/${time_stamp}.nsupdate") generated_files_arr+=("${key_dir}/${dkim_selector}.nsupdate")
if ! $update_dns ; then if ! $update_dns ; then
[[ -z "${dns_dkim_zone_master_server}" ]] && dns_dkim_zone_master_server=${DEFAULT_dns_dkim_zone_master_server}
blank_line 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 ""
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 "To cancel at this point, enter 'no' or press Ctrl-C."
echo "" echo ""
echo -n "Type <return> to continue: " echo -n "Continue? [yes/no]: "
read OK 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 fi
@@ -1212,8 +1400,8 @@ if $update_dns ; then
server $dns_dkim_zone_master_server server $dns_dkim_zone_master_server
zone $update_zone zone $update_zone
key ${key_algo}:$key_name $key_secret key ${key_algo}:$key_name $key_secret
update delete ${time_stamp}.${update_zone}. update delete ${dkim_selector}.${update_zone}.
update add ${time_stamp}.${update_zone}. $ttl IN TXT $(cat ${key_dir}/${time_stamp}.nsupdate) update add ${dkim_selector}.${update_zone}. $ttl IN TXT $(cat ${key_dir}/${dkim_selector}.nsupdate)
send send
EOF EOF
if [[ $? -eq 0 ]] ; then if [[ $? -eq 0 ]] ; then
@@ -1225,21 +1413,21 @@ cat <<EOF | nsupdate -v -L3
server $dns_dkim_zone_master_server server $dns_dkim_zone_master_server
zone $update_zone zone $update_zone
key ${key_algo}:$key_name $key_secret key ${key_algo}:$key_name $key_secret
update delete ${time_stamp}.${update_zone}. update delete ${dkim_selector}.${update_zone}.
update add ${time_stamp}.${update_zone}. $ttl IN TXT $(cat ${key_dir}/${time_stamp}.nsupdate) update add ${dkim_selector}.${update_zone}. $ttl IN TXT $(cat ${key_dir}/${dkim_selector}.nsupdate)
send send
EOF EOF
END END
cat <<END > ${key_dir}/${time_stamp}.nsupdate.command cat <<END > ${key_dir}/${dkim_selector}.nsupdate.command
cat <<EOF | nsupdate -v -L3 cat <<EOF | nsupdate -v -L3
server $dns_dkim_zone_master_server server $dns_dkim_zone_master_server
zone $update_zone zone $update_zone
key ${key_algo}:$key_name $key_secret key ${key_algo}:$key_name $key_secret
update delete ${time_stamp}.${update_zone}. update delete ${dkim_selector}.${update_zone}.
update add ${time_stamp}.${update_zone}. $ttl IN TXT $(cat ${key_dir}/${time_stamp}.nsupdate) update add ${dkim_selector}.${update_zone}. $ttl IN TXT $(cat ${key_dir}/${dkim_selector}.nsupdate)
send send
EOF EOF
@@ -1253,8 +1441,8 @@ cat <<EOF | nsupdate -v -L3
server $dns_dkim_zone_master_server server $dns_dkim_zone_master_server
zone $update_zone zone $update_zone
key ${key_algo}:$key_name $key_secret key ${key_algo}:$key_name $key_secret
update delete ${time_stamp}.${update_zone}. update delete ${dkim_selector}.${update_zone}.
update add ${time_stamp}.${update_zone}. $ttl IN TXT $(cat ${key_dir}/${time_stamp}.nsupdate) update add ${dkim_selector}.${update_zone}. $ttl IN TXT $(cat ${key_dir}/${dkim_selector}.nsupdate)
send send
EOF EOF
END END
@@ -1313,7 +1501,7 @@ fi
# - # -
echononl " Configure/Adjust key table" echononl " Configure/Adjust key table"
if grep -q -E "^\s*$dkim_domain_shortname\s" $key_table_file 2>/dev/null ; then 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 if [[ $? -eq 0 ]] ; then
echo_ok echo_ok
else else
@@ -1321,7 +1509,7 @@ if grep -q -E "^\s*$dkim_domain_shortname\s" $key_table_file 2>/dev/null ; then
error "$(cat $log_file)" error "$(cat $log_file)"
fi fi
else 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 if [[ $? -eq 0 ]] ; then
echo_ok echo_ok
else else
@@ -1331,7 +1519,7 @@ else
fi fi
echononl " Adjust file ${key_dir}/generated_keys.selectors" 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 echo_done
@@ -1370,13 +1558,13 @@ fi
if $terminal ; then if $terminal ; then
info "DKIM Key for domain \033[1m${dkim_domain}\033[m created/updated." info "DKIM Key for domain \033[1m${dkim_domain}\033[m created/updated."
if $update_dns ; then 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 fi
else else
echo "" echo ""
echo " [ Info ] DKIM Key for domain ${dkim_domain} created/updated." echo " [ Info ] DKIM Key for domain ${dkim_domain} created/updated."
echo "" echo ""
echo " [ Info ] DKIM TXT Record with selector $time_stamp created." echo " [ Info ] DKIM TXT Record with selector $dkim_selector created."
echo "" echo ""
fi fi
@@ -1386,7 +1574,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_1=${txt_record:0:255}
#txt_record_2=${txt_record:255} #txt_record_2=${txt_record:255}
#new_txt_record="\"$txt_record_1\"\"$txt_record_2\"" #new_txt_record="\"$txt_record_1\"\"$txt_record_2\""

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"

View File

@@ -14,12 +14,12 @@ host_name=`hostname -f`
from_address="postfix@$host_name" from_address="postfix@$host_name"
content_type='Content-Type: text/plain;\n charset="utf-8"' content_type='Content-Type: text/plain;\n charset="utf-8"'
default_notification_addresses="argus@oopen.de"
postfix_queue_dir=/var/spool/postfix postfix_queue_dir=/var/spool/postfix
declare -i count_warn declare -i count_warn
declare -i default_count_warn=80
default_notification_addresses="argus@oopen.de"
declare -i default_count_warn=100
# ---------- # ----------

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