feat: add email

This commit is contained in:
2025-11-21 14:00:47 +01:00
parent b3c5366f31
commit d6f206f0bb
5 changed files with 492 additions and 25 deletions

View File

@@ -0,0 +1,350 @@
# Email Setup for amzebs-01 (amz.at)
This host is configured to send emails via Laravel with DKIM signing.
## Configuration Overview
- **Postfix**: Localhost-only SMTP server (no external access)
- **Rspamd**: DKIM signing with host-specific key
- **Domain**: amz.at
- **DKIM Selector**: amzebs-01
- **Secret Management**: DKIM private key stored in sops
## Initial Setup (Before First Deployment)
### 1. Generate DKIM Key Pair
You need to generate a DKIM key pair locally first. You'll need `rspamd` package installed.
#### Option A: Using rspamd (if installed locally)
```bash
# Create a temporary directory
mkdir -p /tmp/dkim-gen
# Generate the key pair
rspamadm dkim_keygen -s amzebs-01 -d amz.at -k /tmp/dkim-gen/amz.at.amzebs-01.key
```
This will output:
- **Private key** saved to `/tmp/dkim-gen/amz.at.amzebs-01.key`
- **Public key** printed to stdout (starts with `v=DKIM1; k=rsa; p=...`)
#### Option B: Using OpenSSL (alternative)
```bash
# Create temporary directory
mkdir -p /tmp/dkim-gen
# Generate private key (2048-bit RSA)
openssl genrsa -out /tmp/dkim-gen/amz.at.amzebs-01.key 2048
# Extract public key in the correct format for DNS
openssl rsa -in /tmp/dkim-gen/amz.at.amzebs-01.key -pubout -outform PEM | \
grep -v '^-----' | tr -d '\n' > /tmp/dkim-gen/public.txt
# Display the DNS record value
echo "v=DKIM1; k=rsa; p=$(cat /tmp/dkim-gen/public.txt)"
```
**Save the public key output!** You'll need it for DNS configuration later.
### 2. Add DKIM Private Key to Sops Secrets
Now you need to encrypt and add the private key to your secrets file.
#### Step 1: View the private key
```bash
cat /tmp/dkim-gen/amz.at.amzebs-01.key
```
#### Step 2: Edit the secrets file
```bash
cd /home/dominik/projects/cloonar/cloonar-nixos/hosts/amzebs-01
sops secrets.yaml
```
#### Step 3: Add the key to secrets.yaml
In the sops editor, add a new key called `rspamd-dkim-key` with the **entire private key content** including the BEGIN/END markers:
```yaml
rspamd-dkim-key: |
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC...
(paste the entire key content here)
...
-----END PRIVATE KEY-----
```
**Important:**
- Make sure to use the pipe `|` character for multiline content
- Keep the proper indentation (2 spaces before each line of the key)
- Include the full BEGIN/END markers
#### Step 4: Save and exit
Save the file in sops (it will be encrypted automatically).
#### Step 5: Clean up temporary files
```bash
rm -rf /tmp/dkim-gen
```
### 3. Verify Secret is Encrypted
Check that the secret is properly encrypted:
```bash
cat hosts/amzebs-01/secrets.yaml
```
You should see encrypted content, not the plain private key.
### 4. Extract Public Key for DNS (if needed later)
If you didn't save the public key earlier, you can extract it after deployment:
```bash
# On the server after deployment
sudo cat /var/lib/rspamd/dkim/amz.at.amzebs-01.key | \
openssl rsa -pubout -outform PEM 2>/dev/null | \
grep -v '^-----' | tr -d '\n'
```
Then format it as:
```
v=DKIM1; k=rsa; p=<output_from_above>
```
## Deployment
### 1. Deploy Configuration
After adding the DKIM private key to sops, deploy the configuration:
```bash
# Build and switch on the remote host
nixos-rebuild switch --flake .#amzebs-01 --target-host amzebs-01 --use-remote-sudo
```
Or if deploying locally on the server:
```bash
sudo nixos-rebuild switch
```
### 2. Verify Deployment
Check that the services are running:
```bash
# Check rspamd-dkim-setup service
systemctl status rspamd-dkim-setup
# Check that rspamd is running
systemctl status rspamd
# Check that postfix is running
systemctl status postfix
# Verify DKIM key was deployed
ls -la /var/lib/rspamd/dkim/amz.at.amzebs-01.key
```
## DNS Configuration
Add the following DNS records to your `amz.at` domain:
#### SPF Record
```
Type: TXT
Name: @
Value: v=spf1 mx a:amzebs-01.amz.at ~all
```
#### DKIM Record
```
Type: TXT
Name: amzebs-01._domainkey
Value: [Your public key from step 1 above]
```
The DKIM record will look something like:
```
v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
```
#### DMARC Record
```
Type: TXT
Name: _dmarc
Value: v=DMARC1; p=quarantine; rua=mailto:postmaster@amz.at; ruf=mailto:postmaster@amz.at; fo=1
```
**Explanation:**
- `p=quarantine`: Failed messages should be quarantined (you can change to `p=reject` after testing)
- `rua=mailto:...`: Aggregate reports sent to this address
- `ruf=mailto:...`: Forensic reports sent to this address
- `fo=1`: Generate forensic reports for any failure
## Laravel Configuration
Update your Laravel application's `.env` file:
#### Option A: Using sendmail (Recommended)
```env
MAIL_MAILER=sendmail
MAIL_FROM_ADDRESS=noreply@amz.at
MAIL_FROM_NAME="${APP_NAME}"
```
#### Option B: Using SMTP
```env
MAIL_MAILER=smtp
MAIL_HOST=127.0.0.1
MAIL_PORT=25
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=noreply@amz.at
MAIL_FROM_NAME="${APP_NAME}"
```
**Note**: Laravel can use ANY email address with @amz.at domain. All will be DKIM signed automatically.
## Testing Email
### Test from Command Line
```bash
# Send a test email
echo "Test email body" | mail -s "Test Subject" test@example.com -aFrom:test@amz.at
```
### Check Postfix Queue
```bash
# View mail queue
mailq
# View logs
journalctl -u postfix -f
```
### Check Rspamd Logs
```bash
# View rspamd logs
journalctl -u rspamd -f
```
### Test DKIM Signature
Send an email to a Gmail account or use an email testing service like:
- https://www.mail-tester.com/
- https://mxtoolbox.com/emailhealth/
They will show you:
- If DKIM signature is valid
- If SPF passes
- If DMARC passes
- Your spam score
## Verification Commands
```bash
# Check if Postfix is running
systemctl status postfix
# Check if Rspamd is running
systemctl status rspamd
# Check if Postfix is listening on localhost only
ss -tlnp | grep master
# View DKIM public key again
systemctl start rspamd-show-dkim
journalctl -u rspamd-show-dkim
# Check if DKIM key exists
ls -la /var/lib/rspamd/dkim/
```
## Security Notes
1. **Localhost-only**: Postfix is configured to listen ONLY on 127.0.0.1
2. **No authentication**: Not needed since only local processes can connect
3. **No firewall changes**: No external ports opened for email
4. **DKIM signing**: All outgoing emails are automatically signed with DKIM
5. **Host-specific key**: Using selector "amzebs-01" allows multiple hosts to send for amz.at
## Troubleshooting
### Email not being sent
1. Check Postfix status: `systemctl status postfix`
2. Check queue: `mailq`
3. Check logs: `journalctl -u postfix -n 100`
### DKIM not signing
1. Check Rspamd status: `systemctl status rspamd`
2. Check if key exists: `ls -la /var/lib/rspamd/dkim/amz.at.amzebs-01.key`
3. Check Rspamd logs: `journalctl -u rspamd -n 100`
### Permission errors
```bash
# Ensure proper ownership
chown -R rspamd:rspamd /var/lib/rspamd/dkim/
chmod 600 /var/lib/rspamd/dkim/*.key
```
### Rotate DKIM key
```bash
# 1. Generate new key pair locally (follow "Initial Setup" steps)
# 2. Update the rspamd-dkim-key in secrets.yaml with new key
# 3. Deploy the configuration
nixos-rebuild switch
# 4. Restart the setup service to copy new key
systemctl restart rspamd-dkim-setup
# 5. Restart rspamd to use new key
systemctl restart rspamd
# 6. Update DNS with new public key
# 7. Wait for DNS propagation before removing old DNS record
```
## Related Files
- Postfix config: `hosts/amzebs-01/modules/postfix.nix`
- Rspamd config: `hosts/amzebs-01/modules/rspamd.nix`
- Main config: `hosts/amzebs-01/configuration.nix`
- Secrets file: `hosts/amzebs-01/secrets.yaml` (encrypted)
## Sops Secret Configuration
The DKIM private key is stored as a sops secret with the following configuration:
```nix
sops.secrets.rspamd-dkim-key = {
owner = "rspamd";
group = "rspamd";
mode = "0400";
};
```
This ensures:
- Only the rspamd user can read the key
- The key is decrypted at boot time by sops-nix
- The key is encrypted in version control
- The key persists across rebuilds
The key is automatically copied from the sops secret path to `/var/lib/rspamd/dkim/amz.at.amzebs-01.key` by the `rspamd-dkim-setup.service` on every boot.