Skip to content

Instantly share code, notes, and snippets.

@dkrusky
Created April 10, 2026 07:53
Show Gist options
  • Select an option

  • Save dkrusky/2133fd9019da79dfc84efe19affadd22 to your computer and use it in GitHub Desktop.

Select an option

Save dkrusky/2133fd9019da79dfc84efe19affadd22 to your computer and use it in GitHub Desktop.
Quickly generate and verify DANE/TLSA/etc
#!/bin/bash
# Usage:
# ./generate-tlsa.sh /path/to/cert.pem
#
# Output:
# TLSA values for:
# selector 0 / matchtype 0,1,2
# selector 1 / matchtype 0,1,2
CERT="$1"
if [ -z "$CERT" ]; then
echo "Usage: $0 /path/to/cert.pem"
exit 1
fi
if [ ! -f "$CERT" ]; then
echo "File not found: $CERT"
exit 1
fi
# Convert PEM → DER
openssl x509 -in "$CERT" -outform DER > cert.der
# Extract SPKI (SubjectPublicKeyInfo)
openssl x509 -in "$CERT" -pubkey -noout \
| openssl pkey -pubin -outform DER > spki.der
echo "===================================================="
echo " TLSA Generator for: $CERT"
echo "===================================================="
echo
# Helper function
hex() {
xxd -p -c 9999 "$1" | tr -d '\n'
}
sha256() {
openssl sha256 -binary "$1" | xxd -p -c 9999 | tr -d '\n'
}
sha512() {
openssl sha512 -binary "$1" | xxd -p -c 9999 | tr -d '\n'
}
echo "Selector 0 (Full Certificate)"
echo "-----------------------------"
echo "Matchtype 0 (Exact):"
echo " $(hex cert.der)"
echo
echo "Matchtype 1 (SHA-256):"
echo " $(sha256 cert.der)"
echo
echo "Matchtype 2 (SHA-512):"
echo " $(sha512 cert.der)"
echo
echo "Selector 1 (SPKI)"
echo "-----------------------------"
echo "Matchtype 0 (Exact):"
echo " $(hex spki.der)"
echo
echo "Matchtype 1 (SHA-256):"
echo " $(sha256 spki.der)"
echo
echo "Matchtype 2 (SHA-512):"
echo " $(sha512 spki.der)"
echo
echo "===================================================="
echo " Done — copy the value you need into your TLSA record"
echo "===================================================="
#!/bin/bash
# Usage: ./verify-mail-security.sh domain.com
DOMAIN="$1"
if [ -z "$DOMAIN" ]; then
echo "Usage: $0 domain.com"
exit 1
fi
POLICY_URL="https://mta-sts.${DOMAIN}/.well-known/mta-sts.txt"
MTA_STS_TXT="_mta-sts.${DOMAIN}"
TLS_RPT_TXT="_smtp._tls.${DOMAIN}"
echo "===================================================="
echo " Checking Mail Security for: $DOMAIN"
echo "===================================================="
echo
echo "1) Checking MTA-STS DNS TXT record (${MTA_STS_TXT})"
echo "----------------------------------------------------"
dig +short TXT ${MTA_STS_TXT}
echo
echo "2) Checking TLS-RPT DNS TXT record (${TLS_RPT_TXT})"
echo "----------------------------------------------------"
dig +short TXT ${TLS_RPT_TXT}
echo
echo "3) Checking MX records"
echo "----------------------------------------------------"
MX_HOSTS=$(dig +short MX ${DOMAIN} | awk '{print $2}' | sed 's/\.$//')
echo "$MX_HOSTS"
echo
echo "4) Fetching MTA-STS HTTPS policy"
echo "----------------------------------------------------"
curl -s -D headers_mta_sts.txt "${POLICY_URL}" -o mta_sts_policy.txt
echo
echo "5) Checking TLS certificate for mta-sts.${DOMAIN}"
echo "----------------------------------------------------"
echo | openssl s_client -connect mta-sts.${DOMAIN}:443 -servername mta-sts.${DOMAIN} 2>/dev/null \
| openssl x509 -noout -dates -issuer -subject
echo
echo "6) Checking DANE TLSA records and validating against MX certificates"
echo "----------------------------------------------------"
for MX in $MX_HOSTS; do
echo "MX Host: $MX"
dig +short TLSA _25._tcp.${MX} > tlsa_raw.txt
if [ ! -s tlsa_raw.txt ]; then
echo " No TLSA records found (DANE not enabled)"
echo
continue
fi
echo " TLSA Records:"
sed 's/^/ /' tlsa_raw.txt
echo " Fetching certificate via STARTTLS..."
CERT_DER="cert_${MX}.der"
echo | openssl s_client -starttls smtp -connect ${MX}:25 -servername ${MX} 2>/dev/null \
| openssl x509 -outform DER > "$CERT_DER"
if [ ! -s "$CERT_DER" ]; then
echo " ERROR: Could not retrieve certificate"
echo
continue
fi
while read -r line; do
# Parse usage, selector, matchtype
usage=$(echo "$line" | awk '{print $1}')
selector=$(echo "$line" | awk '{print $2}')
matchtype=$(echo "$line" | awk '{print $3}')
# Join all remaining fields into one hex string
data=$(echo "$line" | cut -d' ' -f4- | tr -d ' ')
echo " TLSA: usage=$usage selector=$selector matchtype=$matchtype"
echo " Data: $data"
# Determine data to hash
if [ "$selector" = "0" ]; then
tohash="$CERT_DER"
elif [ "$selector" = "1" ]; then
SPKI_DER="spki_${MX}.der"
openssl x509 -in "$CERT_DER" -inform DER -pubkey -noout \
| openssl pkey -pubin -outform DER > "$SPKI_DER"
tohash="$SPKI_DER"
else
echo " ✘ Invalid selector"
continue
fi
# Compute hash
if [ "$matchtype" = "0" ]; then
hash=$(xxd -p -c 9999 "$tohash")
elif [ "$matchtype" = "1" ]; then
hash=$(openssl sha256 -binary "$tohash" | xxd -p -c 9999)
elif [ "$matchtype" = "2" ]; then
hash=$(openssl sha512 -binary "$tohash" | xxd -p -c 9999)
else
echo " ✘ Invalid matchtype"
continue
fi
# Compare lowercase
if [ "${hash,,}" = "${data,,}" ]; then
echo " ✔ MATCH"
else
echo " ✘ MISMATCH"
echo " Expected: ${data,,}"
echo " Got: ${hash,,}"
fi
done < tlsa_raw.txt
echo
done
echo
echo "7) Displaying MTA-STS policy file"
echo "----------------------------------------------------"
cat mta_sts_policy.txt
echo
echo "8) Displaying MTA-STS HTTPS response headers"
echo "----------------------------------------------------"
cat headers_mta_sts.txt
echo
echo "===================================================="
echo " Mail Security Verification Complete"
echo "===================================================="
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment