Add send_only_mailserver role and deploy Send-Only-Mailserver with it

Co-authored-by: yuri <yuri@nekover.se>
This commit is contained in:
June 2023-05-09 23:01:57 +02:00 committed by julian
parent f4a79fb4e2
commit b56ca3899d
14 changed files with 263 additions and 0 deletions

View file

@ -0,0 +1,8 @@
send_only_mail_server__mail_server_fqdn: send-only-mailserver.ccchh.net
send_only_mail_server__mail_server_fqdn_zone: ccchh.net
send_only_mail_server__mail_domains:
- name: send-only-mail.ccchh.net
zone: ccchh.net
send_only_mail_server__bind_9_host: authoritative-dns
cert__acme_account_email: j+letsencrypt-ccchh@jsts.xyz

View file

@ -27,3 +27,6 @@ all:
keycloak: keycloak:
ansible_host: keycloak.z9.ccchh.net ansible_host: keycloak.z9.ccchh.net
ansible_user: chaos ansible_user: chaos
send-only-mailserver:
ansible_host: send-only-mailserver.z9.ccchh.net
ansible_user: chaos

View file

@ -0,0 +1,6 @@
---
- name: Deploy the Send-Only-Mailserver
hosts: send-only-mailserver
become: true
roles:
- send_only_mail_server

View file

@ -0,0 +1,35 @@
# Role `send_only_mail_server`
Makes sure a send-only mail server is deployed using OpenSMTPD and Rspamd for DKIM signing.
Make sure to manually set a DMARC record and MX record for the mail domains.
## Supported Distributions
The following distributions are supported:
- Debian 11
## Required Arguments
For the required arguments look at the [`argument_specs.yaml`](./meta/argument_specs.yml)
Also make sure to set the following for the `cert` role dependency:
- `cert__acme_account_email`
## Updates
This role doesn't handle updates.
However it uses the system package manager for installing all the packages, so when you're making sure the system packages are up-to-date, you're handling updates for the packages installed by this role as well.
## `hosts`
The `hosts` for this role need to be the machines on which you want to deploy a mail server.
## Links & Resources
- <https://www.opensmtpd.org/>
- <https://www.opensmtpd.org/manual.html>
- <https://www.rspamd.com/>
- <https://poolp.org/posts/2019-09-14/setting-up-a-mail-server-with-opensmtpd-dovecot-and-rspamd/>

View file

@ -0,0 +1,7 @@
dkim_signing {
id = "dkim_signing";
apply {
symbols_enabled = ["DKIM_SIGNED"];
flags = ["skip_process"]; # Disable expensive MIME processing
}
}

View file

@ -0,0 +1,11 @@
- name: Restart `opensmtpd.service`
ansible.builtin.systemd:
name: opensmtpd.service
state: restarted
become: true
- name: Restart `rspamd.service`
ansible.builtin.systemd:
name: rspamd.service
state: restarted
become: true

View file

@ -0,0 +1,31 @@
argument_specs:
main:
options:
send_only_mail_server__mail_server_fqdn:
description: The FQDN of the mail server host itself.
type: str
required: true
send_only_mail_server__mail_server_fqdn_zone:
description: >
The DNS zone on the BIND 9 server for records for the mail server host
FQDN.
type: str
required: true
send_only_mail_server__mail_domains:
description: The domains the mail server should send mails for.
type: list
elements: dict
required: true
options:
name:
description: The domain name.
type: str
required: true
zone:
description: The DNS zone on the BIND 9 server.
type: str
required: true
send_only_mail_server__bind_9_host:
description: The machine running BIND 9 to deploy DNS records via.
type: str
required: true

View file

@ -0,0 +1,7 @@
dependencies: # noqa meta-no-info
- role: distribution_check
vars:
distribution_check__supported_distributions:
- name: Debian
versions:
- "11"

View file

@ -0,0 +1,55 @@
- name: make sure DKIM private key exists
community.crypto.openssl_privatekey:
path: "/etc/mail-dkim/{{ item.name }}.key"
size: 1024
type: RSA
owner: "root"
group: "_rspamd"
mode: "0640"
become: true
notify: Restart `rspamd.service`
- name: make sure DKIM public key exists
community.crypto.openssl_publickey:
path: "/etc/mail-dkim/{{ item.name }}.pub"
privatekey_path: "/etc/mail-dkim/{{ item.name }}.key"
return_content: true
become: true
notify: Restart `rspamd.service`
register: send_only_mail_server__dkim_public_key
- name: deploy DKIM public key DNS entry # noqa: no-handler
delegate_to: "{{ send_only_mail_server__bind_9_host }}"
when: send_only_mail_server__dkim_public_key.changed
block:
- name: Add file containing nsupdate commands for removing DKIM public key TXT records
ansible.builtin.template:
src: nsupdate_delete_dkim_public_key_txt_records.j2
dest: /root/nsupdate_delete_dkim_public_key_txt_records
owner: root
group: root
mode: "0600"
- name: Remove DNS records from BIND 9 server via nsupdate # noqa: no-changed-when
ansible.builtin.command: /usr/bin/nsupdate -l /root/nsupdate_delete_dkim_public_key_txt_records
- name: Add file containing nsupdate commands for adding DKIM public key TXT record
ansible.builtin.template:
src: nsupdate_add_dkim_public_key_txt_record.j2
dest: /root/nsupdate_add_dkim_public_key_txt_record
owner: root
group: root
mode: "0600"
- name: Add DNS record to BIND 9 server via nsupdate # noqa: no-changed-when
ansible.builtin.command: /usr/bin/nsupdate -l /root/nsupdate_add_dkim_public_key_txt_record
always:
- name: Remove file containing nsupdate commands for removing DKIM public key TXT records again
ansible.builtin.file:
path: /root/nsupdate_delete_dkim_public_key_txt_records
state: absent
- name: Remove file containing nsupdate commands for adding DKIM public key TXT record again
ansible.builtin.file:
path: /root/nsupdate_add_dkim_public_key_txt_record
state: absent

View file

@ -0,0 +1,65 @@
- name: make sure packages are installed
ansible.builtin.apt:
name:
- opensmtpd
- rspamd
- opensmtpd-filter-rspamd
become: true
- name: make sure certificates exist
ansible.builtin.include_role:
name: cert
vars:
cert__domains:
- "{{ send_only_mail_server__mail_server_fqdn }}"
cert__owner: root
cert__group: opensmtpd
cert__bind_9_zone: "{{ send_only_mail_server__mail_server_fqdn_zone }}"
cert__bind_9_host: "{{ send_only_mail_server__bind_9_host }}"
cert__privkey_pem_permissions: "0640"
cert__fullchain_pem_permissions: "0640"
cert__chain_pem_permissions: "0640"
cert__cert_pem_permissions: "0640"
- name: make sure the OpenSMTPD config is deployed
ansible.builtin.template:
src: etc_smtpd.conf.j2
dest: /etc/smtpd.conf
owner: root
group: root
mode: "0600"
become: true
notify: Restart `opensmtpd.service`
- name: make sure `/etc/mail-dkim` directory exists
ansible.builtin.file:
path: /etc/mail-dkim
state: directory
owner: root
group: root
mode: "755"
become: true
- name: make sure DKIM keypairs for all domains exist
loop: "{{ send_only_mail_server__mail_domains }}"
ansible.builtin.include_tasks: ensure_dkim_keypair.yaml
- name: make sure the Rspamd `dkim_signing.conf` is deployed
ansible.builtin.template:
src: etc_rspamd_dkim_signing.conf.j2
dest: /etc/rspamd/local.d/dkim_signing.conf
owner: root
group: root
mode: "0600"
become: true
notify: Restart `rspamd.service`
- name: make sure the Rspamd `settings.conf` is deployed
ansible.builtin.copy:
src: etc_rspamd_settings.conf
dest: /etc/rspamd/local.d/settings.conf
owner: root
group: root
mode: "0600"
become: true
notify: Restart `rspamd.service`

View file

@ -0,0 +1,12 @@
allow_username_mismatch = true;
use_esld = false;
domain {
{% for mail_domain in send_only_mail_server__mail_domains %}
{{ mail_domain.name }} {
path = "/etc/mail-dkim/{{ mail_domain.name }}.key";
selector = "key";
}
{% endfor %}
}

View file

@ -0,0 +1,15 @@
# Managed by Ansible.
# This configuration enables sending emails using this server, but to not receiving any.
pki {{ send_only_mail_server__mail_server_fqdn }} cert "/etc/ansible_certs/certs/{{ send_only_mail_server__mail_server_fqdn }}/fullchain.pem"
pki {{ send_only_mail_server__mail_server_fqdn }} key "/etc/ansible_certs/certs/{{ send_only_mail_server__mail_server_fqdn }}/privkey.pem"
filter "rspamd-dkim-signing" proc-exec "filter-rspamd -settings-id dkim_signing"
listen on lo
listen on eth0 smtps pki {{ send_only_mail_server__mail_server_fqdn }} auth filter "rspamd-dkim-signing"
listen on eth0 tls-require pki {{ send_only_mail_server__mail_server_fqdn }} auth filter "rspamd-dkim-signing"
action "outbound" relay helo {{ send_only_mail_server__mail_server_fqdn }}
match from any auth for any action "outbound"

View file

@ -0,0 +1,4 @@
debug
zone {{ item.zone }}
update add key._domainkey.{{ item.name }} 60 TXT v=DKIM1;k=rsa;p={{ send_only_mail_server__dkim_public_key.publickey | replace('\n', '') | replace('-----BEGIN PUBLIC KEY-----', '') | replace('-----END PUBLIC KEY-----', '') }}
send

View file

@ -0,0 +1,4 @@
debug
zone {{ item.zone }}
update delete key._domainkey.{{ item.name }} TXT
send