diff --git a/.ansible-lint b/.ansible-lint index 6b21768..b04781e 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -1,6 +1,5 @@ --- warn_list: - - '106' - - '204' - - '405' - - '601' + - role-name + - name[play] + - name[casing] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7c00f3c..bc43ab5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,15 +15,17 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out the codebase - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Set up Python 3 - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: '3.x' - name: Install test dependencies - run: pip install ansible-lint[community,yamllint] + run: | + pip install ansible-lint + ansible-galaxy install -r requirements.yml - name: Lint code run: | @@ -42,12 +44,9 @@ jobs: fail-fast: false matrix: include: - - distro: debian8 - ansible-version: '<2.10' - - distro: debian9 - distro: debian10 - - distro: ubuntu1604 - ansible-version: '>=2.9, <2.10' + - distro: debian11 + - distro: debian12 - distro: ubuntu1604 ansible-version: '>=2.10, <2.11' - distro: ubuntu1604 @@ -56,17 +55,17 @@ jobs: steps: - name: Check out the codebase - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: path: "${{ github.repository }}" - name: Set up Python 3 - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: '3.x' - name: Install test dependencies - run: pip install 'ansible${{ matrix.ansible-version }}' molecule[docker] docker + run: pip install 'ansible${{ matrix.ansible-version }}' molecule-plugins[docker] docker - name: Run Molecule tests run: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5b34abe..5cc5164 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out the codebase - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Publish to Galaxy uses: robertdebock/galaxy-action@1.2.0 diff --git a/Dockerfile b/Dockerfile index b179278..6ebe0c4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,20 @@ -FROM ubuntu:16.04 +FROM ubuntu:18.04 MAINTAINER Mischa ter Smitten +ENV LANG C.UTF-8 +ENV LC_ALL C.UTF-8 + # python RUN apt-get update && \ - DEBIAN_FRONTEND=noninteractive apt-get install -y python-minimal python-dev curl && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y python3-minimal python3-dev curl && \ apt-get clean -RUN curl -sL https://bootstrap.pypa.io/pip/2.7/get-pip.py | python - +RUN curl -sL https://bootstrap.pypa.io/pip/3.6/get-pip.py | python3 - RUN rm -rf $HOME/.cache # ansible -RUN DEBIAN_FRONTEND=noninteractive apt-get install -y gcc libffi-dev libssl-dev && \ +RUN DEBIAN_FRONTEND=noninteractive apt-get install -y python3-apt && \ apt-get clean -RUN pip install ansible==2.9.15 +RUN pip3 install ansible==2.10.7 RUN rm -rf $HOME/.cache # provision diff --git a/README.md b/README.md index 94bc81b..05d7817 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ None * `postfix_default_database_type` [default: `hash`]: The default database type for use in `newaliases`, `postalias` and `postmap` commands * `postfix_aliases` [default: `[]`]: Aliases to ensure present in `/etc/aliases` + * `postfix_aliases_database_type` [default: `"{{ postfix_default_database_type }}"`]: The database type for aliases * `postfix_virtual_aliases` [default: `[]`]: Virtual aliases to ensure present in `/etc/postfix/virtual` * `postfix_sender_canonical_maps` [default: `[]`]: Sender address rewriting in `/etc/postfix/sender_canonical_maps` ([see](http://www.postfix.org/postconf.5.html#transport_maps)) * `postfix_sender_canonical_maps_database_type` [default: `"{{ postfix_default_database_type }}"`]: The database type for use in `postfix_sender_canonical_maps` @@ -69,6 +70,7 @@ None * `postfix_smtpd_tls_cert_file` [default: `/etc/ssl/certs/ssl-cert-snakeoil.pem`]: Path to certificate file * `postfix_smtpd_tls_key_file` [default: `/etc/ssl/certs/ssl-cert-snakeoil.key`]: Path to key file + * `postfix_smtpd_security_level` [optional]: The SMTP TLS security level for the Postfix SMTP server ([see](http://www.postfix.org/postconf.5.html#smtpd_tls_security_level)) * `postfix_raw_options` [default: `[]`]: List of lines (to pass extra (unsupported) configuration) * `postfix_smtp_tls_mandatory_ciphers` [default: `undefined`]: The minimum TLS cipher grade that the Postfix SMTP client will use with mandatory TLS ([see](https://www.postfix.org/postconf.5.html#smtp_tls_mandatory_ciphers)) * `postfix_smtp_tls_mandatory_protocols` [default: `undefined`]: TLS protocols that the Postfix SMTP client will use with mandatory TLS encryption ([see](https://www.postfix.org/postconf.5.smtp_tls_mandatory_protocols)) @@ -91,7 +93,7 @@ A simple example that doesn't use SASL relaying: --- - hosts: all roles: - - postfix + - oefenweb.postfix vars: postfix_aliases: - user: root @@ -104,7 +106,7 @@ A simple example with virtual aliases for mail forwarding that doesn't use SASL --- - hosts: all roles: - - postfix + - oefenweb.postfix vars: postfix_mydestination: - "{{ postfix_hostname }}" @@ -125,7 +127,7 @@ A simple example that rewrites the sender address: --- - hosts: all roles: - - postfix + - oefenweb.postfix vars: postfix_sender_canonical_maps: - sender: root @@ -138,7 +140,7 @@ Provide the relay host name if you want to enable relaying: --- - hosts: all roles: - - postfix + - oefenweb.postfix vars: postfix_aliases: - user: root @@ -152,7 +154,7 @@ Provide the relay domain name and use MX records if you want to enable relaying --- - hosts: all roles: - - postfix + - oefenweb.postfix vars: postfix_aliases: - user: root @@ -167,7 +169,7 @@ Conditional relaying: --- - hosts: all roles: - - postfix + - oefenweb.postfix vars: postfix_transport_maps: - pattern: 'root@yourdomain.org' @@ -183,13 +185,27 @@ Conditional relaying: result: "smtp:{{ ansible_lo['ipv4']['address'] }}:1025" ``` +Aliases with regexp table (forward all local mail to specified address): + +```yaml +--- +- hosts: all + roles: + - oefenweb.postfix + vars: + postfix_aliases_database_type: regexp + postfix_aliases: + - user: /.*/ + alias: you@yourdomain.org +``` + For AWS SES support: ```yaml --- - hosts: all roles: - - postfix + - oefenweb.postfix vars: postfix_aliases: - user: root @@ -207,7 +223,7 @@ For MailHog support: --- - hosts: all roles: - - postfix + - oefenweb.postfix vars: postfix_aliases: - user: root @@ -223,7 +239,7 @@ For Gmail support: --- - hosts: all roles: - - postfix + - oefenweb.postfix vars: postfix_aliases: - user: root @@ -248,7 +264,7 @@ A simple example that shows how to add some raw config: --- - hosts: all roles: - - postfix + - oefenweb.postfix vars: postfix_raw_options: - | diff --git a/Vagrantfile b/Vagrantfile index a0182a0..7f58430 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -26,23 +26,23 @@ boxes = [ :ram => "384" }, { - :name => "debian-8", - :box => "bento/debian-8", - :ip => '10.0.0.16', + :name => "debian-10", + :box => "bento/debian-10", + :ip => '10.0.0.18', :cpu => "50", :ram => "256" }, { - :name => "debian-9", - :box => "bento/debian-9", - :ip => '10.0.0.17', + :name => "debian-11", + :box => "bento/debian-11", + :ip => '10.0.0.19', :cpu => "50", :ram => "256" }, { - :name => "debian-10", - :box => "bento/debian-10", - :ip => '10.0.0.18', + :name => "debian-12", + :box => "bento/debian-12", + :ip => '10.0.0.20', :cpu => "50", :ram => "256" }, diff --git a/defaults/main.yml b/defaults/main.yml index 0ae3c00..7ff626f 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -12,6 +12,7 @@ postfix_mailname: "{{ ansible_fqdn }}" postfix_default_database_type: hash postfix_aliases: [] +postfix_aliases_database_type: "{{ postfix_default_database_type }}" postfix_virtual_aliases: [] postfix_sender_canonical_maps: [] postfix_sender_canonical_maps_database_type: "{{ postfix_default_database_type }}" diff --git a/handlers/main.yml b/handlers/main.yml index 0315064..ce2d541 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -1,54 +1,62 @@ # handlers file --- - name: new aliases - command: > + ansible.builtin.command: > newaliases - when: postfix_default_database_type != 'regexp' + when: postfix_aliases_database_type != 'regexp' + changed_when: true - name: new virtual aliases - command: > + ansible.builtin.command: > postmap {{ postfix_default_database_type }}:{{ postfix_virtual_aliases_file }} when: postfix_default_database_type != 'regexp' + changed_when: true - name: postmap sasl_passwd - command: > + ansible.builtin.command: > postmap {{ postfix_default_database_type }}:{{ postfix_sasl_passwd_file }} when: postfix_default_database_type != 'regexp' + changed_when: true - name: postmap sender_canonical_maps - command: > + ansible.builtin.command: > postmap {{ postfix_sender_canonical_maps_database_type }}:{{ postfix_sender_canonical_maps_file }} when: postfix_sender_canonical_maps_database_type != 'regexp' + changed_when: true - name: postmap recipient_canonical_maps - command: > + ansible.builtin.command: > postmap {{ postfix_recipient_canonical_maps_database_type }}:{{ postfix_recipient_canonical_maps_file }} when: postfix_recipient_canonical_maps_database_type != 'regexp' + changed_when: true - name: postmap transport_maps - command: > + ansible.builtin.command: > postmap {{ postfix_transport_maps_database_type }}:{{ postfix_transport_maps_file }} when: postfix_transport_maps_database_type != 'regexp' + changed_when: true - name: postmap sender_dependent_relayhost_maps - command: > + ansible.builtin.command: > postmap {{ postfix_default_database_type }}:{{ postfix_sender_dependent_relayhost_maps_file }} when: postfix_default_database_type != 'regexp' + changed_when: true - name: postmap generic - command: > + ansible.builtin.command: > postmap {{ postfix_smtp_generic_maps_database_type }}:{{ postfix_smtp_generic_maps_file }} when: postfix_smtp_generic_maps_database_type != 'regexp' + changed_when: true - name: remove pid - file: + ansible.builtin.file: path: "~postfix/pid/master.pid" state: absent listen: restart postfix when: is_docker_guest - name: restart service - service: + ansible.builtin.service: name: postfix state: restarted listen: restart postfix diff --git a/meta/main.yml b/meta/main.yml index e7459bf..e919379 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -7,7 +7,7 @@ galaxy_info: company: Oefenweb.nl B.V. description: Set up a postfix server in Debian-like systems license: MIT - min_ansible_version: 2.9.0 + min_ansible_version: 2.10.0 platforms: - name: Ubuntu versions: @@ -16,9 +16,9 @@ galaxy_info: - focal - name: Debian versions: - - jessie - - stretch - buster + - bullseye + - bookworm galaxy_tags: - system - web diff --git a/molecule/default/collections.yml b/molecule/default/collections.yml new file mode 100644 index 0000000..c3d7e2a --- /dev/null +++ b/molecule/default/collections.yml @@ -0,0 +1,6 @@ +--- +collections: + - name: community.docker + version: '>=1.2.0,<2' + - name: community.general + version: '>=2,<3' diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml index fbb7120..8841165 100644 --- a/molecule/default/molecule.yml +++ b/molecule/default/molecule.yml @@ -8,7 +8,9 @@ platforms: image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu1604}-ansible:latest" command: ${MOLECULE_DOCKER_COMMAND:-""} volumes: - - /sys/fs/cgroup:/sys/fs/cgroup:ro + - /sys/fs/cgroup:/sys/fs/cgroup:rw + - /var/lib/containerd + cgroupns_mode: host privileged: true pre_build_image: true provisioner: diff --git a/requirements.yml b/requirements.yml new file mode 100644 index 0000000..3d5f1cd --- /dev/null +++ b/requirements.yml @@ -0,0 +1,3 @@ +# requirements file +--- +collections: [] diff --git a/tasks/main.yml b/tasks/main.yml index 69aac5d..e50749c 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,7 +1,7 @@ # tasks file --- - name: facts | set - set_fact: + ansible.builtin.set_fact: is_docker_guest: "{{ ansible_virtualization_role | default('host') == 'guest' and ansible_virtualization_type | default('none') == 'docker' }}" tags: - configuration @@ -9,7 +9,7 @@ - postfix-facts - name: configure debconf - debconf: + ansible.builtin.debconf: name: "{{ item.name }}" question: "{{ item.question }}" value: "{{ item.value }}" @@ -21,7 +21,7 @@ - postfix-install - name: install package - apt: + ansible.builtin.apt: name: "{{ postfix_install }}" state: "{{ apt_install_state | default('latest') }}" update_cache: true @@ -32,7 +32,7 @@ - postfix-install - name: configure mailname - template: + ansible.builtin.template: src: "{{ postfix_mailname_file.lstrip('/') }}.j2" dest: "{{ postfix_mailname_file }}" owner: root @@ -45,7 +45,7 @@ - postfix-mailname - name: update configuration file - template: + ansible.builtin.template: src: "{{ postfix_main_cf.lstrip('/') }}.j2" dest: "{{ postfix_main_cf }}" owner: root @@ -58,7 +58,7 @@ - postfix-configuration - name: configure sasl username/password - template: + ansible.builtin.template: src: "{{ postfix_sasl_passwd_file.lstrip('/') }}.j2" dest: "{{ postfix_sasl_passwd_file }}" owner: root @@ -77,7 +77,7 @@ - postfix-sasl-passwd - name: configure aliases - template: + ansible.builtin.template: src: "{{ postfix_aliases_file.lstrip('/') }}.j2" dest: "{{ postfix_aliases_file }}" owner: root @@ -92,11 +92,11 @@ - postfix-aliases - name: check if aliases.db exists - stat: + ansible.builtin.stat: path: "{{ postfix_aliases_file }}.db" register: _aliasesdb changed_when: not _aliasesdb.stat.exists - when: postfix_default_database_type == 'hash' + when: postfix_aliases_database_type == 'hash' notify: - new aliases - restart postfix @@ -106,7 +106,7 @@ - postfix-aliases - name: configure virtual aliases - lineinfile: + ansible.builtin.lineinfile: dest: "{{ postfix_virtual_aliases_file }}" regexp: '^{{ item.virtual | regex_escape }}\s.*' line: '{{ item.virtual }} {{ item.alias }}' @@ -125,7 +125,7 @@ - postfix-virtual-aliases - name: configure sender canonical maps - lineinfile: + ansible.builtin.lineinfile: dest: "{{ postfix_sender_canonical_maps_file }}" regexp: '^{{ item.sender | regex_escape }}\s.*' line: '{{ item.sender }} {{ item.rewrite }}' @@ -144,7 +144,7 @@ - postfix-sender-canonical-maps - name: configure recipient canonical maps - lineinfile: + ansible.builtin.lineinfile: dest: "{{ postfix_recipient_canonical_maps_file }}" regexp: '^{{ item.recipient | regex_escape }}\s.*' line: '{{ item.recipient }} {{ item.rewrite }}' @@ -163,7 +163,7 @@ - postfix-recipient-canonical-maps - name: configure transport maps - lineinfile: + ansible.builtin.lineinfile: dest: "{{ postfix_transport_maps_file }}" regexp: '^{{ item.pattern | regex_escape }}\s.*' line: '{{ item.pattern }} {{ item.result }}' @@ -182,7 +182,7 @@ - postfix-transport-maps - name: configure sender dependent relayhost maps - lineinfile: + ansible.builtin.lineinfile: dest: "{{ postfix_sender_dependent_relayhost_maps_file }}" regexp: '^{{ item.pattern | regex_escape }}\s.*' line: '{{ item.pattern }} {{ item.result }}' @@ -201,7 +201,7 @@ - postfix-sender-dependent-relayhost-maps - name: configure generic table - lineinfile: + ansible.builtin.lineinfile: dest: "{{ postfix_smtp_generic_maps_file }}" regexp: '^{{ item.pattern | regex_escape }}\s.*' line: '{{ item.pattern }} {{ item.result }}' @@ -220,7 +220,7 @@ - postfix-generic-table - name: configure header checks - template: + ansible.builtin.template: src: "{{ postfix_header_checks_file.lstrip('/') }}.j2" dest: "{{ postfix_header_checks_file }}" owner: root @@ -234,7 +234,7 @@ - postfix-header-checks-table - name: start and enable service - service: + ansible.builtin.service: name: postfix state: "{{ service_default_state | default('started') }}" enabled: "{{ service_default_enabled | default(true) | bool }}" diff --git a/templates/etc/aliases.j2 b/templates/etc/aliases.j2 index 8dedf5e..3652d01 100644 --- a/templates/etc/aliases.j2 +++ b/templates/etc/aliases.j2 @@ -1,7 +1,13 @@ {{ ansible_managed | comment }} # See man 5 aliases for format +{% if postfix_aliases_database_type == 'regexp' %} +{% for alias in postfix_aliases %} +{{ alias.user }} {{ alias.alias }} +{% endfor %} +{% else %} postmaster: root {% for alias in postfix_aliases %} {{ alias.user }}: {{ alias.alias }} {% endfor %} +{% endif %} diff --git a/templates/etc/postfix/main.cf.j2 b/templates/etc/postfix/main.cf.j2 index 6338785..f80df9c 100644 --- a/templates/etc/postfix/main.cf.j2 +++ b/templates/etc/postfix/main.cf.j2 @@ -25,7 +25,10 @@ compatibility_level = {{ postfix_compatibility_level }} # TLS parameters smtpd_tls_cert_file = {{ postfix_smtpd_tls_cert_file }} smtpd_tls_key_file = {{ postfix_smtpd_tls_key_file }} -smtpd_use_tls=yes +smtpd_use_tls = yes +{% if postfix_smtpd_tls_security_level is defined %} +smtpd_tls_security_level = {{ postfix_smtpd_tls_security_level }} +{% endif %} smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache @@ -59,8 +62,8 @@ smtp_tls_protocols = {{ postfix_smtp_tls_protocols }} myhostname = {{ postfix_hostname }} default_database_type = {{ postfix_default_database_type }} -alias_maps = {{ postfix_default_database_type }}:{{ postfix_aliases_file }} -alias_database = {{ postfix_default_database_type }}:{{ postfix_aliases_file }} +alias_maps = {{ postfix_aliases_database_type }}:{{ postfix_aliases_file }} +alias_database = {{ postfix_aliases_database_type }}:{{ postfix_aliases_file }} {% if postfix_virtual_aliases %} virtual_alias_maps = {{ postfix_default_database_type }}:{{ postfix_virtual_aliases_file }} {% endif %}