351 lines
8.1 KiB
Markdown
351 lines
8.1 KiB
Markdown
# 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.
|