Skip to content

Instantly share code, notes, and snippets.

@cendyne
Created Aug 15, 2021
Embed
What would you like to do?
#!/bin/bash
HOST=mail.cendyne.dev
TELEGRAM_CHAT_ID=REDACTED
TELEGRAM_BOT_TOKEN=REDACTED
getSig() {
sig=$(openssl x509 -pubkey -noout | openssl base64 -d | openssl dgst -sha256 -binary | xxd -u -p -c 100000)
echo "3 1 1 $sig"
}
getHttpsSig() {
echo | openssl s_client -connect "$1:443" -servername "$1" -showcerts 2>/dev/null | getSig
}
getSmtpSig() {
echo | openssl s_client -connect "$1:25" -starttls smtp -showcerts 2>/dev/null | getSig
}
verifySmtpSig() {
local -n args=$2
result=$(openssl s_client -starttls smtp -connect "$1:25" -dane_tlsa_domain "$1" "${args[@]}" </dev/null 2>/dev/null \
| grep "Verify return code" | head -n 1)
if [[ "$result" == "Verify return code: 0 (ok)" ]]; then
return 0
else
echo "$result"
return 1
fi
}
verifyHttpsSig() {
local -n args=$2
result=$(openssl s_client -connect "$1:443" -servername "$1" -dane_tlsa_domain "$1" "${args[@]}" </dev/null 2>/dev/null \
| grep "Verify return code" | head -n 1)
if [[ "$result" == "Verify return code: 0 (ok)" ]]; then
return 0
else
echo "$result"
return 1
fi
}
reformatDigTLSA() {
local -r tlsa_pat='([[:digit:]]+)[[:space:]]+([[:digit:]]+)[[:space:]]+([[:digit:]]+)[[:space:]]+(.+)$'
while read -r line; do
if [[ "$line" =~ $tlsa_pat ]]; then
tlsa_usage="${BASH_REMATCH[1]}"
tlsa_selector="${BASH_REMATCH[2]}"
tlsa_matching="${BASH_REMATCH[3]}"
tlsa_cadata="${BASH_REMATCH[4]}"
tlsa_cadata="${tlsa_cadata// /}"
echo "$tlsa_usage $tlsa_selector $tlsa_matching $tlsa_cadata"
fi
done
}
getTLSA() {
dig tlsa "_$2._tcp.$1" +short | reformatDigTLSA
}
sendTelegramMessage() {
MSG=$(echo -e "$1")
json=$(jq -n --arg chat "$TELEGRAM_CHAT_ID" --arg msg "$MSG" '{"chat_id":$chat,"text":$msg,"parse_mode":"MarkdownV2"}')
curl -X POST "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendMessage" \
-H "Content-Type: application/json" \
--data "$json" 2>/dev/null >/dev/null
}
TLSA_25=$(getTLSA "$HOST" 25)
TLSA_443=$(getTLSA "$HOST" 443)
function verify() {
local command="$1"
local lines="$2"
local -a DANE_PARAMS
OLD_IFS="$IFS"
IFS=$'\n'
for line in $lines; do
DANE_PARAMS+=(-dane_tlsa_rrdata)
DANE_PARAMS+=("$line")
done
IFS="$OLD_IFS"
verification=$($command "$HOST" DANE_PARAMS)
STATUS=$?
if [[ $STATUS != 0 ]]; then
echo "$verification"
fi
return $STATUS
}
VERIFY_ERROR=false
verify verifySmtpSig "$TLSA_25"
if [[ $? != 0 ]]; then
SMTP=$(getSmtpSig "$HOST")
echo "SMTP NOT MATCH FAILED, please review!"
dig tlsa "_25._tcp.$HOST"
echo -e "versus\n$SMTP"
sendTelegramMessage "SMTP TLSA Record does not match the current server, currently it sees:
\`\`\`\n$TLSA_25\n\`\`\`
But I expect to see \`$SMTP\`"
VERIFY_ERROR=true
fi
verify verifyHttpsSig "$TLSA_443"
if [[ $? != 0 ]]; then
HTTPS=$(getHttpsSig "$HOST")
echo "HTTPS MATCH_FAILED, please review!"
dig tlsa "_443._tcp.$HOST"
echo -e "versus\n$HTTPS"
sendTelegramMessage "HTTPS TLSA Record does not match the current server, currently it sees:
\`\`\`\n$TLSA_443\n\`\`\`
But I expect to see \`$HTTPS\`"
VERIFY_ERROR=true
fi
if [[ "$VERIFY_ERROR" == "true" ]]; then
exit 1
fi
lines=$(echo "$TLSA_25" | wc -l)
if (( "$lines" < 1 || "$lines" > 2 )); then
echo -e "Warning, SMTP lines count $lines is not within [1,2]\n$TLSA_25"
fi
lines=$(echo "$TLSA_443" | wc -l)
if (( "$lines" < 1 || "$lines" > 2 )); then
echo -e "Warning, HTTPS lines count $lines is not within [1,2]\n$TLSA_443"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment