simplificando config

This commit is contained in:
Mauro Torrez 2019-08-25 19:15:29 -03:00
parent 16c2f29f06
commit 8cd5818318
5 changed files with 242 additions and 155 deletions

View File

@ -22,6 +22,7 @@ import re
from ansible.plugins.action import ActionBase from ansible.plugins.action import ActionBase
from ansible.utils.vars import merge_hash from ansible.utils.vars import merge_hash
from ansible.module_utils._text import to_text from ansible.module_utils._text import to_text
from six import string_types
class PfWorkflowError(Exception): class PfWorkflowError(Exception):
pass pass
@ -29,7 +30,7 @@ class PfWorkflowError(Exception):
class ActionModule(ActionBase): class ActionModule(ActionBase):
def getarg(self, key, default=True): def getarg(self, key, default=True):
if isinstance(default, basestring): if isinstance(default, string_types):
if key == 'parameter': if key == 'parameter':
return self._task.args.get(key, default) return self._task.args.get(key, default)
return '{}'.format(self._task.args.get(key, default)) return '{}'.format(self._task.args.get(key, default))
@ -234,7 +235,7 @@ class ActionModule(ActionBase):
''' '''
# value should be string # value should be string
if not isinstance(value, basestring): if not isinstance(value, string_types):
try: try:
value = ', '.join(value) value = ', '.join(value)
except TypeError: except TypeError:
@ -341,7 +342,7 @@ class ActionModule(ActionBase):
state = self.getarg('state') state = self.getarg('state')
if parameter: if parameter:
# build (parameter, value) pairs for iteration # build (parameter, value) pairs for iteration
if isinstance(parameter, basestring): if isinstance(parameter, string_types):
pv = [ (parameter, self.getarg('value')) ] pv = [ (parameter, self.getarg('value')) ]
elif isinstance(parameter, dict): elif isinstance(parameter, dict):
# if dict ignore new_value # if dict ignore new_value

View File

@ -1,10 +1,6 @@
--- ---
# directorio con reglas
# Postfix config directory (changing this is probably a bad idea) postfix_rules_dir: /etc/postfix/rules
postfix_config_dir: "/etc/postfix"
# Where to save access lists
postfix_rules_dir: "{{ postfix_config_dir }}/rules"
# accepted email domains # accepted email domains
postfix_mail_domains: "{{ mail_domains | default(['example.com']) }}" postfix_mail_domains: "{{ mail_domains | default(['example.com']) }}"
@ -13,7 +9,7 @@ postfix_mail_domains: "{{ mail_domains | default(['example.com']) }}"
postfix_server_domain: "{{ postfix_mail_domains | first }}" postfix_server_domain: "{{ postfix_mail_domains | first }}"
# postfix server identification # postfix server identification
postfix_server_name: "mail.{{ postfix_server_domain }}" postfix_server_name: mail.{{ postfix_server_domain }}
# domains considered as "local" unix domains (local server users) # domains considered as "local" unix domains (local server users)
# ansible_fqdn, localhost.localdomain, and localhost are always added regardless of this value # ansible_fqdn, localhost.localdomain, and localhost are always added regardless of this value
@ -29,14 +25,14 @@ postfix_domain_config: {}
# LDAP ------------------------------------------------------------------------ # LDAP ------------------------------------------------------------------------
# Default LDAP connection parameters # Default LDAP connection parameters
postfix_ldap_server: "localhost" postfix_ldap_server: "{{ ldap_server | default('localhost') }}"
postfix_ldap_port: 389 postfix_ldap_port: "{{ ldap_port | default(389) }}"
postfix_ldap_version: 3 postfix_ldap_version: "{{ ldap_version | default(3) }}"
postfix_ldap_scope: "sub" postfix_ldap_scope: "{{ ldap_search_scope | default('sub') }}"
postfix_ldap_bind: no postfix_ldap_bind: "{{ ldap_bind | default(False) }}"
postfix_ldap_bind_dn: '' postfix_ldap_bind_dn: "{{ ldap_bind_dn | default('') }}"
postfix_ldap_bind_pw: '' postfix_ldap_bind_pw: "{{ ldap_bind_password | default('') }}"
postfix_ldap_start_tls: no postfix_ldap_start_tls: "{{ ldap_starttls | default(False) }}"
postfix_ldap_tls_ca_cert_dir: '' postfix_ldap_tls_ca_cert_dir: ''
postfix_ldap_tls_ca_cert_file: '' postfix_ldap_tls_ca_cert_file: ''
postfix_ldap_use_group_alias: yes postfix_ldap_use_group_alias: yes

17
files/11-postfix.conf Normal file
View File

@ -0,0 +1,17 @@
# LMTP delivery service for Postfix
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0600
group = postfix
user = postfix
}
}
# Authentication service for Postfix
service auth {
unix_listener /var/spool/postfix/private/auth {
mode = 0660
user = postfix
group = postfix
}
}

59
tasks/lookup_tables.yml Normal file
View File

@ -0,0 +1,59 @@
---
- name: Template LDAP lookup tables
template:
src: ldap_table.cf.j2
dest: /etc/postfix/{{ domain }}_ldap_{{ item }}.cf"
when:
- postfix_domain_config[domain][item+'_lookup'].provider|default(postfix_lookup_provider) == 'ldap'
loop:
- user
- alias
- group
notify: reload postfix
- name: Template SQLite lookup tables
template:
src: sqlite_table.cf.j2
dest: /etc/postfix/{{ domain }}_sqlite_{{ item }}.cf
when:
- postfix_domain_config[domain][item+'_lookup'].provider|default(postfix_lookup_provider) == 'sqlite'
loop:
- user
- alias
notify: reload postfix
- name: Template file user lookup table
blockinfile:
block: |
{% for item in postfix_domain_config[domain]['users']|default([]) -%}
{% if item is string %}{{ item }} /nomailbox/{{ item }}
{% else %}{{ item.user }} {{ item.mailbox }}
{% endif %}{% endfor %}
dest: "{{ postfix_domain_config[domain].user_lookup.file|default(vmail_home+'/'+domain+'_users') }}"
marker: "# {mark} ANSIBLE-MANAGED USERS"
create: yes
when:
- postfix_domain_config[domain].user_lookup.provider|default(postfix_lookup_provider) == 'file'
notify: postmap hash users
- name: Template file alias lookup table
blockinfile:
block: |
{% for key in postfix_domain_config[domain]['aliases']|default([]) -%}
{{ key.alias }} {{ key.dest }}
{% endfor %}
dest: "{{ postfix_domain_config[domain].user_lookup.file|default(vmail_home+'/'+domain+'_aliases') }}"
marker: "# {mark} ANSIBLE-MANAGED ALIASES"
create: yes
when:
- postfix_domain_config[domain].alias_lookup.provider|default(postfix_lookup_provider) == 'file'
notify: postmap hash aliases
- name: Template no-reply aliases file
copy:
content: |
{% for address in postfix_domain_config[domain].noreply_aliases|default(['noreply']) %}
{{ address }}@domain _dev_null
{% endfor %}
dest: "{{ postfix_domain_config[domain].noreply_file|default(vmail_home+'/'+domain+'_noreply') }}"
notify: postmap no reply aliases

View File

@ -1,123 +1,118 @@
--- ---
- name: "Load default config for domains" # - name: "Load default config for domains"
set_fact: # set_fact:
dc: "{{ dc|default({})|combine( { item: { # dc: "{{ dc|default({})|combine( { item: {
'user_lookup': { # 'user_lookup': {
'provider': 'file', # 'provider': 'file',
'file': vmail_home +'/'+item+'_users', # 'file': vmail_home +'/'+item+'_users',
'domain': item, # 'domain': item,
'server_host': postfix_ldap_server, # 'server_host': postfix_ldap_server,
'server_port': postfix_ldap_port, # 'server_port': postfix_ldap_port,
'version': postfix_ldap_version, # 'version': postfix_ldap_version,
'scope': postfix_ldap_scope, # 'scope': postfix_ldap_scope,
'bind': postfix_ldap_bind, # 'bind': postfix_ldap_bind,
'bind_dn': postfix_ldap_bind_dn, # 'bind_dn': postfix_ldap_bind_dn,
'bind_pw': postfix_ldap_bind_pw, # 'bind_pw': postfix_ldap_bind_pw,
'start_tls': postfix_ldap_start_tls, # 'start_tls': postfix_ldap_start_tls,
'tls_ca_cert_file': postfix_ldap_tls_ca_cert_file, # 'tls_ca_cert_file': postfix_ldap_tls_ca_cert_file,
'tls_ca_cert_dir': postfix_ldap_tls_ca_cert_dir, # 'tls_ca_cert_dir': postfix_ldap_tls_ca_cert_dir,
'search_base': # 'search_base':
'ou=People,'+item.split('.')|map('regex_replace','^','dc=')|join(','), # 'ou=People,'+item.split('.')|map('regex_replace','^','dc=')|join(','),
'query_filter': '(&(objectClass=inetOrgPerson)(uid=%u))', # 'query_filter': '(&(objectClass=inetOrgPerson)(uid=%u))',
'result_attribute': 'uid', # 'result_attribute': 'uid',
'result_format': vmail_home+'/mail/'+item+'/%s/', # 'result_format': vmail_home+'/mail/'+item+'/%s/',
'dbpath': vmail_home+'/'+item+'_users.sqlite', # 'dbpath': vmail_home+'/'+item+'_users.sqlite',
'query': postfix_sqlite_user_query # 'query': postfix_sqlite_user_query
}, # },
'users': [], # 'users': [],
'alias_lookup': { # 'alias_lookup': {
'provider': 'file', # 'provider': 'file',
'file': vmail_home +'/'+item+'_aliases', # 'file': vmail_home +'/'+item+'_aliases',
'domain': item, # 'domain': item,
'server_host': postfix_ldap_server, # 'server_host': postfix_ldap_server,
'server_port': postfix_ldap_port, # 'server_port': postfix_ldap_port,
'version': postfix_ldap_version, # 'version': postfix_ldap_version,
'scope': postfix_ldap_scope, # 'scope': postfix_ldap_scope,
'bind': postfix_ldap_bind, # 'bind': postfix_ldap_bind,
'bind_dn': postfix_ldap_bind_dn, # 'bind_dn': postfix_ldap_bind_dn,
'bind_pw': postfix_ldap_bind_pw, # 'bind_pw': postfix_ldap_bind_pw,
'start_tls': postfix_ldap_start_tls, # 'start_tls': postfix_ldap_start_tls,
'tls_ca_cert_file': postfix_ldap_tls_ca_cert_file, # 'tls_ca_cert_file': postfix_ldap_tls_ca_cert_file,
'tls_ca_cert_dir': postfix_ldap_tls_ca_cert_dir, # 'tls_ca_cert_dir': postfix_ldap_tls_ca_cert_dir,
'search_base': # 'search_base':
'ou=Alias,'+item.split('.')|map('regex_replace','^','dc=')|join(','), # 'ou=Alias,'+item.split('.')|map('regex_replace','^','dc=')|join(','),
'query_filter': '(&(objectClass=nisMailAlias)(cn=%u))', # 'query_filter': '(&(objectClass=nisMailAlias)(cn=%u))',
'result_attribute': 'rfc822MailMember', # 'result_attribute': 'rfc822MailMember',
'result_format': '%s', # 'result_format': '%s',
'dbpath': vmail_home+'/'+item+'_aliases.sqlite', # 'dbpath': vmail_home+'/'+item+'_aliases.sqlite',
'query': postfix_sqlite_alias_query # 'query': postfix_sqlite_alias_query
}, # },
'aliases': [], # 'aliases': [],
'use_group_as_alias': postfix_ldap_use_group_alias, # 'use_group_as_alias': postfix_ldap_use_group_alias,
'group_lookup': { # 'group_lookup': {
'provider': 'ldap', # 'provider': 'ldap',
'domain': item, # 'domain': item,
'server_host': postfix_ldap_server, # 'server_host': postfix_ldap_server,
'server_port': postfix_ldap_port, # 'server_port': postfix_ldap_port,
'version': postfix_ldap_version, # 'version': postfix_ldap_version,
'scope': postfix_ldap_scope, # 'scope': postfix_ldap_scope,
'bind': postfix_ldap_bind, # 'bind': postfix_ldap_bind,
'bind_dn': postfix_ldap_bind_dn, # 'bind_dn': postfix_ldap_bind_dn,
'bind_pw': postfix_ldap_bind_pw, # 'bind_pw': postfix_ldap_bind_pw,
'start_tls': postfix_ldap_start_tls, # 'start_tls': postfix_ldap_start_tls,
'tls_ca_cert_file': postfix_ldap_tls_ca_cert_file, # 'tls_ca_cert_file': postfix_ldap_tls_ca_cert_file,
'tls_ca_cert_dir': postfix_ldap_tls_ca_cert_dir, # 'tls_ca_cert_dir': postfix_ldap_tls_ca_cert_dir,
'search_base': # 'search_base':
'ou=Group,'+item.split('.')|map('regex_replace','^','dc=')|join(','), # 'ou=Group,'+item.split('.')|map('regex_replace','^','dc=')|join(','),
'query_filter': '(&(objectClass=posixGroup)(cn=%u))', # 'query_filter': '(&(objectClass=posixGroup)(cn=%u))',
'result_attribute': 'memberUid', # 'result_attribute': 'memberUid',
'result_format': '%s@{{d}}', # 'result_format': '%s@{{d}}',
}, # },
'noreply_aliases': [ 'noreply' ], # 'noreply_aliases': [ 'noreply' ],
'noreply_file': vmail_home +'/'+item+'_noreply', # 'noreply_file': vmail_home +'/'+item+'_noreply',
} }, recursive=True) }}" # } }, recursive=True) }}"
with_items: "{{ postfix_mail_domains|belist }}" # with_items: "{{ postfix_mail_domains }}"
- name: "Override config for domains" # - name: "Override config for domains"
set_fact: # set_fact:
dc: '{{ dc | combine(postfix_domain_config, recursive=True) }}' # dc: '{{ dc | combine(postfix_domain_config, recursive=True) }}'
- apt: name=postfix update_cache=yes - name: Instalar Postfix
- apt: name=postfix-pcre apt:
name:
- postfix
- postfix-pcre
- postfix-ldap
- postfix-sqlite
state: present
notify: restart postfix notify: restart postfix
- apt: name=postfix-ldap - name: Servicio delivery+auth mediante Dovecot
when: copy:
# see http://jmespath.org/ src: 11-postfix.conf
- '"ldap" in dc|json_query("*.[ alias_lookup, user_lookup ][].provider")'
notify: restart postfix
- apt: name=postfix-sqlite
when:
# see http://jmespath.org/
- '"sqlite" in dc|json_query("*.[ alias_lookup, user_lookup ][].provider")'
notify: restart postfix
- name: "Template Dovecot delivery/auth service config for Postfix"
template:
src: 11-postfix.conf.j2
dest: /etc/dovecot/conf.d/11-postfix.conf dest: /etc/dovecot/conf.d/11-postfix.conf
notify: restart dovecot notify: restart dovecot
- name: "Configure lookup tables" - name: Configurar lookup tables
include_tasks: lookup_tables.yml include_tasks: lookup_tables.yml
with_items: "{{postfix_mail_domains|belist}}" loop: "{{ postfix_mail_domains }}"
loop_control: loop_control:
loop_var: "domain" loop_var: domain
- name: "Configure no-reply local mail alias" - name: Alias local para usuario no-reply
blockinfile: blockinfile:
block: | block: |
_dev_null: /dev/null _dev_null: /dev/null
marker: "# {mark} ANSIBLE-MANAGED ALIASES" marker: "# {mark} ANSIBLE-MANAGED ALIASES"
path: "/etc/aliases" path: /etc/aliases
notify: newaliases notify: newaliases
- name: "Create rules directory for access lists" - name: Directorio de reglas para access lists
file: file:
name: "{{ postfix_rules_dir }}" name: "{{ postfix_rules_dir }}"
state: directory state: directory
- name: "Template client access list" - name: Template client access list
blockinfile: blockinfile:
path: "{{ postfix_rules_dir }}/client_access_list" path: "{{ postfix_rules_dir }}/client_access_list"
create: yes create: yes
@ -127,7 +122,7 @@
{{ entry.regex }} {{ entry.action }} {{ entry.regex }} {{ entry.action }}
{% endfor %} {% endfor %}
- name: "Template helo access list" - name: Template helo access list
blockinfile: blockinfile:
path: "{{ postfix_rules_dir }}/helo_access_list" path: "{{ postfix_rules_dir }}/helo_access_list"
create: yes create: yes
@ -138,7 +133,7 @@
{% endfor %} {% endfor %}
notify: postmap access lists notify: postmap access lists
- name: "Template recipient access list" - name: Template recipient access list
blockinfile: blockinfile:
path: "{{ postfix_rules_dir }}/recipient_access_list" path: "{{ postfix_rules_dir }}/recipient_access_list"
create: yes create: yes
@ -149,7 +144,7 @@
{% endfor %} {% endfor %}
notify: postmap access lists notify: postmap access lists
- name: "Template sender access list" - name: Template sender access list
blockinfile: blockinfile:
path: "{{ postfix_rules_dir }}/sender_access_list" path: "{{ postfix_rules_dir }}/sender_access_list"
create: yes create: yes
@ -160,61 +155,80 @@
{% endfor %} {% endfor %}
notify: postmap access lists notify: postmap access lists
- name: "Set main.cf parameters" - name: Configurar main.cf
postconf: postconf:
parameter: parameter:
mydestination: >- mydestination: >-
{{ postfix_unix_domains | belist | {{ postfix_unix_domains |
union( [ ansible_fqdn, 'localhost.localdomain', 'localhost'] ) | union( [ ansible_fqdn, 'localhost.localdomain', 'localhost'] ) |
difference( postfix_mail_domains|belist ) }} difference( postfix_mail_domains ) }}
myhostname: "{{ postfix_server_name }}" myhostname:
mydomain: "{{ postfix_server_domain }}" "{{ postfix_server_name }}"
mydomain:
"{{ postfix_server_domain }}"
mynetworks: >- mynetworks: >-
{{ ['127.0.0.0/8', '[::ffff:127.0.0.0]/104', '[::1]/128'] | {{ ['127.0.0.0/8', '[::ffff:127.0.0.0]/104', '[::1]/128'] |
union( postfix_local_networks ) }} union( postfix_local_networks ) }}
virtual_alias_maps: >- virtual_alias_maps: >-
{% for d in postfix_mail_domains|belist %} {% for d in postfix_mail_domains %}
{% set p = dc[d]['alias_lookup']['provider'] %} {% set p = postfix_domain_config[d].alias_lookup.provider|default(postfix_lookup_provider) %}
{% if p == "ldap" %} {% if p == "ldap" %}
ldap:{{ postfix_config_dir }}/{{d}}_ldap_alias.cf ldap:/etc/postfix/{{ d }}_ldap_alias.cf
{% if dc[d]['use_group_as_alias'] %}, {% if postfix_domain_config[d].alias_lookup.use_group_as_alias|default(postfix_ldap_use_group_alias) %},
ldap:{{ postfix_config_dir }}/{{d}}_ldap_group.cf ldap:/etc/postfix/{{ d }}_ldap_group.cf
{% endif %} {% endif %}
{% elif p == "sqlite" %} {% elif p == "sqlite" %}
sqlite:{{ postfix_config_dir }}/{{d}}_sqlite_alias.cf sqlite:/etc/postfix/{{d}}_sqlite_alias.cf
{% elif p == "file" %} {% elif p == "file" %}
hash:{{ vmail_home }}/{{d}}_aliases hash:{{ vmail_home }}/{{ d }}_aliases
{% endif %}{{ '' if loop.last else ',' }}{% endfor %}, {% endif %}{{ '' if loop.last else ',' }}{% endfor %},
hash:{{ postfix_config_dir }}/noreply_aliases hash:/etc/postfix/noreply_aliases
virtual_mailbox_maps: >- virtual_mailbox_maps: >-
{% for d in postfix_mail_domains|belist %} {% for d in postfix_mail_domains %}
{% set p = dc[d]['user_lookup']['provider'] %} {% set p = postfix_domain_config[d].user_lookup.provider|default(postfix_lookup_provider) %}
{% if p == "ldap" %} {% if p == "ldap" %}
ldap:{{ postfix_config_dir }}/{{d}}_ldap_user.cf ldap:/etc/postfix/{{ d }}_ldap_user.cf
{% elif p == "sqlite" %} {% elif p == "sqlite" %}
sqlite:{{ postfix_config_dir }}/{{d}}_sqlite_user.cf sqlite:/etc/postfix/{{ d }}_sqlite_user.cf
{% elif p == "file" %} {% elif p == "file" %}
hash:{{ vmail_home }}/{{d}}_users hash:{{ vmail_home }}/{{ d }}_users
{% endif %}{{ '' if loop.last else ',' }}{% endfor %}, {% endif %}{{ '' if loop.last else ',' }}{% endfor %},
virtual_transport: "lmtp:unix:private/dovecot-lmtp" virtual_transport:
virtual_mailbox_domains: "{{ postfix_mail_domains }}" lmtp:unix:private/dovecot-lmtp
virtual_mailbox_domains:
"{{ postfix_mail_domains }}"
smtpd_sasl_path: private/auth smtpd_sasl_path: private/auth
smtpd_sasl_type: dovecot smtpd_sasl_type: dovecot
smtpd_sasl_auth_enable: "{{ 'yes' if postfix_enable_smtpd_auth else 'no' }}" smtpd_sasl_auth_enable:
smtpd_tls_cert_file: "{{ postfix_tls_certificate }}" "{{ 'yes' if postfix_enable_smtpd_auth else 'no' }}"
smtpd_tls_key_file: "{{ postfix_tls_private_key }}" smtpd_tls_cert_file:
smtp_tls_security_level: "{{postfix_incoming_tls_security}}" "{{ postfix_tls_certificate }}"
smtpd_tls_security_level: "{{postfix_outgoing_tls_security}}" smtpd_tls_key_file:
smtpd_tls_auth_only: "{{ 'yes' if postfix_allow_insecure_auth else 'no'}}" "{{ postfix_tls_private_key }}"
smtpd_tls_session_cache_database: "{{ 'btree:${data_directory}/smtpd_scache' if postfix_tls_session_cache else '' }}" smtp_tls_security_level:
smtpd_client_restrictions: "{{ postfix_client_restrictions }}" "{{postfix_incoming_tls_security}}"
smtpd_data_restrictions: "{{ postfix_data_restrictions }}" smtpd_tls_security_level:
smtpd_helo_restrictions: "{{ postfix_helo_restrictions }}" "{{postfix_outgoing_tls_security}}"
smtpd_relay_restrictions: "{{ postfix_relay_restrictions }}" smtpd_tls_auth_only:
smtpd_recipient_restrictions: "{{ postfix_recipient_restrictions }}" "{{ 'yes' if postfix_allow_insecure_auth else 'no'}}"
message_size_limit: "{{ postfix_message_size_limit }}" smtpd_tls_session_cache_database:
smtpd_helo_required: "{{ 'yes' if postfix_helo_required else 'no' }}" "{{ 'btree:${data_directory}/smtpd_scache' if postfix_tls_session_cache else '' }}"
biff: "{{ 'yes' if postfix_biff else 'no' }}" smtpd_client_restrictions:
"{{ postfix_client_restrictions }}"
smtpd_data_restrictions:
"{{ postfix_data_restrictions }}"
smtpd_helo_restrictions:
"{{ postfix_helo_restrictions }}"
smtpd_relay_restrictions:
"{{ postfix_relay_restrictions }}"
smtpd_recipient_restrictions:
"{{ postfix_recipient_restrictions }}"
message_size_limit:
"{{ postfix_message_size_limit }}"
smtpd_helo_required:
"{{ 'yes' if postfix_helo_required else 'no' }}"
biff:
"{{ 'yes' if postfix_biff else 'no' }}"
notify: reload postfix notify: reload postfix
- name: "Enable submission service" - name: "Enable submission service"