Skip to content

Commit

Permalink
permit multiple domains
Browse files Browse the repository at this point in the history
  • Loading branch information
rtertiaer committed Dec 31, 2023
1 parent 5750c6f commit 687e135
Show file tree
Hide file tree
Showing 6 changed files with 16 additions and 13 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,21 @@ This role deploys a reasonably secure small mail server stack. This Ansible play
- [TREES from riseuplabs](https://0xacab.org/liberate/trees)
- [Dovecot](https://en.wikipedia.org/wiki/Dovecot_(software))
- [Postfix](https://en.wikipedia.org/wiki/Postfix_(software))
- [OpenDKIM](https://www.opendkim.org/)
- [sqlite3](https://en.wikipedia.org/wiki/SQLite) user database
- SSL certs from [Let's Encrypt](https://letsencrypt.org)
on a single host.

## Requirements
* Debian 11+
* Debian 12+
* The hostname in `mailfruit_server_hostname` pointing to the server

## Role Variables
* `mailfruit_server_hostname` - *required*
* `mailfruit_mail_domain` - *required*
* `mailfruit_mail_domains` - *required* a list of domains this server can accept mail for. The first item in this list is used as a default for various things.
* `mailfruit_admin_email` - *required*
* `mailfruit_certbot_authenticator` - _optional_, default: `standalone`
* `mailfruit_trees_git_ref` - _optional_, default: `ed0bbfb2746e620593b17668b4cd660b5aaf6e18'

## Some notes
I've opted to require TLS at every step with pre-wrapped ports - ie, using port 993 for IMAPS instead of 143, where TLS is negotiated within a cleartext connection. Not all clients like this, but it can prevent attacks where the TLS negotiation is stripped out of the cleartext.
* `mailfruit_trees_git_ref` - _optional_, default: `master`

## Example Playbook

Expand All @@ -36,5 +34,7 @@ I've opted to require TLS at every step with pre-wrapped ports - ie, using port
## License
GPLv3

## Post-deployment suggestions
## Post-deployment
*Important*: For each server you deploy this to, you _must_ host the DKIM `TXT` record for each domain. This record can be found on each server at `/etc/opendkim/keys/mail.txt`. You must also configure your SPF/DMARC records. If you do not do this, you will have very poor email deliverability.

You should probably use something like fail2ban to prevent account harvesting & break-in attempts. You should almost certainly harden your SSH install. You should definitely take backups of this server, particularly the user database; without it, the mail files become unreadable. You should implement external monitoring of this server; in particular, if this monitoring sends emails to alert you, those email addresses shouldn't reside on this server ;)
4 changes: 4 additions & 0 deletions tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,7 @@
- name: Install user database
ansible.builtin.include_tasks:
file: user_database.yml

- name: Post-deploy reminders
ansible.builtin.debug:
msg: "Please ensure the DKIM TXT record at /etc/opendkim/keys/mail.txt is hosted for each domain. Each server generates its own; be sure to host each server's key for each domain!"
4 changes: 1 addition & 3 deletions tasks/opendkim.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
# This play should occur before Postfix.
# TODO: handle multiple domains better
- name: Install opendkim
ansible.builtin.apt:
name:
Expand All @@ -16,9 +15,8 @@
group: opendkim
mode: '0750'

# TODO: output pubkey; save this in a better spot to permit multiple domains
- name: Make opendkim key
ansible.builtin.command: "opendkim-genkey -s mail -d {{ mailfruit_mail_domain }}"
ansible.builtin.command: "opendkim-genkey -s mail"
args:
chdir: /etc/opendkim/keys
creates: /etc/opendkim/keys/mail.private
Expand Down
2 changes: 1 addition & 1 deletion tasks/user_database.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
- name: Test for test user
ansible.builtin.shell: |
set -o pipefail
echo "select user_id from mailboxes where username='test' and domain='{{ mailfruit_mail_domain }}';" | sqlite3 /var/lib/dovecot/passwd.db
echo "select user_id from mailboxes where username='test' and domain='{{ mailfruit_mail_domains[0] }}';" | sqlite3 /var/lib/dovecot/passwd.db
register: test_user
args:
executable: /bin/bash
Expand Down
3 changes: 2 additions & 1 deletion templates/opendkim.conf.j2
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ LogWhy Yes
Canonicalization relaxed/simple

InternalHosts csl:127.0.0.1/24,localhost
Domain csl:{{ mailfruit_mail_domain }}
Domain csl:{% for domain in mailfruit_mail_domains %}{{ domain }}{% if not loop.last %},{% endif %}{% endfor %}

KeyFile /etc/opendkim/keys/mail.private
Selector mail

Expand Down
2 changes: 1 addition & 1 deletion templates/postfix/mailname.j2
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{{ mailfruit_mail_domain }}
{{ mailfruit_mail_domains[0] }}

0 comments on commit 687e135

Please sign in to comment.