Skip to content

Commit

Permalink
Merge pull request #7 from idsys-unibe-ch/feature/mrolli/3-support-se…
Browse files Browse the repository at this point in the history
…nder_canonical-map

Support sender_canoncial lookup tables
  • Loading branch information
mrolli authored Jun 14, 2023
2 parents 80131e8 + 3ebacfa commit ad58643
Show file tree
Hide file tree
Showing 15 changed files with 262 additions and 2 deletions.
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,47 @@ Use the local account you want to forward mails for as the key and either a
string or list of strings for the mail addresses to forward these mails to. In
the above example, mails to root are forwarded to two external addresses instead.

#### sender_canonical map

##### hash type map

postfix_sender_canonicals: []

This allows setting sender canonical addresses in the database
`hash:/etc/postfix/sender_canonical` in order to rewrite sender addresses to be
sure bounces can be routed back to valid address.
This can be used to rewrite local accounts:

Examples:

postfix_sender_canonicals:
- root: existing.user@example.com

By adding mappings here the hash map is automatically added to the
sender_canonical_map configuration option of Postfix.

##### ldap type map

postfix_ldap_sender_canonincal_config: {}

This config dictionary allows to configure lookups of sender_canonicals stored
in an LDAP directory. Use configuration parameters as described in the official
documentation on [that topic](https://www.postfix.org/ldap_table.5.html). An
example using two LDAP servers as a failover setup and transport encryption
might look as follows:

postfix_ldap_sender_canonincal_config:
server_host: "ldap://ldap01.mycompany.com ldap://ldap02.mycompany.com"
start_tls: "yes"
version: "3"
bind: "no"
search_base: "ou=users,dc=mycompany,dc=com"
query_filter: "(uid=%s)"
result_attribute: "mail"

By adding a configuration here the ldap map is automatically added to the
sender_canonical_map configuration option of Postfix.

### Configuring Package and Service State

postfix_enabled: true
Expand Down
6 changes: 6 additions & 0 deletions defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ postfix_inet_protocols: all
# Dictionary with mail aliases that are managed in /etc/aliases
postfix_alias_map: {}

# Array with sender canoncial mappings
postfix_sender_canonicals: []

# Dictionary holding config parameters for the /etc/postfix/ldap-sender_canonical.cf
postfix_sender_canonical_ldap_config: {}

# The relayhost parameter specifies the default host to send mail to.
# Specify a domain, host, host:port, [host]:port, [address] or [address]:port;
# the form [host] turns off MX lookups.
Expand Down
15 changes: 14 additions & 1 deletion handlers/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,26 @@
- name: Rebuild alias database
ansible.builtin.command:
cmd: postalias "{{ postfix_alias_path }}"
changed_when: false
changed_when: yes
listen: rebuild_aliases_db

- name: Rebuild sender_canonical database
ansible.builtin.command:
cmd: postmap "{{ __postfix_sender_canonical_path }}"
changed_when: yes
listen: rebuild_sender_canonical_db

# Restart postfix service
- name: Restart postfix service
ansible.builtin.service:
name: "{{ postfix_service }}"
state: "{{ postfix_restart_state }}"
listen: "restart-postifx"
when: postfix_state | default('started') == 'started'

- name: Reload postfix service
ansible.builtin.service:
name: "{{ postfix_service }}"
state: "reloaded"
listen: "reload-postfix"
when: postfix_state | default('started') == 'started'
8 changes: 8 additions & 0 deletions molecule/default/verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@
register: aliases
failed_when: aliases is changed

- name: No sender_canonical file is present
ansible.builtin.file:
path: /etc/postfix/sender_canonical
state: absent
check_mode: true
register: sender_canonical
failed_when: sender_canonical is changed

- name: Postfix service is running
ansible.builtin.wait_for:
port: 25
Expand Down
21 changes: 21 additions & 0 deletions molecule/lookup-tables/converge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
- name: Deploy different Postfix lookup tables

hosts: all
vars:
postfix_sender_canonicals:
- root: elmar.fudge@example.com
- user1@test.com: road.runner@example.com
postfix_sender_canonical_ldap_config:
server_host: "ldap://ldap01.mycompany.com"
start_tls: "yes"
version: "3"
bind: "no"
search_base: "ou=users,dc=mycompany,dc=com"
query_filter: "(uid=%s)"
result_attribute: "mail"

tasks:
- name: "Include unibe_idsys.postfix"
ansible.builtin.include_role:
name: "unibe_idsys.postfix"
19 changes: 19 additions & 0 deletions molecule/lookup-tables/molecule.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
role_name_check: 1
dependency:
name: galaxy
driver:
name: podman
platforms:
- name: ${MOLECULE_DISTRO:-rockylinux9}
image: "geerlingguy/docker-${MOLECULE_DISTRO:-rockylinux9}-ansible:latest"
command: ${MOLECULE_DOCKER_COMMAND:-""}
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
cgroupns_mode: host
privileged: true
pre_build_image: true
provisioner:
name: ansible
playbooks:
converge: ${MOLECULE_PLAYBOOK:-converge.yml}
55 changes: 55 additions & 0 deletions molecule/lookup-tables/verify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
- name: Verify the different lookup maps work correctly
hosts: all
gather_facts: false

tasks:
- name: Sender canonical for root is correctly set
ansible.builtin.lineinfile:
path: /etc/postfix/sender_canonical
regexp: "^root\\s+elmar.fudge@example.com$"
state: absent
check_mode: true
register: sender_canonical
changed_when: false
failed_when: not sender_canonical.found

- name: Sender canonical for user1@test.com is correctly set
ansible.builtin.lineinfile:
path: /etc/postfix/sender_canonical
regexp: "^user1@test.com\\s+road.runner@example.com$"
state: absent
check_mode: true
register: sender_canonical
changed_when: false
failed_when: not sender_canonical.found

- name: Check ldap-canonical.cf for option start_tls
ansible.builtin.lineinfile:
path: /etc/postfix/ldap-sender_canonical.cf
regexp: "^start_tls = yes$"
state: absent
check_mode: true
register: ldap_option
changed_when: false
failed_when: not ldap_option.found

- name: Check ldap-canonical.cf for option result_attribute
ansible.builtin.lineinfile:
path: /etc/postfix/ldap-sender_canonical.cf
regexp: "^result_attribute = mail$"
state: absent
check_mode: true
register: ldap_option
changed_when: false
failed_when: not ldap_option.found

- name: Check if both tables are in the sender_canonical_map
ansible.builtin.lineinfile:
path: /etc/postfix/main.cf
regexp: "^sender_canonical_map = hash:/etc/postfix/sender_canonical, ldap:/etc/postfix/ldap-sender_canonical.cf$"
state: absent
check_mode: true
register: ldap_option
changed_when: false
failed_when: not ldap_option.found
29 changes: 29 additions & 0 deletions tasks/ldap_sender_canonical_cf.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
- name: Manage configuration parameter file
when: postfix_sender_canonical_ldap_config.server_host is defined
notify:
- reload-postfix
block:
- name: Prepare template variable
ansible.builtin.set_fact:
__postfix_config_params: "{{ postfix_sender_canonical_ldap_config }}"

- name: Add table to sender_canonical_map in main.cf
ansible.builtin.set_fact:
__postfix_sender_canonical_maps: "{{ __postfix_sender_canonical_maps + ['ldap:{{ __postfix_sender_canonical_ldap_config_path }}'] }}"

- name: "Manage entries in {{ __postfix_sender_canonical_ldap_config_path }}"
ansible.builtin.template:
src: "configfile.j2"
dest: "{{ __postfix_sender_canonical_ldap_config_path }}"
mode: 0644

- name: Remove mapping files
when: postfix_sender_canonical_ldap_config.server_host is not defined
notify:
- reload-postfix
block:
- name: Remove map file
ansible.builtin.file:
path: "{{ __postfix_sender_canonical_ldap_config_path }}"
state: absent
8 changes: 8 additions & 0 deletions tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@
- name: Include OS-specific tasks
ansible.builtin.include_tasks: "setup_{{ ansible_os_family | lower }}.yml"

- name: Proccess sender_canonical hash map
ansible.builtin.import_tasks:
file: sender_canonical_map.yml

- name: Process ldap-sender_canonical.cf
ansible.builtin.import_tasks:
file: ldap_sender_canonical_cf.yml

- name: Create /etc/postfix/main.cf
ansible.builtin.template:
src: "main.cf-{{ ansible_os_family | lower }}.j2"
Expand Down
35 changes: 35 additions & 0 deletions tasks/sender_canonical_map.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
- name: Manage mapping entries
when: postfix_sender_canonicals | length > 0
notify:
- rebuild_sender_canonical_db
- reload-postfix
block:
- name: Prepare template variable
ansible.builtin.set_fact:
__postfix_mappings: "{{ postfix_sender_canonicals }}"

- name: Add table to sender_canonical_map in main.cf
ansible.builtin.set_fact:
__postfix_sender_canonical_maps: "{{ __postfix_sender_canonical_maps + ['hash:{{ __postfix_sender_canonical_path }}'] }}"

- name: "Manage entries in {{ __postfix_sender_canonical_path }}"
ansible.builtin.template:
src: "mapfile.j2"
dest: "{{ __postfix_sender_canonical_path }}"
mode: 0644

- name: Remove mapping files
when: postfix_sender_canonicals | length == 0
notify:
- reload-postfix
block:
- name: Remove map file
ansible.builtin.file:
path: "{{ __postfix_sender_canonical_path }}"
state: absent

- name: Remove db file
ansible.builtin.file:
path: "{{ __postfix_sender_canonical_path }}.db"
state: absent
5 changes: 5 additions & 0 deletions templates/configfile.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# {{ ansible_managed }}

{% for param, value in __postfix_config_params.items() %}
{{ param }} = {{ value }}
{% endfor %}
4 changes: 4 additions & 0 deletions templates/main.cf-debian.j2
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,7 @@ mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = {{ postfix_inet_interfaces }}
inet_protocols = {{ postfix_inet_protocols }}

{% if __postfix_sender_canonical_maps | length > 0 %}
sender_canonical_map = {{ __postfix_sender_canonical_maps | join(", ") }}
{% endif %}
4 changes: 4 additions & 0 deletions templates/main.cf-redhat.j2
Original file line number Diff line number Diff line change
Expand Up @@ -749,3 +749,7 @@ smtp_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt
smtp_tls_security_level = may
meta_directory = /etc/postfix
shlib_directory = /usr/lib64/postfix

{% if __postfix_sender_canonical_maps | length > 0 %}
sender_canonical_map = {{ __postfix_sender_canonical_maps | join(", ") }}
{% endif %}
7 changes: 7 additions & 0 deletions templates/mapfile.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# {{ ansible_managed }}

{% for mapping in __postfix_mappings %}
{% for key, value in mapping.items() %}
{{ key }} {{ value }}
{% endfor %}
{% endfor %}
7 changes: 6 additions & 1 deletion vars/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,10 @@ postfix_packages:
# Name of the postfix systemd service
postfix_service: postfix

# Default alias file
# Default database files
postfix_alias_path: /etc/aliases

# sender_canonical related option names and filepaths
__postfix_sender_canonical_maps: []
__postfix_sender_canonical_path: /etc/postfix/sender_canonical
__postfix_sender_canonical_ldap_config_path: /etc/postfix/ldap-sender_canonical.cf

0 comments on commit ad58643

Please sign in to comment.