From 6be613d07ddc6d0b1e4b73f93c0fa1c0b1f7ba10 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Sun, 24 Nov 2013 03:53:39 +0100 Subject: Postfix master (nullmailer) configuration We use a dedicated instance for each role: MDA, MTA out, MX, etc. --- roles/common/files/etc/postfix/generic.pcre | 1 + roles/common/files/etc/postfix/master.cf | 35 +++++++++++++++ roles/common/handlers/main.yml | 7 +++ roles/common/tasks/ipsec.yml | 5 +-- roles/common/tasks/mail.yml | 62 +++++++++++++++++++++++++++ roles/common/tasks/main.yml | 1 + roles/common/templates/etc/postfix/main.cf.j2 | 57 ++++++++++++++++++++++++ 7 files changed, 164 insertions(+), 4 deletions(-) create mode 100644 roles/common/files/etc/postfix/generic.pcre create mode 100644 roles/common/files/etc/postfix/master.cf create mode 100644 roles/common/tasks/mail.yml create mode 100644 roles/common/templates/etc/postfix/main.cf.j2 (limited to 'roles') diff --git a/roles/common/files/etc/postfix/generic.pcre b/roles/common/files/etc/postfix/generic.pcre new file mode 100644 index 0000000..c46f4b5 --- /dev/null +++ b/roles/common/files/etc/postfix/generic.pcre @@ -0,0 +1 @@ +/^(.+)@([^@.]+)\.[^@]+$/ admin+${1}=${2}@fripost.org diff --git a/roles/common/files/etc/postfix/master.cf b/roles/common/files/etc/postfix/master.cf new file mode 100644 index 0000000..dd49d31 --- /dev/null +++ b/roles/common/files/etc/postfix/master.cf @@ -0,0 +1,35 @@ +# +# Postfix master process configuration file. For details on the format +# of the file, see the master(5) manual page (command: "man 5 master"). +# +# Do not forget to execute "postfix reload" after editing this file. +# +# ========================================================================== +# service type private unpriv chroot wakeup maxproc command + args +# (yes) (yes) (yes) (never) (100) +# ========================================================================== +smtp inet n - - - - smtpd +pickup fifo n - - 60 1 pickup +cleanup unix n - - - 0 cleanup +qmgr fifo n - n 300 1 qmgr +tlsmgr unix - - - 1000? 1 tlsmgr +rewrite unix - - - - - trivial-rewrite +bounce unix - - - - 0 bounce +defer unix - - - - 0 bounce +trace unix - - - - 0 bounce +verify unix - - - - 1 verify +flush unix n - - 1000? 0 flush +proxymap unix - - n - - proxymap +proxywrite unix - - n - 1 proxymap +smtp unix - - - - - smtp +relay unix - - - - - smtp +# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 +showq unix n - - - - showq +error unix - - - - - error +retry unix - - - - - error +discard unix - - - - - discard +local unix - n n - - local +virtual unix - n n - - virtual +lmtp unix - - - - - lmtp +anvil unix - - - - 1 anvil +scache unix - - - - 1 scache diff --git a/roles/common/handlers/main.yml b/roles/common/handlers/main.yml index 56b37e7..54643ed 100644 --- a/roles/common/handlers/main.yml +++ b/roles/common/handlers/main.yml @@ -28,3 +28,10 @@ # it should be "up" whenever ansible has access to the machine, we use # pattern=init as a dummy assumption. service: name=networking pattern=init state=reloaded + +# TODO: should be in a separate file, since it's used by other roles +- name: Restart Postfix + service: name=postfix state=restarted + +- name: Reload Postfix + service: name=postfix state=reloaded diff --git a/roles/common/tasks/ipsec.yml b/roles/common/tasks/ipsec.yml index 619c093..56c8300 100644 --- a/roles/common/tasks/ipsec.yml +++ b/roles/common/tasks/ipsec.yml @@ -52,11 +52,8 @@ notify: - Reload networking -# XXX: As of 1.3.1 ansible doesn't accept relative src. -# See https://github.com/ansible/ansible/issues/4459 - name: Auto-deactivate the dedicated interface for IPSec - file: #src=../if-up.d/ipsec - src=/etc/network/if-up.d/ipsec + file: src=../if-up.d/ipsec dest=/etc/network/if-down.d/ipsec owner=root group=root state=link diff --git a/roles/common/tasks/mail.yml b/roles/common/tasks/mail.yml new file mode 100644 index 0000000..9de0eaa --- /dev/null +++ b/roles/common/tasks/mail.yml @@ -0,0 +1,62 @@ +- name: Install Postfix + apt: pkg={{ item }} + with_items: + # That one is nicer than GNU mailutils' mailx(1) + - heirloom-mailx + - postfix + - postfix-cdb + - postfix-pcre + +- name: Create Postfix instances + postmulti: instance={{ postfix_instance[item].name }} + group={{ postfix_instance[item].group | default('') }} + register: r1 + with_items: postfix_instance.keys() | intersect(group_names) | list + notify: + - Restart Postfix + +- name: Define dynamic maps for children instances + # main.cf and master.cf are configured in dedicated roles, though + file: src=../postfix/dynamicmaps.cf + dest=/etc/postfix-{{ postfix_instance[item].name }}/dynamicmaps.cf + owner=root group=root state=link + register: r2 + with_items: postfix_instance.keys() | intersect(group_names) | list + notify: + - Restart Postfix + +- name: Configure Postfix (1) + copy: src=etc/postfix/{{ item }} + dest=/etc/postfix/{{ item }} + owner=root group=root + mode=0644 + register: r3 + with_items: + - master.cf + - generic.pcre + notify: + - Reload Postfix + +- name: Configure Postfix (2) + template: src=etc/postfix/main.cf.j2 + dest=/etc/postfix/main.cf + owner=root group=root + mode=0644 + register: r4 + notify: + - Restart Postfix + +- name: Update the static local Postfix database + postmap: cmd=postalias src=/etc/aliases db=cdb + owner=root group=root + mode=0644 + +# We're using CDB +- name: Delete /etc/aliases.db + file: path=/etc/aliases.db state=absent + +- name: Start Postfix + service: name=postfix state=started + when: not (r1.changed or r2.changed or r3.changed or r4.changed) + +- meta: flush_handlers diff --git a/roles/common/tasks/main.yml b/roles/common/tasks/main.yml index 3ee4f49..355b2df 100644 --- a/roles/common/tasks/main.yml +++ b/roles/common/tasks/main.yml @@ -8,3 +8,4 @@ - include: fail2ban.yml tags=fail2ban - include: ipsec.yml tags=strongswan,ipsec - include: logging.yml tags=logging +- include: mail.yml tags=mail,postfix diff --git a/roles/common/templates/etc/postfix/main.cf.j2 b/roles/common/templates/etc/postfix/main.cf.j2 new file mode 100644 index 0000000..3169ac6 --- /dev/null +++ b/roles/common/templates/etc/postfix/main.cf.j2 @@ -0,0 +1,57 @@ +######################################################################## +# Nullmailer configuration + +smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU) +biff = no +readme_directory = no + +myorigin = /etc/mailname +myhostname = {{ ansible_fqdn }} +mydomain = {{ ansible_domain }} +append_dot_mydomain = no + +# This server is for internal use only +mynetworks_style = host +inet_interfaces = loopback-only +inet_protocols = ipv4 +# Tunnel everything through IPSec +smtp_bind_address = 172.16.0.1 + +# No local delivery +mydestination = +local_transport = error:5.1.1 Mailbox unavailable +alias_maps = +local_recipient_maps = + +# All aliases are virtual +default_database_type = cdb +virtual_alias_maps = cdb:/etc/aliases +alias_database = $virtual_alias_maps + +# Transform local FQDN addresses to addresses routable on the internet +smtp_generic_maps = pcre:$config_directory/generic.pcre + +# Forward everything to our internal mailhub +{% if 'MTA-out' in group_names %} +relayhost = [127.0.0.1]:2525 +{% else %} +relayhost = [outgoing.fripost.org]:2525 +{% endif %} + +# This server is for internal use only; external connections are +# protected by IPSec already +smtpd_tls_security_level = none +smtp_tls_security_level = none + +{% set multi_instance = False %} +{%- for g in postfix_instance.keys() | sort -%} + {%- if g in group_names -%} + {%- if not multi_instance -%} + {%- set multi_instance = True -%} +## Other postfix instances +multi_instance_wrapper = $command_directory/postmulti -p -- +multi_instance_enable = yes +multi_instance_directories = + {%- endif %} /etc/postfix-{{ postfix_instance[g].name }} + {%- endif %} +{% endfor %} -- cgit v1.2.3