summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@spreadspace.org>2024-07-10 18:00:32 +0200
committerChristian Pointner <equinox@spreadspace.org>2024-07-10 18:00:32 +0200
commit63a3ecbe58c2bb192c5693af3939eb9e29877e65 (patch)
tree7b0eace6670557a6154f8930342c883c28b115ed
parentmove postfix rules to mail subdir (diff)
add extended postfix roles
-rw-r--r--chaos-at-home/ch-testvm-prometheus.yml18
-rw-r--r--inventory/host_vars/ch-testvm-prometheus.yml72
-rw-r--r--roles/mail/opendkim/defaults/main.yml26
-rw-r--r--roles/mail/opendkim/handlers/main.yml9
-rw-r--r--roles/mail/opendkim/tasks/dkim-key.yml37
-rw-r--r--roles/mail/opendkim/tasks/main.yml105
-rw-r--r--roles/mail/opendkim/templates/KeyTable.j25
-rw-r--r--roles/mail/opendkim/templates/SigningTable.j23
-rw-r--r--roles/mail/postfix/relay/defaults/main.yml14
-rw-r--r--roles/mail/postfix/relay/filter_plugins/postfix.py25
-rw-r--r--roles/mail/postfix/relay/handlers/main.yml5
-rw-r--r--roles/mail/postfix/relay/tasks/main.yml64
-rw-r--r--roles/mail/postfix/submission/defaults/main.yml21
-rw-r--r--roles/mail/postfix/submission/handlers/main.yml10
-rw-r--r--roles/mail/postfix/submission/tasks/main.yml79
-rw-r--r--roles/mail/postfix/submission/tasks/saslauthd-ldap.yml29
-rw-r--r--roles/mail/postfix/submission/tasks/saslauthd.yml48
17 files changed, 570 insertions, 0 deletions
diff --git a/chaos-at-home/ch-testvm-prometheus.yml b/chaos-at-home/ch-testvm-prometheus.yml
new file mode 100644
index 00000000..a63dcc71
--- /dev/null
+++ b/chaos-at-home/ch-testvm-prometheus.yml
@@ -0,0 +1,18 @@
+---
+- name: Basic Setup
+ hosts: ch-testvm-prometheus
+ roles:
+ - role: apt-repo/base
+ - role: core/base
+ - role: core/sshd/base
+ - role: core/zsh
+ - role: core/ntp
+
+- name: Payload Setup
+ hosts: ch-testvm-prometheus
+ roles:
+ - role: x509/static-ca/base
+ - role: mail/opendkim
+ - role: mail/postfix/base
+ - role: mail/postfix/relay
+ - role: mail/postfix/submission
diff --git a/inventory/host_vars/ch-testvm-prometheus.yml b/inventory/host_vars/ch-testvm-prometheus.yml
index 879ef694..1c9bcfab 100644
--- a/inventory/host_vars/ch-testvm-prometheus.yml
+++ b/inventory/host_vars/ch-testvm-prometheus.yml
@@ -37,3 +37,75 @@ network:
ntp_variant: systemd-timesyncd
sshd_allowusers_host: "{{ normal_users_host | union(admin_users_host) | union(['greenbone']) }}"
+
+
+## test
+
+opendkim_admin_mail: postmaster@chaox.org
+opendkim_internal_hosts:
+ - 127.0.0.1
+ - "{{ network_zones.lan.prefix }}"
+ - "{{ network_zones.svc.prefix }}"
+
+opendkim_domains:
+ chaox.org:
+ keys:
+ test-2024-07:
+ keylength: 2048
+
+
+postfix_base_mynetworks:
+ - "127.0.0.0/8"
+ - "[::ffff:127.0.0.0]/104"
+ - "[::1]/128"
+ - "{{ network_zones.svc.prefix }}"
+ - "{{ network_zones.lan.prefix }}"
+
+postfix_base_mydestination:
+ - "$myhostname"
+ - "{{ host_name }}.{{ host_domain }}"
+ - "localhost"
+ - mailrelay.chaox.org
+
+postfix_base_inet_interfaces:
+ - "all"
+
+postfix_base_relayhost: 192.168.28.250
+
+
+postfix_relay_sender_canonical_maps:
+ rewrite_chaox_subdomains:
+ type: regexp
+ content: |
+ /^(.+)@(.+)\.chaox\.org$/i ${1}%${2}@chaox.org
+
+postfix_relay_local_header_rewrite_clients:
+ - "permit_inet_interfaces"
+ - "permit_mynetworks"
+
+postfix_relay_dkim_signer: "opendkim"
+
+
+postfix_submission_hostname: mailrelay.chaox.org
+
+postfix_submission_tls:
+ certificate_provider: static-ca
+ certificate_config:
+ ca:
+ key_content: "{{ chaos_at_home_internal_ca_key }}"
+ cert_content: "{{ chaos_at_home_internal_ca_cert }}"
+
+
+postfix_submission_auth_saslauthd:
+ mechanism: ldap
+ ldap_options:
+ auth_method: fastbind
+ servers: ldaps://ldap.chaos-at-home.org
+ tls_check_peer: yes
+ tls_cacert_content: "{{ chaos_at_home_internal_ca_cert }}"
+ filter: "%u@chaos-at-home.org"
+
+postfix_submission_allowed_sender_domains:
+ - chaox.org
+
+postfix_submission_dkim_signer: "opendkim"
diff --git a/roles/mail/opendkim/defaults/main.yml b/roles/mail/opendkim/defaults/main.yml
new file mode 100644
index 00000000..22636720
--- /dev/null
+++ b/roles/mail/opendkim/defaults/main.yml
@@ -0,0 +1,26 @@
+---
+opendkim_sign: yes
+opendkim_verify: no
+
+opendkim_socket_for_postfix: yes
+
+# opendkim_admin_mail:
+
+# opendkim_internal_hosts:
+# - 127.0.0.1/8
+# - 192.168.0.0/24
+
+# opendkim_domains:
+# example.com:
+# keys:
+# test-2022-07:
+# keylength: 2048
+# test-2021-03:
+# keylength: 2048
+# example.foo:
+# keys:
+# bar:
+# content: |
+# -----BEGIN RSA PRIVATE KEY-----
+# ....
+# -----END RSA PRIVATE KEY-----
diff --git a/roles/mail/opendkim/handlers/main.yml b/roles/mail/opendkim/handlers/main.yml
new file mode 100644
index 00000000..5d328ca3
--- /dev/null
+++ b/roles/mail/opendkim/handlers/main.yml
@@ -0,0 +1,9 @@
+---
+- name: reload systemd
+ systemd:
+ daemon_reload: yes
+
+- name: restart opendkim
+ service:
+ name: opendkim
+ state: restarted
diff --git a/roles/mail/opendkim/tasks/dkim-key.yml b/roles/mail/opendkim/tasks/dkim-key.yml
new file mode 100644
index 00000000..02ac34db
--- /dev/null
+++ b/roles/mail/opendkim/tasks/dkim-key.yml
@@ -0,0 +1,37 @@
+---
+- name: create sub directory for keys
+ file:
+ path: "/etc/opendkim/keys/{{ opendkim_domain.key }}"
+ state: directory
+ mode: 0700
+ owner: opendkim
+ group: opendkim
+
+- name: install precomputed keys
+ loop: "{{ opendkim_domain.value['keys'] | dict2items | selectattr('value.content', 'defined') }}"
+ loop_control:
+ label: "{{ item.key }}@{{ opendkim_domain.key }}"
+ copy:
+ dest: "/etc/opendkim/keys/{{ opendkim_domain.key }}/{{ item.key }}.private"
+ content: "{{ item.value.content }}"
+ mode: 0600
+ owner: opendkim
+ group: opendkim
+
+- name: generate DKIM keys
+ loop: "{{ opendkim_domain.value['keys'] | dict2items | rejectattr('value.content', 'defined') }}"
+ loop_control:
+ label: "{{ item.key }}@{{ opendkim_domain.key }}"
+ command: "opendkim-genkey -b {{ item.value.keylength }} -s {{ item.key }} -d {{ opendkim_domain.key }} -D '/etc/opendkim/keys/{{ opendkim_domain.key }}'"
+ args:
+ creates: "/etc/opendkim/keys/{{ opendkim_domain.key }}/{{ item.key }}.private"
+
+- name: fix permission for generated DKIM keys
+ loop: "{{ opendkim_domain.value['keys'] | dict2items | rejectattr('value.content', 'defined') }}"
+ loop_control:
+ label: "{{ item.key }}@{{ opendkim_domain.key }}"
+ file:
+ path: "/etc/opendkim/keys/{{ opendkim_domain.key }}/{{ item.key }}.private"
+ mode: 0600
+ owner: opendkim
+ group: opendkim
diff --git a/roles/mail/opendkim/tasks/main.yml b/roles/mail/opendkim/tasks/main.yml
new file mode 100644
index 00000000..615b45e0
--- /dev/null
+++ b/roles/mail/opendkim/tasks/main.yml
@@ -0,0 +1,105 @@
+---
+- name: install opendkim packages
+ apt:
+ name:
+ - opendkim
+ - opendkim-tools
+ state: present
+
+- name: create configure sub directory
+ file:
+ path: /etc/opendkim
+ state: directory
+ mode: 0700
+ owner: opendkim
+ group: opendkim
+
+- name: remove annoying sample Socket options
+ lineinfile:
+ regexp: "^#Socket\\s+"
+ state: absent
+ dest: /etc/opendkim.conf
+ notify: restart opendkim
+
+- name: set opendkim default options
+ set_fact:
+ opendkim_options_default:
+ Mode: "{{ opendkim_sign | ternary('s','') }}{{ opendkim_verify | ternary('v','') }}"
+ ReportAddress: "{{ opendkim_admin_mail }}"
+ LogWhy: "yes"
+ opendkim_options_postfix: {}
+ opendkim_options_sign: {}
+ opendkim_options_verify: {}
+
+- name: prepare opendkim to be used with chrooted postfix
+ when: opendkim_socket_for_postfix
+ block:
+ - name: set opendkim postfix options
+ set_fact:
+ opendkim_options_postfix:
+ Socket: "local:/var/spool/postfix/opendkim/opendkim.sock"
+
+ - name: create systemd override directory
+ file:
+ path: /etc/systemd/system/opendkim.service.d
+ state: directory
+
+ - name: add systemd service override
+ copy:
+ content: |
+ [Service]
+ ExecStartPre=+/usr/bin/install -d /var/spool/postfix/opendkim -o opendkim -g opendkim -m 0750
+ dest: /etc/systemd/system/opendkim.service.d/postfix-chroot.conf
+ notify: reload systemd
+
+ - name: configure opendkim listen socket for legacy init
+ lineinfile:
+ dest: /etc/default/opendkim
+ regexp: '^SOCKET='
+ line: 'SOCKET="local:/var/spool/postfix/opendkim/opendkim.sock"'
+ notify: restart opendkim
+
+- name: prepare opendkim for signing
+ when: opendkim_sign
+ block:
+ - name: set opendkim sign options
+ set_fact:
+ opendkim_options_sign:
+ InternalHosts: "{{ opendkim_internal_hosts | join(', ') }}"
+ KeyTable: "refile:/etc/opendkim/KeyTable"
+ SigningTable: "refile:/etc/opendkim/SigningTable"
+
+ - name: generate/install dkim keys
+ loop: "{{ opendkim_domains | dict2items }}"
+ loop_control:
+ loop_var: opendkim_domain
+ label: "{{ opendkim_domain.key }}"
+ include_tasks: dkim-key.yml
+
+ - name: install KeyTable and SingingTable
+ loop:
+ - KeyTable
+ - SigningTable
+ template:
+ src: "{{ item }}.j2"
+ dest: "/etc/opendkim/{{ item }}"
+ notify: restart opendkim
+
+## TODO: implement this
+# - name: prepare opendkim for verifying
+# when: opendkim_verify
+# block:
+# - name: set opendkim verify options
+# set_fact:
+# opendkim_options_verify:
+# option: "value"
+
+- name: configure opendkim
+ loop: "{{ opendkim_options_default | combine(opendkim_options_postfix) | combine(opendkim_options_sign) | combine(opendkim_options_verify) | dict2items }}"
+ loop_control:
+ label: "{{ item.key }} = {{ item.value }}"
+ lineinfile:
+ regexp: "^#?\\s*{{ item.key }}\\s+"
+ line: "{{ item.key }}\t\t\t{{ item.value }}"
+ dest: /etc/opendkim.conf
+ notify: restart opendkim
diff --git a/roles/mail/opendkim/templates/KeyTable.j2 b/roles/mail/opendkim/templates/KeyTable.j2
new file mode 100644
index 00000000..99061267
--- /dev/null
+++ b/roles/mail/opendkim/templates/KeyTable.j2
@@ -0,0 +1,5 @@
+{% for domain in opendkim_domains %}
+{% for selector in opendkim_domains[domain]['keys'] %}
+{{ selector }}._domainkey.{{ domain }} {{ domain }}:{{ selector }}:/etc/opendkim/keys/{{ domain }}/{{ selector }}.private
+{% endfor %}
+{% endfor %}
diff --git a/roles/mail/opendkim/templates/SigningTable.j2 b/roles/mail/opendkim/templates/SigningTable.j2
new file mode 100644
index 00000000..bfadaac5
--- /dev/null
+++ b/roles/mail/opendkim/templates/SigningTable.j2
@@ -0,0 +1,3 @@
+{% for domain in opendkim_domains %}
+*@{{ domain }} {{ opendkim_domains[domain]['keys'] | first }}._domainkey.{{ domain }}
+{% endfor %}
diff --git a/roles/mail/postfix/relay/defaults/main.yml b/roles/mail/postfix/relay/defaults/main.yml
new file mode 100644
index 00000000..806e019f
--- /dev/null
+++ b/roles/mail/postfix/relay/defaults/main.yml
@@ -0,0 +1,14 @@
+---
+# postfix_relay_local_header_rewrite_clients:
+# - "permit_inet_interfaces"
+# - "permit_mynetworks"
+# - "permit_sasl_authenticated"
+
+# postfix_relay_sender_canonical_maps:
+# rewrite_example_subdomains:
+# type: regexp
+# content: |
+# /^(.+)@(.+)\.example\.com$/i ${1}%${2}@example.com
+
+postfix_relay_dkim_signer: "none"
+# postfix_relay_dkim_signer: "opendkim"
diff --git a/roles/mail/postfix/relay/filter_plugins/postfix.py b/roles/mail/postfix/relay/filter_plugins/postfix.py
new file mode 100644
index 00000000..673cba0b
--- /dev/null
+++ b/roles/mail/postfix/relay/filter_plugins/postfix.py
@@ -0,0 +1,25 @@
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+from ansible import errors
+
+
+def postfix_maps(maps, prefix=''):
+ try:
+ tmp = []
+ for name, map in maps.items():
+ tmp.append('%s:%s%s' % (map['type'], prefix, name))
+ return ', '.join(tmp)
+ except Exception as e:
+ raise errors.AnsibleFilterError("postfix_maps(): %s" % str(e))
+
+
+class FilterModule(object):
+
+ ''' postfix helpers '''
+ filter_map = {
+ 'postfix_maps': postfix_maps,
+ }
+
+ def filters(self):
+ return self.filter_map
diff --git a/roles/mail/postfix/relay/handlers/main.yml b/roles/mail/postfix/relay/handlers/main.yml
new file mode 100644
index 00000000..bea754c9
--- /dev/null
+++ b/roles/mail/postfix/relay/handlers/main.yml
@@ -0,0 +1,5 @@
+---
+- name: restart postfix
+ service:
+ name: postfix
+ state: restarted
diff --git a/roles/mail/postfix/relay/tasks/main.yml b/roles/mail/postfix/relay/tasks/main.yml
new file mode 100644
index 00000000..b622bf7f
--- /dev/null
+++ b/roles/mail/postfix/relay/tasks/main.yml
@@ -0,0 +1,64 @@
+---
+- name: install canonical maps
+ when: postfix_relay_sender_canonical_maps is defined
+ block:
+ - name: create subdirectory for canonical maps
+ file:
+ path: /etc/postfix/canonical
+ state: directory
+
+ - name: install canoncial maps
+ loop: "{{ postfix_relay_sender_canonical_maps | dict2items }}"
+ loop_control:
+ label: "{{ item.key }} ({{ item.value.type }})"
+ copy:
+ content: "{{ item.value.content }}"
+ dest: "/etc/postfix/canonical/{{ item.key }}"
+ register: sender_canonical_maps_status
+
+ - name: generate canoncial maps
+ loop: "{{ sender_canonical_maps_status.results | select('changed') }}"
+ loop_control:
+ label: "{{ item.item.key }} ({{ item.item.value.type }})"
+ command: postmap "/etc/postfix/canonical/{{ item.item.key }}"
+
+ - name: configure sender canonical maps
+ lineinfile:
+ regexp: "^#?\\s*sender_canonical_maps\\s*="
+ line: "sender_canonical_maps = {{ postfix_relay_sender_canonical_maps | postfix_maps('/etc/postfix/canonical/') }}"
+ dest: /etc/postfix/main.cf
+ notify: restart postfix
+
+- name: configure local_header_rewrite_clients
+ when: postfix_relay_local_header_rewrite_clients is defined
+ lineinfile:
+ regexp: "^#?\\s*local_header_rewrite_clients\\s*="
+ line: "local_header_rewrite_clients = {{ postfix_relay_local_header_rewrite_clients | join(', ') }}"
+ dest: /etc/postfix/main.cf
+ notify: restart postfix
+
+- name: configure dkim signing using opendkim
+ when: postfix_relay_dkim_signer == "opendkim"
+ block:
+ - name: add postfix user to opendkim group
+ user:
+ name: postfix
+ groups: opendkim
+ append: yes
+ notify: restart postfix
+
+ - name: configure postfix milter config for opendkim
+ vars:
+ postfix_options:
+ milter_protocol: "6"
+ milter_default_action: "accept"
+ smtpd_milters: "unix:opendkim/opendkim.sock"
+ non_smtpd_milters: "unix:opendkim/opendkim.sock"
+ loop: "{{ postfix_options | dict2items }}"
+ loop_control:
+ label: "{{ item.key }} = {{ item.value }}"
+ lineinfile:
+ regexp: "^#?\\s*{{ item.key }}\\s*="
+ line: "{{ item.key }} = {{ item.value }}"
+ dest: /etc/postfix/main.cf
+ notify: restart postfix
diff --git a/roles/mail/postfix/submission/defaults/main.yml b/roles/mail/postfix/submission/defaults/main.yml
new file mode 100644
index 00000000..6ea29e91
--- /dev/null
+++ b/roles/mail/postfix/submission/defaults/main.yml
@@ -0,0 +1,21 @@
+---
+# postfix_submission_hostname: mailrelay.example.com
+
+# postfix_submission_tls:
+# certificate_provider: {{ acme_client }}
+
+# postfix_submission_auth_saslauthd:
+# mechanism: ldap
+# ldap_options:
+# auth_method: fastbind
+# servers: ldap://ldap.exmaple.com
+# start_tls: yes
+# tls_check_peer: yes
+# tls_cacert_file: "{{ global_files_dir }}/common/ldapscert.pem"
+# ldap_filter: "uid=%u,dc=example,dc=com"
+
+# postfix_submission_allowed_sender_domains:
+# - example.com
+
+postfix_submission_dkim_signer: "none"
+# postfix_submission_dkim_signer: "opendkim"
diff --git a/roles/mail/postfix/submission/handlers/main.yml b/roles/mail/postfix/submission/handlers/main.yml
new file mode 100644
index 00000000..68ad2bf2
--- /dev/null
+++ b/roles/mail/postfix/submission/handlers/main.yml
@@ -0,0 +1,10 @@
+---
+- name: restart saslauthd
+ service:
+ name: saslauthd
+ state: restarted
+
+- name: restart postfix
+ service:
+ name: postfix
+ state: restarted
diff --git a/roles/mail/postfix/submission/tasks/main.yml b/roles/mail/postfix/submission/tasks/main.yml
new file mode 100644
index 00000000..981f1511
--- /dev/null
+++ b/roles/mail/postfix/submission/tasks/main.yml
@@ -0,0 +1,79 @@
+---
+- name: install access table for allowed sender domains
+ when: postfix_submission_allowed_sender_domains is defined
+ block:
+ - name: create subdirectory for submission specific config
+ file:
+ path: /etc/postfix/submission
+ state: directory
+
+ - name: install access table for allowed domains
+ copy:
+ content: |
+ {% for domain in postfix_submission_allowed_sender_domains %}
+ /@{{ domain | replace('.', '\.') }}$/ OK
+ {% endfor %}
+ /@/ REJECT
+ dest: /etc/postfix/submission/allowed-sender-domains
+ register: allowed_sender_domains_status
+
+ - name: generate access table for allowed domains
+ when: allowed_sender_domains_status is changed
+ command: postmap /etc/postfix/submission/allowed-sender-domains
+
+- name: install and configure saslauthd
+ when: postfix_submission_auth_saslauthd is defined
+ include_tasks: saslauthd.yml
+
+- name: generate/install/fetch TLS certificate
+ when: postfix_submission_tls is defined
+ vars:
+ x509_certificate_name: "postfix-{{ postfix_submission_hostname }}"
+ x509_certificate_config: "{{ postfix_submission_tls.certificate_config | default({}) }}"
+ x509_certificate_hostnames:
+ - "{{ postfix_submission_hostname }}"
+ x509_certificate_reload_services:
+ - postfix
+ include_role:
+ name: "x509/{{ postfix_submission_tls.certificate_provider }}/cert"
+
+- name: add postfix user to opendkim group
+ when: postfix_submission_dkim_signer == "opendkim"
+ user:
+ name: postfix
+ groups: opendkim
+ append: yes
+ notify: restart postfix
+
+- name: configure postfix submission daemon
+ blockinfile:
+ marker: "# {mark} ansible postfix/submission"
+ block: |
+ submission inet n - y - - smtpd
+ -o myhostname={{ postfix_submission_hostname }}
+ {% if postfix_submission_tls is defined %}
+ -o smtpd_tls_key_file={{ x509_certificate_path_key }}
+ -o smtpd_tls_cert_file={{ x509_certificate_path_fullchain }}
+ -o smtpd_tls_security_level=encrypt
+ -o smtpd_tls_mandatory_protocols=!SSLv2,!SSLv3,!TLSv1,!TLSv1.1
+ -o smtpd_tls_mandatory_ciphers=medium
+ -o tls_medium_cipherlist=ECDHE+CHACHA20:ECDHE+AESGCM:DHE+CHACHA20:DHE+AESGCM:ECDHE+AES256:DHE+AES256:ECDHE+AES128:DHE+AES128:!ADH:!AECDH:!MD5:!SHA
+ -o tls_preempt_cipherlist=no
+ {% endif %}
+ -o smtpd_sasl_auth_enable=yes
+ -o smtpd_sasl_path=submission
+ -o smtpd_sasl_security_options=noanonymous
+ {% if postfix_submission_allowed_sender_domains is defined %}
+ -o { smtpd_sender_restrictions=reject_non_fqdn_sender,check_sender_access regexp:/etc/postfix/submission/allowed-sender-domains,permit_sasl_authenticated,reject }
+ {% else %}
+ -o smtpd_sender_restrictions=reject_non_fqdn_sender,permit_sasl_authenticated,reject
+ {% endif %}
+ -o smtpd_recipient_restrictions=reject_non_fqdn_recipient,reject_unknown_recipient_domain
+ {% if postfix_submission_dkim_signer == 'opendkim' %}
+ -o milter_protocol=6
+ -o milter_default_action=accept
+ -o smtpd_milters=unix:opendkim/opendkim.sock
+ -o non_smtpd_milters=unix:opendkim/opendkim.sock
+ {% endif %}
+ dest: /etc/postfix/master.cf
+ notify: restart postfix
diff --git a/roles/mail/postfix/submission/tasks/saslauthd-ldap.yml b/roles/mail/postfix/submission/tasks/saslauthd-ldap.yml
new file mode 100644
index 00000000..55f1ece9
--- /dev/null
+++ b/roles/mail/postfix/submission/tasks/saslauthd-ldap.yml
@@ -0,0 +1,29 @@
+---
+- name: prepare ldap options for salsauthd
+ set_fact:
+ saslauthd_ldap_options: "{{ postfix_submission_auth_saslauthd.ldap_options }}"
+
+- name: install and configure ldap server certificate
+ when: "'tls_cacert_file' in postfix_submission_auth_saslauthd.ldap_options or 'tls_cacert_content' in postfix_submission_auth_saslauthd.ldap_options"
+ block:
+ - name: install ldap server certificate
+ copy:
+ src: "{{ postfix_submission_auth_saslauthd.ldap_options.tls_cacert_file | default(omit) }}"
+ content: "{{ postfix_submission_auth_saslauthd.ldap_options.tls_cacert_content | default(omit) }}"
+ dest: /etc/saslauthd-ldapscert.pem
+ notify: restart saslauthd
+
+ - name: update ca certificate file path in ldap options
+ set_fact:
+ saslauthd_ldap_options: "{{ saslauthd_ldap_options | combine({'tls_cacert_file': '/etc/saslauthd-ldapscert.pem'}) }}"
+
+- name: generate salsuathd config for ldap
+ copy:
+ content: |
+ {% for option,value in saslauthd_ldap_options.items() %}
+ {% if option != 'tls_cacert_content' %}
+ ldap_{{ option }}: {{ value }}
+ {% endif %}
+ {% endfor %}
+ dest: /etc/saslauthd.conf
+ notify: restart saslauthd
diff --git a/roles/mail/postfix/submission/tasks/saslauthd.yml b/roles/mail/postfix/submission/tasks/saslauthd.yml
new file mode 100644
index 00000000..065fb255
--- /dev/null
+++ b/roles/mail/postfix/submission/tasks/saslauthd.yml
@@ -0,0 +1,48 @@
+---
+- name: install saslauthd and sasl-modules
+ apt:
+ name:
+ - sasl2-bin
+ - libsasl2-modules
+ state: present
+
+- name: basic saslauthd options
+ vars:
+ saslauthd_options:
+ START: "yes"
+ MECHANISMS: "{{ postfix_submission_auth_saslauthd.mechanism }}"
+ OPTIONS: "-c -m /var/spool/postfix/saslauthd"
+ loop: "{{ saslauthd_options | dict2items }}"
+ loop_control:
+ label: "{{ item.key }} = {{ item.value }}"
+ lineinfile:
+ regexp: '^#?\s*{{ item.key }}\s*='
+ line: '{{ item.key }}="{{ item.value }}"'
+ dest: /etc/default/saslauthd
+ notify: restart saslauthd
+
+- name: configure saslauthd mechanism
+ include_tasks: "saslauthd-{{ postfix_submission_auth_saslauthd.mechanism }}.yml"
+
+- name: configure postfix sasl via saslauthd
+ copy:
+ content: |
+ pwcheck_method: saslauthd
+ saslauthd_path: /saslauthd/mux
+ mech_list: plain login
+ dest: /etc/postfix/sasl/submission.conf
+ notify: restart postfix
+
+- name: add postfix user to sasl group
+ user:
+ name: postfix
+ groups: sasl
+ append: yes
+ notify: restart postfix
+
+- name: make sure saslauthd service is enabled and started
+ systemd:
+ daemon_reload: yes
+ name: saslauthd.service
+ enabled: yes
+ state: started