mirror of
https://github.com/rubenhensen/k8scd.git
synced 2026-09-17 02:12:55 +02:00
Mailserver Ansible
Ansible playbook that deploys and hardens a Stalwart all-in-one mail server on Ubuntu.
What it does
| Role | Purpose |
|---|---|
base |
apt upgrades, unattended-upgrades, timezone, swap, sysctl hardening |
ssh |
Key-only root login, disable password auth, rate limiting |
ufw |
Firewall — deny all incoming except SSH, SMTP, IMAP, HTTPS |
fail2ban |
Brute force protection for SSH + Stalwart auth |
stalwart |
Stalwart mail server with built-in ACME (Let's Encrypt) |
Prerequisites
- Ubuntu server with root SSH key access
- DNS:
mail.rubenhensen.nl→ server IP (A record) - DNS: MX record for your domain pointing to
mail.rubenhensen.nl - Ansible installed locally (
brew install ansible)
Setup
cd ~/Repos/k8scd/ansible/mailserver
# 1. Create vault password file (gitignored)
echo 'your-vault-password' > .vault_pass
chmod 600 .vault_pass
# 2. Create encrypted secrets
ansible-vault create host_vars/mailserver/vault.yml
# Add:
# ---
# vault_stalwart_fallback_admin_password: "your-admin-password"
# 3. Edit inventory if server IP changed
# inventory.yml → ansible_host
# 4. Run
ansible-playbook playbook.yml
Day-to-day operations
Re-run after config changes:
ansible-playbook playbook.yml
Edit encrypted secrets:
ansible-vault edit host_vars/mailserver/vault.yml
Run only a specific role:
ansible-playbook playbook.yml --tags stalwart
(Note: tags aren't configured yet — use --start-at-task "task name" or add tags if needed)
Upgrade Stalwart:
Bump stalwart_version in roles/stalwart/defaults/main.yml and re-run. It only re-downloads when the version changes.
File structure
├── ansible.cfg # Ansible settings + vault password file path
├── inventory.yml # Server IP, SSH user, python interpreter
├── .vault_pass # Vault password (gitignored)
├── .gitignore
├── host_vars/mailserver/
│ ├── vars.yml # Maps variables to vault references
│ └── vault.yml # Encrypted secrets (committed as ciphertext)
└── roles/
├── base/ # OS hardening + swap
├── ssh/ # sshd_config template
├── ufw/ # Firewall rules
├── fail2ban/ # Jails for SSH + Stalwart
└── stalwart/ # Mail server install + config.toml template
Stalwart admin
Web admin: https://mail.rubenhensen.nl
Login: admin / (password from vault)
From the web UI you can manage domains, accounts, DKIM keys, and other mail settings.
TLS certificates
Handled automatically by Stalwart's built-in ACME support (Let's Encrypt, tls-alpn-01 challenge on port 443). No certbot needed. Certificates auto-renew.
Ports
| Port | Service |
|---|---|
| 22 | SSH |
| 25 | SMTP |
| 465 | SMTP submission (implicit TLS) |
| 587 | SMTP submission (STARTTLS) |
| 993 | IMAP (implicit TLS) |
| 443 | HTTPS (web admin + JMAP + ACME) |
| 8080 | HTTP |
If something breaks
- Stalwart logs:
/opt/stalwart/logs/ - Stalwart config:
/opt/stalwart/etc/config.toml - Service status:
systemctl status stalwart - fail2ban status:
fail2ban-client status/fail2ban-client status sshd - Firewall:
ufw status - Check banned IPs:
fail2ban-client status stalwart-auth - Unban an IP:
fail2ban-client set <jail> unbanip <ip>