From 9110d9df828d17d0ababa1ba12607b6dd88a6514 Mon Sep 17 00:00:00 2001 From: genofire Date: Fri, 23 Oct 2020 03:32:54 +0200 Subject: [PATCH] Add a Postfix role and apply it to emma Changes #10 --- host_vars/emma.ccchb.de | 5 + library/postconf_master | 129 +++++ mail.yml | 9 + roles/postfix/handlers/main.yml | 18 + roles/postfix/tasks/main.yml | 145 ++++++ roles/postfix/templates/header_checks.j2 | 4 + roles/postfix/templates/helo_checks.j2 | 4 + roles/postfix/templates/local_recipients.j2 | 5 + roles/postfix/templates/mynetworks.j2 | 4 + roles/postfix/templates/postfix-log/finish.j2 | 13 + roles/postfix/templates/postfix-log/run.j2 | 25 + roles/postfix/templates/postfix/data/check.j2 | 18 + roles/postfix/templates/postfix/finish.j2 | 13 + roles/postfix/templates/postfix/run.j2 | 14 + .../templates/postscreen_dnsbl_reply_map.j2 | 11 + roles/postfix/templates/rbl_override.j2 | 5 + roles/postfix/templates/sender_access.j2 | 5 + roles/postfix/templates/virtual_aliases.j2 | 5 + roles/postfix/vars/main.yml | 467 ++++++++++++++++++ site.yml | 1 + 20 files changed, 900 insertions(+) create mode 100644 library/postconf_master create mode 100644 mail.yml create mode 100644 roles/postfix/handlers/main.yml create mode 100644 roles/postfix/tasks/main.yml create mode 100644 roles/postfix/templates/header_checks.j2 create mode 100644 roles/postfix/templates/helo_checks.j2 create mode 100644 roles/postfix/templates/local_recipients.j2 create mode 100644 roles/postfix/templates/mynetworks.j2 create mode 100644 roles/postfix/templates/postfix-log/finish.j2 create mode 100644 roles/postfix/templates/postfix-log/run.j2 create mode 100644 roles/postfix/templates/postfix/data/check.j2 create mode 100644 roles/postfix/templates/postfix/finish.j2 create mode 100644 roles/postfix/templates/postfix/run.j2 create mode 100644 roles/postfix/templates/postscreen_dnsbl_reply_map.j2 create mode 100644 roles/postfix/templates/rbl_override.j2 create mode 100644 roles/postfix/templates/sender_access.j2 create mode 100644 roles/postfix/templates/virtual_aliases.j2 create mode 100644 roles/postfix/vars/main.yml diff --git a/host_vars/emma.ccchb.de b/host_vars/emma.ccchb.de index 38aae46..a2598e9 100644 --- a/host_vars/emma.ccchb.de +++ b/host_vars/emma.ccchb.de @@ -1,6 +1,11 @@ --- dovecot_listen: '[2a01:4f8:150:926f::2], 176.9.59.104' +postfix_inet_interfaces: '[2a01:4f8:150:926f::2], 176.9.59.104' +postfix_my_networks: + - '2a01:4f8:150:926f::2' + - '176.9.59.104' + haproxy_v4: 176.9.59.104 haproxy_v6: 2a01:4f8:150:926f::2 diff --git a/library/postconf_master b/library/postconf_master new file mode 100644 index 0000000..50d7612 --- /dev/null +++ b/library/postconf_master @@ -0,0 +1,129 @@ +#!/usr/bin/python + +ANSIBLE_METADATA = { + 'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community' +} + +DOCUMENTATION = ''' +--- +module: postconf + +short_description: Module for Postfix postconf + +version_added: "2.4" + +description: + - "This is module for setup Postfix variables in main.cf with postconf command" + +options: + name: + description: + - Variable name. + required: true + value: + description: + - Value of the variable. Required if C(state=present). + required: false + default: null + state: + description: + - Whether to ensure that the variable is present or absent. + required: false + default: present + choices: [ "present", "absent" ] + + +extends_documentation_fragment: + - system + +author: + - Alexander Galato (@alet) +''' + +EXAMPLES = ''' +# Assign value +- name: Make myhostname be equial "gateway.home" + postconf: + name: myhostname + value: gateway.home + +# Remove variable from config file +- name: Remove milter_protocol + postconf: + name: milter_protocol + state: absent +''' + +from ansible.module_utils.basic import AnsibleModule + +def test_var(module, postconf_path, postconf_arg): + postconf_arg += " -H" + rc, out, err = module.run_command("%s %s %s" % (postconf_path, postconf_arg, module.params["name"])) + if rc != 0: + return False + + return True + +def query_var(module, postconf_path, postconf_arg): + postconf_arg += " -h" + rc, out, err = module.run_command("%s %s %s" % (postconf_path, postconf_arg, module.params["name"])) + if rc != 0: + return False + + if out.rstrip() != module.params["value"]: + return False + + return True + + +def set_value(module, postconf_path, postconf_arg): + if query_var(module, postconf_path, postconf_arg): + return (False, "The variable already set in value %s" % module.params["value"]) + rc, out, err = module.run_command("%s %s %s=\"%s\"" % (postconf_path, postconf_arg, module.params["name"], module.params["value"])) + if rc != 0: + module.fail_json(msg="Could not set variable") + + return (True, "Variable was set") + +def remove_value(module, postconf_path, postconf_arg): + if test_var(module, postconf_path, postconf_arg): + postconf_arg += " -X" + rc, out, err = module.run_command("%s %s %s" % (postconf_path, postconf_arg, module.params["name"])) + if rc == 0: + return (True, "Variable was removed") + + return (False, "Variable was not removed") + +def main(): + module_args = dict( + name=dict(type='str', required=True), + value=dict(type='str', required=False, default=''), + state=dict(type='str', required=False, default='present', choises=["present", "absent"]), + ) + + module = AnsibleModule( + argument_spec = module_args, + supports_check_mode = True, + ) + + postconf_path = module.get_bin_path('postconf', True) + p = module.params + + changed = False + message = '' + postconf_arg = "-P" + + if p["value"] is None and p["state"] == "present" : + module.fail_json(msg="You must specify 'value' to setup variable") + + if p["state"] == "present": + changed, msg = set_value(module, postconf_path, postconf_arg) + elif p["state"] == "absent": + changed, msg = remove_value(module, postconf_path, postconf_arg) + + module.exit_json(changed=changed, msg=', '.join(message)) + +if __name__ == '__main__': + main() diff --git a/mail.yml b/mail.yml new file mode 100644 index 0000000..629dad4 --- /dev/null +++ b/mail.yml @@ -0,0 +1,9 @@ +--- +- hosts: + - mail + + become: yes + + roles: + - dovecot + - postfix diff --git a/roles/postfix/handlers/main.yml b/roles/postfix/handlers/main.yml new file mode 100644 index 0000000..7ee8c35 --- /dev/null +++ b/roles/postfix/handlers/main.yml @@ -0,0 +1,18 @@ +--- +- name: Reload s6-rc + service: + name: s6-rc + state: reloaded + +- name: Restart Postfix + command: s6-svc -t /run/service/postfix + +- name: Reload Postfix + command: s6-svc -h /run/service/postfix + +- name: Rebuild Postfix maps + command: 'postmap {{ item.type }}:{{ item.name }}' + args: + chdir: /usr/local/etc/postfix + when: item.type in postfix_rebuild_types + with_items: '{{ postfix_maps }}' diff --git a/roles/postfix/tasks/main.yml b/roles/postfix/tasks/main.yml new file mode 100644 index 0000000..ce2b6b1 --- /dev/null +++ b/roles/postfix/tasks/main.yml @@ -0,0 +1,145 @@ +--- +- name: Install Postfix + package: + name: postfix + state: present + notify: + - Restart Postfix + +- name: Create /usr/local/etc/mail + file: + path: /usr/local/etc/mail + state: directory + owner: root + group: wheel + mode: 0755 + +- name: Install Postfix mailer.conf + copy: + dest: /usr/local/etc/mail/mailer.conf + src: /usr/local/share/postfix/mailer.conf.postfix + remote_src: yes + owner: root + group: wheel + mode: 0644 + +- name: Disable sendmail + sysrc: + name: sendmail_enable + value: NONE + +- name: Make sure sendmail is stopped + service: + name: sendmail + state: stopped + +- name: Disable sendmail periodic tasks + lineinfile: + path: /etc/periodic.conf + owner: root + group: wheel + mode: 0444 + regexp: '^{{ item }}=' + line: '{{ item }}="NO"' + with_items: '{{ sendmail_periodic }}' + +- name: Add /var/log/postfix to fstab + mount: + path: /var/log/postfix + src: tmpfs + fstype: tmpfs + opts: 'rw,size={{ postfix_log_size }},mode={{ postfix_log_mode }},uid={{ postfix_log_uid }},gid={{ postfix_log_gid }},late' + state: mounted + +- name: Create Postfix service directories + file: + path: '/etc/s6-rc/service/{{ item }}' + state: directory + owner: root + group: wheel + mode: 0755 + with_items: '{{ postfix_service_dirs }}' + +- name: Generate Postfix service scripts + template: + dest: '/etc/s6-rc/service/{{ item }}' + src: '{{ item }}.j2' + mode: 0555 + owner: root + group: wheel + with_items: '{{ postfix_service_scripts }}' + notify: + - Reload s6-rc + - Restart Postfix + +- name: Generate Postfix service configuration + copy: + dest: '/etc/s6-rc/service/{{ item.name }}' + content: '{{ item.content }}' + mode: 0444 + owner: root + group: wheel + loop_control: + label: '{{ item.name }} = {{ item.content }}' + notify: + - Reload s6-rc + - Restart Postfix + with_items: '{{ postfix_service_config }}' + +- name: Generate Postfix maps + template: + dest: '/usr/local/etc/postfix/{{ item.name }}' + src: '{{ item.name }}.j2' + mode: 0444 + owner: root + group: wheel + with_items: '{{ postfix_maps }}' + notify: + - Rebuild Postfix maps + - Reload Postfix + +- name: Configure Postfix + postconf: + name: '{{ item.name }}' + value: '{{ item.value | default(omit) }}' + state: '{{ item.state | default(omit) }}' + with_items: '{{ postfix_config }}' + notify: + - Reload Postfix + +- name: Configure Postfix services + lineinfile: + path: /usr/local/etc/postfix/master.cf + regexp: '^{{ item.name }} +{{ item.type }}' + value: '{{ item.value }}' + with_items: '{{ postfix_services }}' + notify: + - Restart Postfix + +- name: Configure per service overrides + postconf_master: + name: '{{ item.name }}' + value: '{{ item.value | default(omit) }}' + state: '{{ item.state | default(omit) }}' + with_items: '{{ postfix_params }}' + notify: + - Restart Postfix + +- name: Flush handlers + meta: flush_handlers + +- name: Start Postfix + command: fdmove -c 2 1 s6-rc -u -v 2 change postfix + register: change + changed_when: change.stdout | length > 0 + +- name: Enable Postfix + lineinfile: + path: /etc/s6-rc/service/enabled/contents + regexp: "^postfix$" + line: "postfix" + notify: + - Reload s6-rc + +- name: Flush handlers (again) + meta: flush_handlers diff --git a/roles/postfix/templates/header_checks.j2 b/roles/postfix/templates/header_checks.j2 new file mode 100644 index 0000000..414ff1e --- /dev/null +++ b/roles/postfix/templates/header_checks.j2 @@ -0,0 +1,4 @@ +# {{ ansible_managed }} +/^Received:(.*)hispeedmailer\.com/ REJECT Mass-mailer. Bye bye spammer... +/^Subject:.*=\?(big5|euc-kr|gb2312|ks_c_5601-1987)\?/ REJECT No foreign character sets, please. +/^Subject:(.*)v[i1][a@4]+g*r[a@4]+/ REJECT No pills needed, thank you. diff --git a/roles/postfix/templates/helo_checks.j2 b/roles/postfix/templates/helo_checks.j2 new file mode 100644 index 0000000..e6f4cc6 --- /dev/null +++ b/roles/postfix/templates/helo_checks.j2 @@ -0,0 +1,4 @@ +# {{ ansible_managed }} +{% for line in postfix_helo_checks | default([]) %} +{{ line }} +{% endfor %} diff --git a/roles/postfix/templates/local_recipients.j2 b/roles/postfix/templates/local_recipients.j2 new file mode 100644 index 0000000..77c6982 --- /dev/null +++ b/roles/postfix/templates/local_recipients.j2 @@ -0,0 +1,5 @@ +{% for domain, users in dovecot_users.items() %} +{% for name, password in users.items() %} +{{ name }}@{{ domain }} OK +{% endfor %} +{% endfor %} diff --git a/roles/postfix/templates/mynetworks.j2 b/roles/postfix/templates/mynetworks.j2 new file mode 100644 index 0000000..3822748 --- /dev/null +++ b/roles/postfix/templates/mynetworks.j2 @@ -0,0 +1,4 @@ +# {{ ansible_managed }} +{% for addr in postfix_my_networks %} +{{ addr }} OK +{% endfor %} diff --git a/roles/postfix/templates/postfix-log/finish.j2 b/roles/postfix/templates/postfix-log/finish.j2 new file mode 100644 index 0000000..00e3945 --- /dev/null +++ b/roles/postfix/templates/postfix-log/finish.j2 @@ -0,0 +1,13 @@ +#!/usr/local/bin/execlineb -S2 +# {{ ansible_managed }} + +s6-envdir ./env +multisubstitute { + importas -i -u NAME NAME +} + +fdmove -c 1 2 +ifelse { test "${1}" -eq 0 } { + echo "${NAME}: Stopped." +} + echo "${NAME}: Failed with exit status (${1}, ${2})." diff --git a/roles/postfix/templates/postfix-log/run.j2 b/roles/postfix/templates/postfix-log/run.j2 new file mode 100644 index 0000000..0a210f1 --- /dev/null +++ b/roles/postfix/templates/postfix-log/run.j2 @@ -0,0 +1,25 @@ +#!/usr/local/bin/execlineb -P +# {{ ansible_managed }} + +s6-envdir ./env +multisubstitute { + importas -i -u NAME NAME + importas -i -u USER USER + importas -i -u GROUP GROUP + importas -i -u MODE MODE + importas -i -u DIR DIR +} + +foreground { fdmove -c 1 2 echo "${NAME} log: Starting." } + +ifelse -n { install -d -o "${USER}" -g "${GROUP}" -m "${MODE}" -- "${DIR}" } { + foreground { fdmove -c 1 2 echo "${NAME} log: Failed to create logging directory." } + false +} + +foreground { if -n { test -p "${DIR}/fifo" } mkfifo -m 0600 -- "${DIR}/fifo" } + +fdmove -c 2 1 +redirfd -u 0 "${DIR}/fifo" +s6-envuidgid $USER +s6-log -d 3 T $DIR diff --git a/roles/postfix/templates/postfix/data/check.j2 b/roles/postfix/templates/postfix/data/check.j2 new file mode 100644 index 0000000..541e3cc --- /dev/null +++ b/roles/postfix/templates/postfix/data/check.j2 @@ -0,0 +1,18 @@ +#!/usr/local/bin/execlineb -P +# {{ ansible_managed }} + +s6-envdir ./env +multisubstitute { + importas -i -u NAME NAME +} + +ifelse { + redirfd -w 1 /dev/null + fdmove -c 2 1 + postfix status +} { + foreground { fdmove -c 1 2 echo "${NAME}: Ready." } + true +} + foreground { fdmove -c 1 2 echo "${NAME}: Poll." } + false diff --git a/roles/postfix/templates/postfix/finish.j2 b/roles/postfix/templates/postfix/finish.j2 new file mode 100644 index 0000000..00e3945 --- /dev/null +++ b/roles/postfix/templates/postfix/finish.j2 @@ -0,0 +1,13 @@ +#!/usr/local/bin/execlineb -S2 +# {{ ansible_managed }} + +s6-envdir ./env +multisubstitute { + importas -i -u NAME NAME +} + +fdmove -c 1 2 +ifelse { test "${1}" -eq 0 } { + echo "${NAME}: Stopped." +} + echo "${NAME}: Failed with exit status (${1}, ${2})." diff --git a/roles/postfix/templates/postfix/run.j2 b/roles/postfix/templates/postfix/run.j2 new file mode 100644 index 0000000..b34f6c9 --- /dev/null +++ b/roles/postfix/templates/postfix/run.j2 @@ -0,0 +1,14 @@ +#!/usr/local/bin/execlineb -P +# {{ ansible_managed }} + +s6-envdir ./env +multisubstitute { + importas -i -u NAME NAME +} + +foreground { fdmove -c 1 2 echo "${NAME}: Starting." } +s6-notifyoncheck -d -w 100 -n 70 + +redirfd -u 1 /var/log/postfix/fifo +fdmove -c 2 1 +/usr/local/libexec/postfix/master -s diff --git a/roles/postfix/templates/postscreen_dnsbl_reply_map.j2 b/roles/postfix/templates/postscreen_dnsbl_reply_map.j2 new file mode 100644 index 0000000..f2fccf3 --- /dev/null +++ b/roles/postfix/templates/postscreen_dnsbl_reply_map.j2 @@ -0,0 +1,11 @@ +# {{ ansible_managed }} + +# We will be rejecting much mail which is listed in multiple DNSBLs. +# We're not proud of some of the lists we are using, thus have given +# them lower scores in postscreen_dnsbl_sites listing. So this checks +# the DNSBL name postscreen(8) gets from dnsblog(8), and if it's not +# one of our Tier 1 DNSBL sites, it changes what the sender will see: + +#/^b\.barracudacentral\.org$/ b.barracudacentral.org +#/^bl\.spameatingmonkey\.net$/ bl.spameatingmonkey.net +!/^zen\.spamhaus\.org$/ multiple DNS-based blocklists diff --git a/roles/postfix/templates/rbl_override.j2 b/roles/postfix/templates/rbl_override.j2 new file mode 100644 index 0000000..c950997 --- /dev/null +++ b/roles/postfix/templates/rbl_override.j2 @@ -0,0 +1,5 @@ +# {{ ansible_managed }} +{% for line in postfix_rbl_override | default([]) %} +{{ line }} +{% endfor %} + diff --git a/roles/postfix/templates/sender_access.j2 b/roles/postfix/templates/sender_access.j2 new file mode 100644 index 0000000..7ac06c5 --- /dev/null +++ b/roles/postfix/templates/sender_access.j2 @@ -0,0 +1,5 @@ +# {{ ansible_managed }} +{% for line in postfix_sender_access | default([]) %} +{{ line }} +{% endfor %} + diff --git a/roles/postfix/templates/virtual_aliases.j2 b/roles/postfix/templates/virtual_aliases.j2 new file mode 100644 index 0000000..6fda202 --- /dev/null +++ b/roles/postfix/templates/virtual_aliases.j2 @@ -0,0 +1,5 @@ +# {{ ansible_managed }} + +{% for line in postfix_virtual_aliases | default([]) %} +{{ line }} +{% endfor %} diff --git a/roles/postfix/vars/main.yml b/roles/postfix/vars/main.yml new file mode 100644 index 0000000..f3999d0 --- /dev/null +++ b/roles/postfix/vars/main.yml @@ -0,0 +1,467 @@ +--- +sendmail_periodic: + - daily_clean_hoststat_enable + - daily_status_mail_rejects_enable + - daily_status_include_submit_mailq + - daily_submit_queuerun + +postfix_log_size: '32m' +postfix_log_mode: '750' +postfix_log_uid: '20000' +postfix_log_gid: '20000' + +postfix_rebuild_types: + - hash + - btree + +postfix_maps: + - name: header_checks + type: regexp + - name: helo_checks + type: hash + - name: local_recipients + type: hash + - name: mynetworks + type: hash + - name: postscreen_dnsbl_reply_map + type: pcre + - name: rbl_override + type: hash + - name: virtual_aliases + type: hash + +postfix_helo_checks: + - localhost REJECT You're not me + +postfix_rbl_override: [] + +postfix_sender_access: + - hostepro.co.ua REJECT Die you fucking spammer! + - molingrush.co.ua REJECT Die you fucking spammer! + - jenreviews.com REJECT Die you fucking spammer! + - hes.net REJECT Die you fucking spammer! + - willsamaren.co.ua REJECT Die you fucking spammer! + - liluinc.eu REJECT Die you fucking spamemr! + - winsoker.co.ua REJECT Die you fucking spammer! + - mellingrush.eu REJECT Die you fucking spammer! + - newdgise.co.ua REJECT Die you fucking spammer! + - nicemaner.eu REJECT Die you fucking spammer! + - qr-hosting.eu REJECT Die you fucking spammer! + - villpubrel.com REJECT Die you fucking spammer! + - willi-bong.eu REJECT Die you fucking spammer! + - pgp.co.in REJECT Die you fucking spammer! + - rapnews.biz.ua REJECT Die you fucking spammer! + +postfix_virtual_aliases: + - root@ccchb.de crest@ccchb.de + - abuse@ccchb.de crest@ccchb.de + - noc@ccchb.de crest@ccchb.de + - security@ccchb.de crest@ccchb.de + - postmaster@ccchb.de crest@ccchb.de + - hostmaster@ccchb.de crest@ccchb.de + + - root@lists.ccchb.de crest@ccchb.de + - crest@lists.ccchb.de crest@ccchb.de + - abuse@lists.ccchb.de crest@ccchb.de + - noc@lists.ccchb.de crest@ccchb.de + - security@lists.ccchb.de crest@ccchb.de + - postmaster@lists.ccchb.de crest@ccchb.de + - hostmaster@lists.ccchb.de crest@ccchb.de + +postfix_service_dirs: + - postfix + - postfix/env + - postfix/data + - postfix-log + - postfix-log/env + +postfix_service_scripts: + - postfix/run + - postfix/finish + - postfix/data/check + - postfix-log/run + - postfix-log/finish + +postfix_service_config: + - name: postfix/type + content: longrun + - name: postfix/dependencies + content: postfix-log + - name: postfix/notification-fd + content: 3 + - name: postfix/env/NAME + content: postfix + - name: postfix/env/PATH + content: /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/root/bin + + - name: postfix-log/type + content: longrun + - name: postfix-log/notification-fd + content: 3 + - name: postfix-log/env/NAME + content: postfix + - name: postfix-log/env/PATH + content: /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/root/bin + - name: postfix-log/env/MODE + content: '750' + - name: postfix-log/env/USER + content: s6-log + - name: postfix-log/env/GROUP + content: s6-log + - name: postfix-log/env/DIR + content: /var/log/postfix + +postfix_config: + - name: compatibility_level + value: '2' + state: present + + - name: header_checks + value: 'regexp:$config_directory/header_checks' + state: present + + - name: inet_interfaces + value: '{{ postfix_inet_interfaces }}' + state: present + + - name: inet_protocols + value: 'ipv6, ipv4' + state: present + + - name: local_recipient_maps + value: 'hash:$config_directory/local_recipients $alias_maps' + state: present + + - name: maillog_file + value: '/var/log/postfix/fifo' + state: present + + - name: mailbox_transport + value: 'lmtp:unix:$queue_directory/private/dovecot-lmtp' + state: present + + - name: milter_default_action + value: 'accept' + state: present + + - name: milter_mail_macros + value: 'i {mail_addr} {client_addr} {client_name} {auth_authen}' + state: present + + - name: mua_client_restrictions + value: 'permit_sasl_authenticated, reject' + state: present + + - name: mua_helo_restrictions + value: 'permit_sasl_authenticated, reject' + state: present + + - name: mua_sender_restrictions + value: 'permit_sasl_authenticated, reject' + state: present + + - name: mydestination + value: '$myhostname, localhost.$mydomain, localhost, $mydomain' + state: present + + - name: mynetworks + value: 'cidr:$config_directory/mynetworks' + state: present + + - name: myorigin + value: '$mydomain' + state: present + + - name: postscreen_bare_newline_action + value: 'enforce' + state: present + + - name: postscreen_bare_newline_enable + value: 'yes' + state: present + + - name: postscreen_blacklist_action + value: 'drop' + state: present + + - name: postscreen_cache_map + value: 'hash:$data_directory/postscreen_cache' + state: present + + - name: postscreen_dnsbl_action + value: 'enforce' + state: present + + - name: postscreen_dnsbl_reply_map + value: 'pcre:$config_directory/postscreen_dnsbl_reply_map' + state: present + + - name: postscreen_dnsbl_sites + value: >- + zen.spamhaus.org*3 + b.barracudacentral.org*2 + bl.spameatingmonkey.net*2 + bl.spamcop.net + dnsbl.sorbs.net + psbl.surriel.com + bl.mailspike.net + swl.spamhaus.org*-4 + list.dnswl.org=127.0.[0..255].0*-2 + list.dnswl.org=127.0.[0..255].1*-3 + list.dnswl.org=127.0.[0..255].[2..3]*-4 + state: present + + - name: postscreen_dnsbl_threshold + value: '3' + state: present + + - name: postscreen_dnsbl_whitelist_threshold + value: '-1' + state: present + + - name: postscreen_greet_action + value: 'enforce' + state: present + + - name: postscreen_non_smtp_command_enable + value: 'yes' + state: present + + - name: postscreen_pipelining_enable + value: 'yes' + state: present + + - name: recipient_delimiter + value: '+' + state: present + + - name: smtp_tls_exclude_ciphers + value: 'aNULL' + state: present + + - name: smtp_tls_loglevel + value: '1' + state: present + + - name: smtp_tls_note_starttls_offer + value: 'yes' + state: present + + - name: smtp_tls_security_level + value: 'may' + state: present + + - name: smtp_tls_session_cache_database + value: 'btree:${data_directory}/smtp_scache' + state: present + + - name: smtpd_banner + value: '$myhostname ESMTP 8BIT-OK NO UCE NO UBE $mail_name' + state: present + + - name: smtpd_client_restrictions + value: >- + permit_sasl_authenticated, + permit_mynetworks, + reject_unknown_client, + check_client_access + hash:$config_directory/rbl_override, + reject_rbl_client cbl.abuseat.org, + reject_rbl_client sbl.spamhaus.org, + reject_rbl_client pbl.spamhaus.org, + reject_rbl_client ix.dnsbl.manitu.net + state: present + + - name: smtpd_helo_required + value: 'yes' + state: present + + - name: smtpd_helo_restrictions + value: >- + permit_sasl_authenticated, + permit_mynetworks, + reject_invalid_hostname, + reject_non_fqdn_hostname, + check_helo_access hash:$config_directory/helo_checks, + reject_unknown_hostname + state: present + + - name: smtpd_milters + value: 'unix:/var/run/rspamd/proxy.sock' + state: present + + - name: smtpd_recipient_restrictions + value: >- + permit_sasl_authenticated, + permit_mynetworks, + reject_non_fqdn_recipient, + reject_unknown_recipient_domain, + reject_unauth_destination + state: present + + - name: smtpd_sasl_auth_enable + value: 'yes' + state: present + + - name: smtpd_sasl_path + value: 'private/dovecot-auth' + state: present + + - name: smtpd_sender_restrictions + value: >- + permit_sasl_authenticated, + permit_mynetworks, + reject_non_fqdn_sender, + reject_unknown_sender_domain, + check_sender_access hash:$config_directory/sender_access + state: present + + - name: smtpd_tls_auth_only + value: 'yes' + state: present + + - name: smtpd_tls_cert_file + value: '/usr/local/etc/dovecot/fullchain.pem' + state: present + + - name: smtpd_tls_eecdh_grade + value: 'ultra' + state: present + + - name: smtpd_tls_exclude_ciphers + value: 'aNULL' + state: present + + - name: smtpd_tls_key_file + value: '/usr/local/etc/dovecot/privkey.pem' + state: present + + - name: smtpd_tls_loglevel + value: '1' + state: present + + - name: smtpd_tls_mandatory_ciphers + value: 'high' + state: present + + - name: smtpd_tls_mandatory_exclude_ciphers + value: 'aNULL' + state: present + + - name: smtpd_tls_received_header + value: 'yes' + state: present + + - name: smtpd_tls_security_level + value: 'may' + state: present + + - name: smtpd_tls_session_cache_database + value: 'btree:${data_directory}/smtpd_scache' + state: present + + - name: strict_rfc821_envelopes + value: 'yes' + state: present + + - name: tls_high_cipherlist + value: 'EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA256:EECDH:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!IDEA:!ECDSA:kEDH:CAMELLIA128-SHA:AES128-SHA' + state: present + + - name: tls_ssl_options + value: 'NO_COMPRESSION' + state: present + + - name: unknown_address_reject_code + value: '554' + state: present + + - name: unknown_client_reject_code + value: '554' + state: present + + - name: unknown_hostname_reject_code + value: '554' + state: present + + - name: virtual_alias_maps + value: 'hash:/usr/local/etc/postfix/virtual_aliases' + state: present + + - name: virtual_mailbox_domains + value: 'lists.ccchb.de' + state: present + + - name: virtual_transport + value: 'lmtp:unix:$queue_directory/private/dovecot-lmtp' + state: present + +postfix_services: + - name: smtp + type: inet + value: "smtp inet n - n - 1 postscreen" + + - name: smtpd + type: pass + value: "smtpd pass - - n - - smtpd" + + - name: submission + type: inet + value: "submission inet n - n - - smtpd" + + - name: dnsblog + type: unix + value: "dnsblog unix - - n - 0 dnsblog" + + - name: tlsproxy + type: unix + value: "tlsproxy unix - - n - 0 tlsproxy" + +postfix_params: + - name: submission/inet/syslog_name + value: 'postfix/submission' + state: present + + - name: submission/inet/smtpd_tls_security_level + value: 'encrypt' + state: present + + - name: submission/inet/tls_preempt_cipherlist + value: 'yes' + state: present + + - name: submission/inet/smtpd_sasl_auth_enable + value: 'yes' + state: present + + - name: submission/inet/smtpd_tls_auth_only + value: 'yes' + state: present + + - name: submission/inet/smtpd_reject_unlisted_recipient + value: 'no' + state: present + + - name: submission/inet/smtpd_client_restrictions + value: '$mua_client_restrictions' + state: present + + - name: submission/inet/smtpd_helo_restrictions + value: '$mua_helo_restrictions' + state: present + + - name: submission/inet/smtpd_sender_restrictions + value: '$mua_sender_restrictions' + state: present + + - name: submission/inet/smtpd_recipient_restrictions + value: '' + state: present + + - name: submission/inet/smtpd_relay_restrictions + value: 'permit_sasl_authenticated,reject' + state: present + + - name: submission/inet/milter_macro_daemon_name + value: ORIGINATING + state: present diff --git a/site.yml b/site.yml index e3c74d1..604de38 100644 --- a/site.yml +++ b/site.yml @@ -2,3 +2,4 @@ - import_playbook: s6.yml - import_playbook: haproxy.yml - import_playbook: bhyve.yml +- import_playbook: mail.yml