Add send_only_mailserver role and deploy Send-Only-Mailserver with it
		
	Co-authored-by: yuri <yuri@nekover.se>
This commit is contained in:
		
					parent
					
						
							
								f4a79fb4e2
							
						
					
				
			
			
				commit
				
					
						b56ca3899d
					
				
			
		
					 14 changed files with 263 additions and 0 deletions
				
			
		
							
								
								
									
										8
									
								
								inventories/z9/host_vars/send-only-mailserver.yaml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								inventories/z9/host_vars/send-only-mailserver.yaml
									
										
									
									
									
										Normal 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
 | 
			
		||||
| 
						 | 
				
			
			@ -27,3 +27,6 @@ all:
 | 
			
		|||
        keycloak:
 | 
			
		||||
          ansible_host: keycloak.z9.ccchh.net
 | 
			
		||||
          ansible_user: chaos
 | 
			
		||||
        send-only-mailserver:
 | 
			
		||||
          ansible_host: send-only-mailserver.z9.ccchh.net
 | 
			
		||||
          ansible_user: chaos
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										6
									
								
								playbooks/deploy_send_only_mailserver.yaml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								playbooks/deploy_send_only_mailserver.yaml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
---
 | 
			
		||||
- name: Deploy the Send-Only-Mailserver
 | 
			
		||||
  hosts: send-only-mailserver
 | 
			
		||||
  become: true
 | 
			
		||||
  roles:
 | 
			
		||||
    - send_only_mail_server
 | 
			
		||||
							
								
								
									
										35
									
								
								playbooks/roles/send_only_mail_server/README.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								playbooks/roles/send_only_mail_server/README.md
									
										
									
									
									
										Normal 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/>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
dkim_signing {
 | 
			
		||||
    id = "dkim_signing";
 | 
			
		||||
    apply {
 | 
			
		||||
        symbols_enabled = ["DKIM_SIGNED"];
 | 
			
		||||
        flags = ["skip_process"]; # Disable expensive MIME processing
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								playbooks/roles/send_only_mail_server/handlers/main.yaml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								playbooks/roles/send_only_mail_server/handlers/main.yaml
									
										
									
									
									
										Normal 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
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
							
								
								
									
										7
									
								
								playbooks/roles/send_only_mail_server/meta/main.yaml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								playbooks/roles/send_only_mail_server/meta/main.yaml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
dependencies: # noqa meta-no-info
 | 
			
		||||
  - role: distribution_check
 | 
			
		||||
    vars:
 | 
			
		||||
      distribution_check__supported_distributions:
 | 
			
		||||
        - name: Debian
 | 
			
		||||
          versions:
 | 
			
		||||
            - "11"
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
							
								
								
									
										65
									
								
								playbooks/roles/send_only_mail_server/tasks/main.yaml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								playbooks/roles/send_only_mail_server/tasks/main.yaml
									
										
									
									
									
										Normal 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`
 | 
			
		||||
| 
						 | 
				
			
			@ -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 %}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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"
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,4 @@
 | 
			
		|||
debug
 | 
			
		||||
zone {{ item.zone }}
 | 
			
		||||
update delete key._domainkey.{{ item.name }} TXT
 | 
			
		||||
send
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue