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
				
			
		
							
								
								
									
										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