now with dnsec

This commit is contained in:
rnsrk 2026-01-19 13:10:13 +01:00
parent b006c8f809
commit fb22e9cab4
118 changed files with 8306 additions and 2337 deletions

85
scripts/README-TLSA.md Normal file
View file

@ -0,0 +1,85 @@
# TLSA Record Automation
This directory contains scripts to automatically update TLSA/DANE records when certificates are renewed.
## Setup
### 1. Install Systemd Timer (Recommended)
```bash
sudo cp /var/deploy/scripts/tlsa-timer.service /etc/systemd/system/
sudo cp /var/deploy/scripts/tlsa-timer.timer /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable tlsa-timer.timer
sudo systemctl start tlsa-timer.timer
```
The timer will:
- Run 5 minutes after boot
- Check every hour for certificate changes
- Update TLSA records automatically when certificates change
### 2. Manual Setup (Alternative)
Add to crontab:
```bash
crontab -e
# Add this line:
0 * * * * /var/deploy/scripts/tlsa-monitor.sh >> /var/deploy/scripts/tlsa-cron.log 2>&1
```
### 3. DNS Provider API Configuration (Optional)
To enable automatic DNS updates via your DNS provider's API, set these environment variables:
```bash
export DNS_API_KEY="your-api-key"
export DNS_API_PASSWORD="your-api-password"
export DNS_CUSTOMER_NUMBER="your-customer-number"
```
Or add to `/var/deploy/scripts/update-tlsa.sh`:
```bash
dnsApiKey="your-api-key"
dnsApiPassword="your-api-password"
dnsCustomerNumber="your-customer-number"
```
**Note:** DNS provider API integration is not yet fully implemented. Currently, the script logs the required TLSA values for manual DNS updates. You'll need to implement the API call for your specific DNS provider.
## Manual TLSA Record Update
If automation is not set up, run manually after certificate renewal:
```bash
/var/deploy/scripts/update-tlsa.sh
```
This will output the TLSA records that need to be added/updated in your DNS provider.
## Current TLSA Hash
The current certificate hash is:
```
5206c4482b4378bd3e86d22d7afd8f341eec95aa999aeff7d94454c197223418
```
Add these TLSA records in your DNS provider:
- `_25._tcp.mail.nasarek.dev``3 1 1 5206c4482b4378bd3e86d22d7afd8f341eec95aa999aeff7d94454c197223418`
- `_465._tcp.mail.nasarek.dev``3 1 1 5206c4482b4378bd3e86d22d7afd8f341eec95aa999aeff7d94454c197223418`
- `_587._tcp.mail.nasarek.dev``3 1 1 5206c4482b4378bd3e86d22d7afd8f341eec95aa999aeff7d94454c197223418`
## Verification
Check if TLSA records are published:
```bash
dig +short TLSA _25._tcp.mail.nasarek.dev
dig +short TLSA _465._tcp.mail.nasarek.dev
dig +short TLSA _587._tcp.mail.nasarek.dev
```
## Troubleshooting
- Check logs: `/var/deploy/scripts/tlsa-update.log`
- Test script manually: `/var/deploy/scripts/tlsa-monitor.sh`
- Verify certificate: `openssl x509 -in /var/deploy/mailcow/data/assets/ssl/cert.pem -noout -dates`

53
scripts/tlsa-monitor.sh Executable file
View file

@ -0,0 +1,53 @@
#!/bin/bash
# Monitor certificate file and update TLSA records when it changes.
# This script checks the certificate modification time and updates TLSA if changed.
set -e
# Configuration.
certFile="/var/deploy/mailcow/data/assets/ssl/cert.pem"
stateFile="/var/deploy/scripts/.tlsa-state"
updateScript="/var/deploy/scripts/update-tlsa.sh"
# Check if certificate file exists.
if [ ! -f "$certFile" ]; then
echo "Certificate file not found: $certFile"
exit 1
fi
# Get certificate modification time and hash.
currentMtime=$(stat -c %Y "$certFile" 2>/dev/null || stat -f %m "$certFile" 2>/dev/null)
currentHash=$(openssl x509 -in "$certFile" -noout -fingerprint -sha256 | cut -d= -f2 | tr -d ':')
# Read previous state.
if [ -f "$stateFile" ]; then
# shellcheck source=/dev/null
source "$stateFile"
else
previousMtime=0
previousHash=""
fi
# Check if certificate has changed.
if [ "$currentMtime" != "$previousMtime" ] || [ "$currentHash" != "$previousHash" ]; then
echo "Certificate changed detected. Updating TLSA records..."
# Run update script.
if [ -x "$updateScript" ]; then
"$updateScript"
else
echo "ERROR: Update script not found or not executable: $updateScript"
exit 1
fi
# Save new state.
cat > "$stateFile" <<EOF
previousMtime=$currentMtime
previousHash=$currentHash
EOF
echo "TLSA records updated successfully"
else
echo "No certificate changes detected"
fi

View file

@ -0,0 +1,11 @@
[Unit]
Description=TLSA Record Update Timer
After=network.target
[Service]
Type=oneshot
ExecStart=/var/deploy/scripts/tlsa-monitor.sh
User=root
[Install]
WantedBy=multi-user.target

11
scripts/tlsa-timer.timer Normal file
View file

@ -0,0 +1,11 @@
[Unit]
Description=Run TLSA monitor every hour
Requires=tlsa-timer.service
[Timer]
OnBootSec=5min
OnUnitActiveSec=1h
AccuracySec=1min
[Install]
WantedBy=timers.target

95
scripts/update-tlsa.sh Executable file
View file

@ -0,0 +1,95 @@
#!/bin/bash
# Script to automatically update TLSA records when certificates are renewed.
# This should be triggered by certdumper or Traefik certificate renewal.
set -e
# Configuration.
mailcowHostname="${MAILCOW_HOSTNAME:-mail.nasarek.dev}"
domain="${DOMAIN:-nasarek.dev}"
dnsApiKey="${DNS_API_KEY:-}"
dnsApiPassword="${DNS_API_PASSWORD:-}"
dnsCustomerNumber="${DNS_CUSTOMER_NUMBER:-}"
# Paths.
certFile="/var/deploy/mailcow/data/assets/ssl/cert.pem"
logFile="/var/deploy/scripts/tlsa-update.log"
# Logging function.
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$logFile"
}
# Check if certificate file exists.
if [ ! -f "$certFile" ]; then
log "ERROR: Certificate file not found: $certFile"
exit 1
fi
# Generate TLSA hash from certificate.
generateTlsaHash() {
local certPath="$1"
if [ ! -f "$certPath" ]; then
log "ERROR: Certificate file not found: $certPath"
return 1
fi
openssl x509 -in "$certPath" -noout -pubkey | \
openssl pkey -pubin -outform der | \
openssl dgst -sha256 | \
awk '{print $2}'
}
# Update TLSA record via DNS provider API.
updateTlsaRecord() {
local port="$1"
local hash="$2"
local recordName="_${port}._tcp.${mailcowHostname}"
log "Updating TLSA record: ${recordName}"
# Check if DNS provider API credentials are configured.
if [ -z "$dnsApiKey" ] || [ -z "$dnsApiPassword" ] || [ -z "$dnsCustomerNumber" ]; then
log "WARNING: DNS provider API credentials not configured. TLSA record needs manual update:"
log " ${recordName} TLSA 3 1 1 ${hash}"
return 1
fi
# DNS provider API call would go here.
# For now, we'll log the required values.
log "INFO: Use DNS provider API to update:"
log " Record: ${recordName}"
log " Type: TLSA"
log " Value: 3 1 1 ${hash}"
# TODO: Implement DNS provider API call.
# Example for Netcup:
# curl -X POST https://ccp.netcup.net/run/webservice/servers/endpoint.php \
# -d "apikey=${dnsApiKey}&apipassword=${dnsApiPassword}&customernumber=${dnsCustomerNumber}&domainname=${domain}&dnsrecordset=..."
}
# Main execution.
main() {
log "Starting TLSA record update check..."
# Generate hash from current certificate.
local tlsaHash
tlsaHash=$(generateTlsaHash "$certFile")
if [ -z "$tlsaHash" ]; then
log "ERROR: Failed to generate TLSA hash"
exit 1
fi
log "Generated TLSA hash: ${tlsaHash}"
# Update TLSA records for all mail ports.
updateTlsaRecord "25" "$tlsaHash"
updateTlsaRecord "465" "$tlsaHash"
updateTlsaRecord "587" "$tlsaHash"
log "TLSA update check completed"
}
main "$@"