248 lines
8.1 KiB
Markdown
248 lines
8.1 KiB
Markdown
# 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
|
|
|
|
# netcup.env Datei laden
|
|
if [ -f netcup.env ]; then
|
|
export $(grep -v '^#' netcup.env | xargs)
|
|
else
|
|
echo "Fehler: netcup.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"
|
|
|
|
# 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"
|
|
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 // []')
|
|
|
|
# Spezifische TLSA-Records überprüfen und aktualisieren oder erstellen
|
|
update_tlsa_record() {
|
|
local HOSTNAME="$1"
|
|
local TYPE="$2"
|
|
local HASH="$3"
|
|
|
|
EXISTING_RECORD=$(echo "$RECORDS" | jq -r ".[] | select(.hostname == \"$HOSTNAME\" and .type == \"TLSA\" and (.destination | tostring | startswith(\"$TYPE\")))")
|
|
|
|
if [[ -n "$EXISTING_RECORD" ]]; then
|
|
RECORD_ID=$(echo "$EXISTING_RECORD" | jq -r '.id')
|
|
OLD_DESTINATION=$(echo "$EXISTING_RECORD" | jq -r '.destination')
|
|
|
|
if [[ "$OLD_DESTINATION" == "$TYPE $HASH" ]]; then
|
|
echo "TLSA-Record ist identisch: $HOSTNAME $TYPE $HASH"
|
|
else
|
|
echo "Aktualisiere bestehenden TLSA-Record: $HOSTNAME"
|
|
echo "Von: $OLD_DESTINATION"
|
|
echo "Nach: $TYPE $HASH"
|
|
send_gotify_notification "TLSA Script Update" "TLSA-Record alt: $OLD_DESTINATION" 5
|
|
|
|
DNS_UPDATE_PAYLOAD='{
|
|
"action": "updateDnsRecords",
|
|
"param": {
|
|
"customernumber": "'"$CUSTOMER_NUMBER"'",
|
|
"apikey": "'"$API_KEY"'",
|
|
"apisessionid": "'"$SESSION_ID"'",
|
|
"domainname": "'"$DOMAIN"'",
|
|
"dnsrecordset": {
|
|
"dnsrecords": [
|
|
{
|
|
"id": "'"$RECORD_ID"'",
|
|
"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 neu: $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
|
|
else
|
|
echo "Erstelle neuen TLSA-Record: $HOSTNAME $TYPE $HASH"
|
|
|
|
DNS_CREATE_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"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}'
|
|
|
|
CREATE_RESPONSE=$(curl -s -X POST -H "Content-Type: application/json" \
|
|
-d "$DNS_CREATE_PAYLOAD" "$API_URL")
|
|
|
|
CREATE_STATUS=$(echo "$CREATE_RESPONSE" | jq -r '.status')
|
|
|
|
if [[ "$CREATE_STATUS" == "success" ]]; then
|
|
echo "TLSA-Record erfolgreich erstellt: $HOSTNAME $TYPE $HASH"
|
|
send_gotify_notification "TLSA Script Erfolg" "TLSA-Record erfolgreich erstellt: $HOSTNAME $TYPE $HASH" 0
|
|
else
|
|
ERROR_MSG="Fehler beim Erstellen des TLSA-Records: $HOSTNAME $TYPE $HASH"
|
|
echo "$ERROR_MSG"
|
|
echo "$CREATE_RESPONSE"
|
|
send_gotify_notification "TLSA Script Fehler" "$ERROR_MSG" 10
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Aktualisieren oder Erstellen der TLSA-Records
|
|
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."
|
|
``` |