# TLSA Records setzen über die API von NetCup Mit diesem Script kann man automatisiert den TLSA Record setzen. Es wird zunächst geprüft ob er bereits vorhanden ist, wenn ja wird er nicht aktualisiert. Darüber hinaus wird auch das Rolloverscheme gesetzt. Hier wird die CA von Letsencrypt genutzt, da man vor dem Zertifikatswechsel das neue Zertifikat ja noch nicht kennt bzw. hat. Optional sind nun auch Pushnachrichten per Gotify möglich, diese werden nur gesandt, wenn Änderungen erfolgt sind. Die `netcup.env` Datei sollte dabei im gleichen Verzeichnis liegen und folgenden Inhalt haben: ```python CUSTOMER_NUMBER=<- DEINE_KUNDENNUMMER -> API_KEY=<- DEIN_API_KEY -> API_PASSWORD=<- DEIN_API_PASSWORT -> DOMAIN=<- deine-domain.de -> GOTIFY_URL=<- https://deine-gotify-domain.de -> GOTIFY_TOKEN=<- DEIN-APP-TOKEN -> ``` ```python #!/bin/bash # .env Datei laden if [ -f netcup.env ]; then export $(grep -v '^#' netcup.env | xargs) else echo "Fehler: .env Datei nicht gefunden!" exit 1 fi # Pfade zu Zertifikaten CA_CERTIFICATE_DIR="/etc/ssl/certs" # Verzeichnis, in dem CA-Zertifikate gespeichert werden # URL der Netcup API API_URL="https://ccp.netcup.net/run/webservice/servers/endpoint.php?JSON" # Gotify-URL und Token für spezifische App GOTIFY_URL="$GOTIFY_URL" GOTIFY_TOKEN="$GOTIFY_TOKEN" # Funktion für Gotify-Benachrichtigungen send_gotify_notification() { local TITLE="$1" local MESSAGE="$2" local PRIORITY=${3:-0} if [[ -n "$GOTIFY_URL" && -n "$GOTIFY_TOKEN" ]]; then curl -s -X POST "$GOTIFY_URL/message?token=$GOTIFY_TOKEN" \ -F "title=$TITLE" \ -F "message=$MESSAGE" \ -F "priority=$PRIORITY" > /dev/null else echo "Gotify-Konfiguration fehlt. Keine Benachrichtigung gesendet." fi } # Zertifikate prüfen if [[ ! -f "$CERTIFICATE_PATH" ]]; then ERROR_MSG="Fehler: Zertifikat unter $CERTIFICATE_PATH nicht gefunden!" echo "$ERROR_MSG" send_gotify_notification "TLSA Script Fehler" "$ERROR_MSG" 10 exit 1 fi # Aktuelles CA-Zertifikat von Let's Encrypt finden CA_ISSUER_URL=$(openssl x509 -in "$CERTIFICATE_PATH" -noout -text | grep -A1 "CA Issuers" | grep http | sed 's/.*URI://') CA_CERTIFICATE_PATH="$CA_CERTIFICATE_DIR/$(basename "$CA_ISSUER_URL")" if [[ ! -f "$CA_CERTIFICATE_PATH" ]]; then echo "CA-Zertifikat wird von $CA_ISSUER_URL heruntergeladen..." wget -q "$CA_ISSUER_URL" -O "$CA_CERTIFICATE_PATH" if [[ $? -ne 0 ]]; then ERROR_MSG="Fehler beim Herunterladen des CA-Zertifikats von $CA_ISSUER_URL" echo "$ERROR_MSG" send_gotify_notification "TLSA Script Fehler" "$ERROR_MSG" 10 exit 1 fi echo "CA-Zertifikat erfolgreich heruntergeladen: $CA_CERTIFICATE_PATH" send_gotify_notification "TLSA Script Erfolg" "CA-Zertifikat erfolgreich heruntergeladen: $CA_CERTIFICATE_PATH" 0 else echo "CA-Zertifikat gefunden: $CA_CERTIFICATE_PATH" fi # TLSA-Hashes generieren TLSA_HASH_CURRENT=$(openssl x509 -in "$CERTIFICATE_PATH" -pubkey -noout | \ openssl pkey -pubin -outform DER | \ openssl dgst -sha256 -binary | hexdump -ve '1/1 "%.2x"') TLSA_HASH_CA=$(openssl x509 -in "$CA_CERTIFICATE_PATH" -pubkey -noout | \ openssl pkey -pubin -outform DER | \ openssl dgst -sha256 -binary | hexdump -ve '1/1 "%.2x"') if [[ -z "$TLSA_HASH_CURRENT" || -z "$TLSA_HASH_CA" ]]; then ERROR_MSG="Fehler beim Generieren der TLSA-Hashes!" echo "$ERROR_MSG" send_gotify_notification "TLSA Script Fehler" "$ERROR_MSG" 10 exit 1 fi echo "TLSA-Hashes generiert:" echo "Aktuelles Zertifikat (3 1 1): $TLSA_HASH_CURRENT" echo "CA-Zertifikat (2 1 1): $TLSA_HASH_CA" # Login zur Netcup API LOGIN_RESPONSE=$(curl -s -X POST -H "Content-Type: application/json" \ -d '{ "action": "login", "param": { "customernumber": "'"$CUSTOMER_NUMBER"'", "apikey": "'"$API_KEY"'", "apipassword": "'"$API_PASSWORD"'" } }' "$API_URL") SESSION_ID=$(echo "$LOGIN_RESPONSE" | jq -r '.responsedata.apisessionid') if [[ -z "$SESSION_ID" || "$SESSION_ID" == "null" ]]; then ERROR_MSG="Fehler beim Login!" echo "$ERROR_MSG" echo "$LOGIN_RESPONSE" send_gotify_notification "TLSA Script Fehler" "$ERROR_MSG" 10 exit 1 fi echo "Erfolgreich eingeloggt. Session-ID: $SESSION_ID" # DNS Records abrufen DNS_RESPONSE=$(curl -s -X POST -H "Content-Type: application/json" \ -d '{ "action": "infoDnsRecords", "param": { "customernumber": "'"$CUSTOMER_NUMBER"'", "apikey": "'"$API_KEY"'", "apisessionid": "'"$SESSION_ID"'", "domainname": "'"$DOMAIN"'" } }' "$API_URL") RECORDS=$(echo "$DNS_RESPONSE" | jq -r '.responsedata.dnsrecords // []') # Prüfen und aktualisieren der TLSA-Records update_tlsa_record() { local HOSTNAME="$1" local TYPE="$2" local HASH="$3" EXISTING_RECORD=$(echo "$RECORDS" | jq -r ".[] | select(.hostname == \"$HOSTNAME\" and .type == \"TLSA\") | .destination // \"\"" | grep -E "^$TYPE.*$HASH") if [[ -n "$EXISTING_RECORD" ]]; then echo "TLSA-Record existiert bereits: $HOSTNAME $TYPE $HASH" else echo "TLSA-Record wird aktualisiert: $HOSTNAME $TYPE $HASH" send_gotify_notification "TLSA Script Info" "TLSA-Record wird aktualisiert: $HOSTNAME $TYPE $HASH" 5 DNS_UPDATE_PAYLOAD='{ "action": "updateDnsRecords", "param": { "customernumber": "'"$CUSTOMER_NUMBER"'", "apikey": "'"$API_KEY"'", "apisessionid": "'"$SESSION_ID"'", "domainname": "'"$DOMAIN"'", "dnsrecordset": { "dnsrecords": [ { "hostname": "'"$HOSTNAME"'", "type": "TLSA", "destination": "'"$TYPE $HASH"'", "state": "yes" } ] } } }' UPDATE_RESPONSE=$(curl -s -X POST -H "Content-Type: application/json" \ -d "$DNS_UPDATE_PAYLOAD" "$API_URL") UPDATE_STATUS=$(echo "$UPDATE_RESPONSE" | jq -r '.status') if [[ "$UPDATE_STATUS" == "success" ]]; then echo "TLSA-Record erfolgreich aktualisiert: $HOSTNAME $TYPE $HASH" send_gotify_notification "TLSA Script Erfolg" "TLSA-Record erfolgreich aktualisiert: $HOSTNAME $TYPE $HASH" 0 else ERROR_MSG="Fehler beim Aktualisieren des TLSA-Records: $HOSTNAME $TYPE $HASH" echo "$ERROR_MSG" echo "$UPDATE_RESPONSE" send_gotify_notification "TLSA Script Fehler" "$ERROR_MSG" 10 fi fi } update_tlsa_record "_25._tcp.mail" "3 1 1" "$TLSA_HASH_CURRENT" update_tlsa_record "_25._tcp.mail" "2 1 1" "$TLSA_HASH_CA" # Logout curl -s -X POST -H "Content-Type: application/json" \ -d '{ "action": "logout", "param": { "customernumber": "'"$CUSTOMER_NUMBER"'", "apikey": "'"$API_KEY"'", "apisessionid": "'"$SESSION_ID"'" } }' "$API_URL" > /dev/null echo "Logout abgeschlossen." ```