summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem@fripost.org>2015-05-30 13:23:19 +0200
committerGuilhem Moulin <guilhem@fripost.org>2015-06-07 02:53:53 +0200
commitfa82a617a0c50b7478cd2b7189aa5f7d14449954 (patch)
tree62488ddf805f34b3f06807a83d6f94a360ece723
parent64e8603cf9790aa4419d0f2746671bd242e6344d (diff)
Upgrade the MX configuration from Wheezy to Jessie.
In particular, since Postfix is now able to perform LDAP lookups using SASL, previous hacks with simble binds on cn=postfix,ou=services,… can now be removed.
-rw-r--r--roles/MX/files/etc/postfix/virtual/alias.cf5
-rw-r--r--roles/MX/files/etc/postfix/virtual/alias_domains.cf5
-rw-r--r--roles/MX/files/etc/postfix/virtual/catchall.cf5
-rw-r--r--roles/MX/files/etc/postfix/virtual/domains.cf5
-rw-r--r--roles/MX/files/etc/postfix/virtual/list.cf5
-rw-r--r--roles/MX/files/etc/postfix/virtual/mailbox.cf5
-rwxr-xr-xroles/MX/files/usr/local/bin/reserved-alias.pl (renamed from roles/MX/files/usr/local/sbin/reserved-alias.pl)0
-rw-r--r--roles/MX/tasks/main.yml18
-rw-r--r--roles/MX/templates/etc/postfix/main.cf.j219
-rw-r--r--roles/common-LDAP/templates/etc/ldap/database.ldif.j258
-rw-r--r--roles/common/files/etc/postfix/master.cf2
11 files changed, 63 insertions, 64 deletions
diff --git a/roles/MX/files/etc/postfix/virtual/alias.cf b/roles/MX/files/etc/postfix/virtual/alias.cf
index 1710376..1c104a9 100644
--- a/roles/MX/files/etc/postfix/virtual/alias.cf
+++ b/roles/MX/files/etc/postfix/virtual/alias.cf
@@ -1,10 +1,9 @@
server_host = ldapi://%2Fvar%2Fspool%2Fpostfix-mx%2Fprivate%2Fldapi/
version = 3
search_base = fvd=%d,ou=virtual,dc=fripost,dc=org
domain = static:all
scope = one
-bind = yes
-bind_dn = cn=postfix,ou=services,dc=fripost,dc=org
-bind_pw = FIXME
+bind = sasl
+sasl_mechs = EXTERNAL
query_filter = (&(objectClass=FripostVirtualAlias)(fvl=%u)(fripostIsStatusActive=TRUE))
result_attribute = fripostMaildrop
diff --git a/roles/MX/files/etc/postfix/virtual/alias_domains.cf b/roles/MX/files/etc/postfix/virtual/alias_domains.cf
index 119b8b2..907166f 100644
--- a/roles/MX/files/etc/postfix/virtual/alias_domains.cf
+++ b/roles/MX/files/etc/postfix/virtual/alias_domains.cf
@@ -1,12 +1,11 @@
server_host = ldapi://%2Fvar%2Fspool%2Fpostfix-mx%2Fprivate%2Fldapi/
version = 3
search_base = ou=virtual,dc=fripost,dc=org
domain = static:all
scope = one
-bind = yes
-bind_dn = cn=postfix,ou=services,dc=fripost,dc=org
-bind_pw = FIXME
+bind = sasl
+sasl_mechs = EXTERNAL
# The domain has already been validated (it's active and not pending)
query_filter = (&(objectClass=FripostVirtualAliasDomain)(fvd=%d))
result_attribute = fripostMaildrop
result_format = %U@%s
diff --git a/roles/MX/files/etc/postfix/virtual/catchall.cf b/roles/MX/files/etc/postfix/virtual/catchall.cf
index 66053c8..e0e6350 100644
--- a/roles/MX/files/etc/postfix/virtual/catchall.cf
+++ b/roles/MX/files/etc/postfix/virtual/catchall.cf
@@ -1,11 +1,10 @@
server_host = ldapi://%2Fvar%2Fspool%2Fpostfix-mx%2Fprivate%2Fldapi/
version = 3
search_base = ou=virtual,dc=fripost,dc=org
domain = static:all
scope = one
-bind = yes
-bind_dn = cn=postfix,ou=services,dc=fripost,dc=org
-bind_pw = FIXME
+bind = sasl
+sasl_mechs = EXTERNAL
# The domain has already been validated (it's active and not pending)
query_filter = (&(objectClass=FripostVirtualDomain)(!(objectClass=FripostVirtualAliasDomain))(fvd=%d)(fripostOptionalMaildrop=*))
result_attribute = fripostOptionalMaildrop
diff --git a/roles/MX/files/etc/postfix/virtual/domains.cf b/roles/MX/files/etc/postfix/virtual/domains.cf
index 4ec247d..f5a7f25 100644
--- a/roles/MX/files/etc/postfix/virtual/domains.cf
+++ b/roles/MX/files/etc/postfix/virtual/domains.cf
@@ -1,12 +1,11 @@
# XXX: How come we use a socked relative to the chroot here? smtpd(8) is
# not (can't be) chrooted...
server_host = ldapi://%2Fprivate%2Fldapi/
version = 3
search_base = ou=virtual,dc=fripost,dc=org
scope = one
-bind = yes
-bind_dn = cn=postfix,ou=services,dc=fripost,dc=org
-bind_pw = FIXME
+bind = sasl
+sasl_mechs = EXTERNAL
query_filter = (&(objectClass=FripostVirtualDomain)(!(objectClass=FripostPendingEntry))(fvd=%s)(fripostIsStatusActive=TRUE))
result_attribute = fvd
result_format = OK
diff --git a/roles/MX/files/etc/postfix/virtual/list.cf b/roles/MX/files/etc/postfix/virtual/list.cf
index 3b364c0..99e2147 100644
--- a/roles/MX/files/etc/postfix/virtual/list.cf
+++ b/roles/MX/files/etc/postfix/virtual/list.cf
@@ -1,13 +1,12 @@
server_host = ldapi://%2Fvar%2Fspool%2Fpostfix-mx%2Fprivate%2Fldapi/
version = 3
search_base = fvd=%d,ou=virtual,dc=fripost,dc=org
domain = static:all
scope = one
-bind = yes
-bind_dn = cn=postfix,ou=services,dc=fripost,dc=org
-bind_pw = FIXME
+bind = sasl
+sasl_mechs = EXTERNAL
query_filter = (&(objectClass=FripostVirtualList)(!(objectClass=FripostPendingEntry))(fvl=%u)(fripostIsStatusActive=TRUE))
result_attribute = fripostListManager
# Use a dedicated "virtual" domain to decongestion potential bottlenecks
# on trivial_rewrite(8) due to slow LDAP lookups in tranport_maps.
result_format = %D/%U@%s.fripost.org
diff --git a/roles/MX/files/etc/postfix/virtual/mailbox.cf b/roles/MX/files/etc/postfix/virtual/mailbox.cf
index 4654607..7289670 100644
--- a/roles/MX/files/etc/postfix/virtual/mailbox.cf
+++ b/roles/MX/files/etc/postfix/virtual/mailbox.cf
@@ -1,13 +1,12 @@
server_host = ldapi://%2Fvar%2Fspool%2Fpostfix-mx%2Fprivate%2Fldapi/
version = 3
search_base = fvd=%d,ou=virtual,dc=fripost,dc=org
domain = static:all
scope = one
-bind = yes
-bind_dn = cn=postfix,ou=services,dc=fripost,dc=org
-bind_pw = FIXME
+bind = sasl
+sasl_mechs = EXTERNAL
query_filter = (&(objectClass=FripostVirtualUser)(fvl=%u)(fripostIsStatusActive=TRUE))
result_attribute = fvl
# Use a dedicated "virtual" domain to decongestion potential bottlenecks
# on trivial_rewrite(8) due to slow LDAP lookups in tranport_maps.
result_format = %D/%U@mda.fripost.org
diff --git a/roles/MX/files/usr/local/sbin/reserved-alias.pl b/roles/MX/files/usr/local/bin/reserved-alias.pl
index e19492e..e19492e 100755
--- a/roles/MX/files/usr/local/sbin/reserved-alias.pl
+++ b/roles/MX/files/usr/local/bin/reserved-alias.pl
diff --git a/roles/MX/tasks/main.yml b/roles/MX/tasks/main.yml
index 361e379..3c96fad 100644
--- a/roles/MX/tasks/main.yml
+++ b/roles/MX/tasks/main.yml
@@ -6,60 +6,74 @@
- postfix-ldap
- postfix-cdb
# The following is for reserved-alias.pl
- libnet-ldap-perl
- libauthen-sasl-perl
- name: Configure Postfix
template: src=etc/postfix/main.cf.j2
dest=/etc/postfix-{{ postfix_instance[inst].name }}/main.cf
owner=root group=root
mode=0644
notify:
- Reload Postfix
- name: Create directory /etc/postfix-.../virtual
file: path=/etc/postfix-{{ postfix_instance[inst].name }}/virtual
state=directory
owner=root group=root
mode=0755
+# trivial-rewrite(8) runs in a chroot. We create an empty
+# /usr/lib/sasl2 to avoid "No such file or directory" warnings.
+# Cf. also #738989.
+- name: Create directory /usr/lib/sasl2
+ file: path=/var/spool/postfix-{{ postfix_instance[inst].name }}/{{ item }}
+ state=directory
+ owner=root group=root
+ mode=0755
+ with_items:
+ - /usr/lib/sasl2
+ - /usr/lib/{{ ansible_architecture }}-linux-gnu/sasl2
+ notify:
+ - Reload Postfix
+
- name: Copy lookup tables (1)
copy: src=etc/postfix/virtual/{{ item }}
dest=/etc/postfix-{{ postfix_instance[inst].name }}/virtual/{{ item }}
owner=root group=root
mode=0644
with_items:
- domains.cf
# no need to reload upon change, as cleanup(8) is short-running
- reserved_alias.pcre
- alias.cf
- mailbox.cf
- list.cf
- alias_domains.cf
- catchall.cf
- name: Copy lookup tables (2)
template: src=etc/postfix/virtual/transport.j2
dest=/etc/postfix-{{ postfix_instance[inst].name }}/virtual/transport
owner=root group=root
mode=0644
- name: Compile the Postfix transport maps
# trivial-rewrite(8) is a long-running process, so it's safer to reload
postmap: instance={{ postfix_instance[inst].name }}
src=/etc/postfix-{{ postfix_instance[inst].name }}/virtual/transport db=cdb
owner=root group=root
mode=0644
notify:
- Reload Postfix
- name: Copy reserved-alias.pl
- copy: src=usr/local/sbin/reserved-alias.pl
- dest=/usr/local/sbin/reserved-alias.pl
+ copy: src=usr/local/bin/reserved-alias.pl
+ dest=/usr/local/bin/reserved-alias.pl
owner=root group=root
mode=0755
- meta: flush_handlers
- name: Start Postfix
service: name=postfix state=started
diff --git a/roles/MX/templates/etc/postfix/main.cf.j2 b/roles/MX/templates/etc/postfix/main.cf.j2
index 09a5ce7..11c8199 100644
--- a/roles/MX/templates/etc/postfix/main.cf.j2
+++ b/roles/MX/templates/etc/postfix/main.cf.j2
@@ -52,62 +52,61 @@ relay_domains =
# Virtual transport
# We use a dedicated "virtual" domain to decongestion potential
# bottlenecks on trivial_rewrite(8) due to slow LDAP lookups in
# tranport_maps.
virtual_transport = error:5.1.1 Virtual transport unavailable
virtual_alias_domains = !cdb:$config_directory/virtual/transport
ldap:$config_directory/virtual/domains.cf
virtual_alias_maps = pcre:$config_directory/virtual/reserved_alias.pcre
# unless there is a matching user/alias/list...
ldap:$config_directory/virtual/mailbox.cf
ldap:$config_directory/virtual/alias.cf
ldap:$config_directory/virtual/list.cf
# ...we resolve alias domains and catch alls
ldap:$config_directory/virtual/alias_domains.cf
ldap:$config_directory/virtual/catchall.cf
transport_maps = cdb:$config_directory/virtual/transport
# Don't rewrite remote headers
-local_header_rewrite_clients =
+local_header_rewrite_clients =
# Pass the client information along to the content filter
-smtp_send_xforward_command = yes
+smtp_send_xforward_command = yes
# Avoid splitting the envelope and scanning messages multiple times
-smtp_destination_recipient_limit = 1000
-reserved-alias_recipient_limit = 1
+smtp_destination_recipient_limit = 1000
+reserved-alias_destination_recipient_limit = 1
# Tolerate occasional high latency
smtp_data_done_timeout = 1200s
{% if 'out' in group_names %}
smtp_tls_security_level = none
smtp_bind_address = 127.0.0.1
{% else %}
smtp_tls_security_level = encrypt
smtp_tls_cert_file = /etc/postfix/ssl/{{ ansible_fqdn }}.pem
smtp_tls_key_file = /etc/postfix/ssl/{{ ansible_fqdn }}.key
smtp_tls_session_cache_database = btree:$data_directory/smtp_tls_session_cache
smtp_tls_policy_maps = cdb:/etc/postfix/tls_policy
smtp_tls_fingerprint_digest = sha256
{% endif %}
-smtpd_tls_security_level = none
smtpd_tls_security_level = may
smtpd_tls_exclude_ciphers = EXPORT, LOW, MEDIUM, aNULL, eNULL, DES, RC4, MD5
smtpd_tls_cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file = /etc/ssl/private/ssl-cert-snakeoil.key
smtpd_tls_dh1024_param_file = /etc/ssl/private/dhparams.pem
smtpd_tls_CApath = /etc/ssl/certs/
smtpd_tls_session_cache_database= btree:$data_directory/smtpd_tls_session_cache
smtpd_tls_received_header = yes
smtpd_tls_ask_ccert = yes
# http://en.linuxreviews.org/HOWTO_Stop_spam_using_Postfix
# http://www.howtoforge.com/block_spam_at_mta_level_postfix
strict_rfc821_envelopes = yes
smtpd_delay_reject = yes
disable_vrfy_command = yes
# UCE control
@@ -123,46 +122,46 @@ unknown_relay_recipient_reject_code = 554
unknown_virtual_alias_reject_code = 554
unknown_virtual_mailbox_reject_code = 554
unverified_recipient_reject_code = 554
unverified_sender_reject_code = 554
postscreen_blacklist_action = drop
postscreen_dnsbl_threshold = 3
postscreen_dnsbl_action = enforce
postscreen_dnsbl_sites =
zen.spamhaus.org*3
swl.spamhaus.org*-4
b.barracudacentral.org*2
bl.spameatingmonkey.net*2
bl.spamcop.net
dnsbl.sorbs.net
list.dnswl.org=127.[0..255].[0..255].0*-2
list.dnswl.org=127.[0..255].[0..255].1*-3
list.dnswl.org=127.[0..255].[0..255].[2..255]*-4
postscreen_greet_action = enforce
-postscreen_whitelist_interfaces = !88.80.11.28 static:all
+postscreen_whitelist_interfaces = !88.80.11.28 ![2a00:16b0:242:13::de30] static:all
smtpd_client_restrictions =
permit_mynetworks
smtpd_helo_required = yes
smtpd_helo_restrictions =
permit_mynetworks
reject_non_fqdn_helo_hostname
reject_invalid_helo_hostname
smtpd_sender_restrictions =
reject_non_fqdn_sender
-smtpd_recipient_restrictions =
- # RFC requirements
- reject_non_fqdn_recipient
+smtpd_relay_restrictions =
permit_mynetworks
reject_unauth_destination
reject_unlisted_recipient
- permit_dnswl_client list.dnswl.org
+
+smtpd_recipient_restrictions =
+ reject_non_fqdn_recipient
smtpd_data_restrictions =
reject_unauth_pipelining
# vim: set filetype=pfmain :
diff --git a/roles/common-LDAP/templates/etc/ldap/database.ldif.j2 b/roles/common-LDAP/templates/etc/ldap/database.ldif.j2
index aa72f62..ff46178 100644
--- a/roles/common-LDAP/templates/etc/ldap/database.ldif.j2
+++ b/roles/common-LDAP/templates/etc/ldap/database.ldif.j2
@@ -191,48 +191,40 @@ olcAddContentAcl: TRUE
# local ldapi:// socket (when using auth_binds, Dovecot delegates
# authentication to the LDAP server).
# * Authenticated users are allowed to change (ie replace) their
# password through TLS-protected connections, but read access is not
# granted.
# * Domain postmasters are allowed to change (ie replace) their users'
# password through TLS-protected connections, but read access is not
# granted.
# * The same goes for general admins.
# * The same goes for local admins.
olcAccess: to dn.regex="^fvl=[^,]+,(fvd=[^,]+,ou=virtual,dc=fripost,dc=org)$"
filter=(objectClass=FripostVirtualUser)
attrs=userPassword
by realanonymous tls_ssf=128 =xd
by realanonymous sockurl.regex="^ldapi://" =xd
by realself tls_ssf=128 =w
by group/FripostVirtualDomain/fripostPostmaster.expand="$1" tls_ssf=128 =w
by dn.onelevel="ou=admins,dc=fripost,dc=org" tls_ssf=128 =w
by group.exact="cn=admin,ou=groups,dc=fripost,dc=org" =w
#
-# XXX
-# * Anonymous users are allowed to simple bind as Postfix, but only when
-# using a local ldapi:// listener from one of the Postfix instance
-# (which should be accessible by the 'postfix' UNIX user only).
-olcAccess: to dn.exact="cn=postfix,ou=services,dc=fripost,dc=org"
- attrs=userPassword
- by realanonymous sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =xd
-#
# TODO: are there other services which need to be able to simple bind?
#
# * Catch-all: no one else may access the passwords (including for
# simple bind).
olcAccess: to dn.subtree="dc=fripost,dc=org"
attrs=userPassword
by * =0
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Base
#
# * Only SyncRepl replicates may access operational attributes in the
# subtree, when using a TLS-protected connection.
{% if 'LDAP-provider' in group_names -%}
olcAccess: to dn.subtree="ou=virtual,dc=fripost,dc=org"
attrs=entryDN,entryCSN,entryUUID,structuralObjectClass,hasSubordinates,subschemaSubentry
by dn.onelevel="ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
by * =0
#
# * They may also read entries (ie, the attributes they have access to
@@ -245,254 +237,254 @@ olcAccess: to dn.subtree="ou=virtual,dc=fripost,dc=org"
by group.exact="cn=admin,ou=groups,dc=fripost,dc=org" =wrsd
by users =0 break
olcAccess: to dn.children="ou=virtual,dc=fripost,dc=org"
by group.exact="cn=admin,ou=groups,dc=fripost,dc=org" =wrsd
by users =0 break
{% endif -%}
#
# * Postfix may use the base as a searchBase on the MX:es, when
# connecting a local ldapi:// socket from the 'private' directory in
# one of the non-default instance's chroot.
# * So may Dovecot on the MDA (needed for the iterate filter), when
# SASL-binding using the EXTERNAL mechanism and connecting to a local
# ldapi:// socket.
olcAccess: to dn.exact="ou=virtual,dc=fripost,dc=org"
attrs=entry,objectClass
filter=(objectClass=FripostVirtual)
{% if 'MDA' in group_names -%}
by dn.exact="username=dovecot,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =sd
{% endif -%}
{% if 'MX' in group_names -%}
- by dn.exact="cn=postfix,ou=services,dc=fripost,dc=org" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =sd
+ by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =sd
{% endif -%}
by users =0 break
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Domain entries
#
# * The SyncRepl replicates have read access to the entry itself, when
# using a TLS-protected connection.
# * So has Postfix, when connecting a local ldapi:// socket from the
# 'private' directory in one of the non-default instance's chroot.
# * So has Dovecot on the MDA (for the iterate filter), when
# SASL-binding using the EXTERNAL mechanism and connecting to a local
# ldapi:// socket.
# * Amavis may use the entry as searchBase (required to look for the
# per-user preferences) but doesn't have read access to the entry.
# * The 'nobody' UNIX user has read access on the MX:es, when using
# SASL-binding using the EXTERNAL mechanism and connecting to a local
# ldapi:// socket. This is required for the 'reserved-alias.pl'
# script.
olcAccess: to dn.regex="^fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=entry,objectClass,fvd
filter=(&(objectClass=FripostVirtualDomain)(!(objectClass=FripostPendingEntry)))
{% if 'LDAP-provider' in group_names -%}
{% if groups.MX | difference([inventory_hostname]) -%}
by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
{% endif -%}
{% endif -%}
- by dn.exact="cn=postfix,ou=services,dc=fripost,dc=org" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
+ by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
{% if 'MDA' in group_names -%}
by dn.exact="username=dovecot,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
by dn.exact="username=amavis,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =sd
{% endif -%}
{% if 'MX' in group_names -%}
by dn.exact="username=nobody,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
{% endif -%}
by users =0 break
#
# * The SyncRepl MX replicates can check whether a virtual domain is
# active, and read the destination address for catch-alls, when using
# a TLS-protected connection.
# * So can Postfix on the MX:es, when connecting a local ldapi:// socket
# from the 'private' directory in one of the non-default instance's
# chroot.
{% if 'MX' in group_names or ('LDAP-provider' in group_names and groups.MX | difference([inventory_hostname])) %}
olcAccess: to dn.regex="^fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=fripostIsStatusActive,fripostOptionalMaildrop
filter=(&(objectClass=FripostVirtualDomain)(!(objectClass=FripostPendingEntry)))
{% if 'LDAP-provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
- by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
+ by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
{% endif -%}
{% if 'MX' in group_names -%}
- by dn.exact="cn=postfix,ou=services,dc=fripost,dc=org" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
+ by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
{% endif -%}
- by users =0 break
+ by users =0 break
{% endif %}
#
# * The 'nobody' UNIX user can list the domain owners and postmasters on
# the MX:es, when SASL-binding using the EXTERNAL mechanism and
# connecting to a local ldapi:// socket. This is required for the
# 'reserved-alias.pl' script.
olcAccess: to dn.regex="^fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=fripostOwner,fripostPostmaster
filter=(&(objectClass=FripostVirtualDomain)(!(objectClass=FripostPendingEntry)))
{% if 'LDAP-provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
{% endif -%}
{% if 'MX' in group_names %}
by dn.exact="username=nobody,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
{% endif -%}
by users =0 break
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Alias domain entries
#
# * The SyncRepl MX replicates have read access to the entry itself and
# the destination domain it aliases to, when using a TLS-protected
# connection.
# * So has Postfix on the MX:es, when connecting a local ldapi:// socket
# from the 'private' directory in one of the non-default instance's
# chroot.
{% if 'MX' in group_names or ('LDAP-provider' in group_names and groups.MX | difference([inventory_hostname])) %}
olcAccess: to dn.regex="^fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=entry,fripostMaildrop
filter=(&(objectClass=FripostVirtualAliasDomain)(!(objectClass=FripostPendingEntry)))
{% if 'LDAP-provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
- by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
+ by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
{% endif -%}
{% if 'MX' in group_names -%}
- by dn.exact="cn=postfix,ou=services,dc=fripost,dc=org" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
+ by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
{% endif -%}
- by users =0 break
+ by users =0 break
{% endif %}
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# User entries
#
# * The SyncRepl replicates have read access to the entry itself, when
# using a TLS-protected connection.
# * So has Postfix, when connecting a local ldapi:// socket from the
# 'private' directory in one of the non-default instance's chroot.
# * So has Dovecot on the MDA (for the iterate filter), when
# SASL-binding using the EXTERNAL mechanism and connecting to a local
# ldapi:// socket.
# * So has Amavis on the MDA, when SASL-binding using the EXTERNAL
# mechanism and connecting to a local ldapi:// socket.
olcAccess: to dn.regex="^fvl=[^,]+,fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=entry,objectClass,fvl
filter=(objectClass=FripostVirtualUser)
{% if 'LDAP-provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
- by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
+ by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
{% endif -%}
- by dn.exact="cn=postfix,ou=services,dc=fripost,dc=org" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
+ by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
{% if 'MDA' in group_names -%}
- by dn.exact="username=dovecot,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
- by dn.exact="username=amavis,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
+ by dn.exact="username=dovecot,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
+ by dn.exact="username=amavis,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
{% endif -%}
- by users =0 break
+ by users =0 break
#
# * The SyncRepl MX replicates can check whether a virtual user is
# active, when using a TLS-protected connection.
# * So can Postfix on the MX:es, when connecting a local ldapi:// socket
# from the 'private' directory in one of the non-default instance's
# chroot.
{% if 'MX' in group_names or ('LDAP-provider' in group_names and groups.MX | difference([inventory_hostname])) %}
olcAccess: to dn.regex="^fvl=[^,]+,fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=fripostIsStatusActive,fripostUseContentFilter
filter=(objectClass=FripostVirtualUser)
{% if 'LDAP-provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
- by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
+ by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
{% endif -%}
{% if 'MX' in group_names -%}
- by dn.exact="cn=postfix,ou=services,dc=fripost,dc=org" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
+ by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
{% endif -%}
- by users =0 break
+ by users =0 break
{% endif %}
{% if 'MDA' in group_names %}
#
# * Amavis can look for per-user configuration options, when
# SASL-binding using the EXTERNAL mechanism and connecting to a local
# ldapi:// socket.
# TODO: only allow it to read the configuration options users are allowed
# to set and modify.
olcAccess: to dn.regex="^fvl=[^,]+,fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=@AmavisAccount
filter=(&(objectClass=FripostVirtualUser)(objectClass=AmavisAccount)(fripostIsStatusActive=TRUE)(fripostUseContentFilter=TRUE))
by dn.exact="username=amavis,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
by users =0 break
#
# * Dovecot can look for user quotas, when SASL-binding using the
# EXTERNAL mechanism and connecting to a local ldapi:// socket.
olcAccess: to dn.regex="^fvl=[^,]+,fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=fripostUserQuota
filter=(objectClass=FripostVirtualUser)
by dn.exact="username=dovecot,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
by users =0 break
{% endif %}
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Alias entries
#
# * The SyncRepl MX replicates can read the entry itelf, whether it
# is active, and the address(es) it aliases to, when using a
# TLS-protected connection.
# * So can Postfix on the MX:es, when connecting a local ldapi:// socket
# from the 'private' directory in one of the non-default instance's
# chroot.
{% if 'MX' in group_names or ('LDAP-provider' in group_names and groups.MX | difference([inventory_hostname])) %}
olcAccess: to dn.regex="^fvl=[^,]+,fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=entry,objectClass,fvl,fripostMaildrop,fripostIsStatusActive
filter=(objectClass=FripostVirtualAlias)
{% if 'LDAP-provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
- by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
+ by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
{% endif -%}
{% if 'MX' in group_names -%}
- by dn.exact="cn=postfix,ou=services,dc=fripost,dc=org" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
+ by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
{% endif -%}
- by users =0 break
+ by users =0 break
{% endif %}
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# List entries
#
# * The SyncRepl replicates can read the entry itelf and the list manager, when
# using a TLS-protected connection.
# * So can Postfix on the MX:es, when connecting a local ldapi:// socket
# from the 'private' directory in one of the non-default instance's chroot.
{% if 'MX' in group_names or ('LDAP-provider' in group_names and groups.MX | difference([inventory_hostname])) %}
olcAccess: to dn.regex="^fvl=[^,]+,fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=entry,objectClass,fvl,fripostListManager
filter=(&(objectClass=FripostVirtualList)(!(objectClass=FripostPendingEntry)))
{% if 'LDAP-provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
- by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
+ by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
{% endif -%}
{% if 'MX' in group_names -%}
- by dn.exact="cn=postfix,ou=services,dc=fripost,dc=org" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
+ by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
{% endif -%}
- by users =0 break
+ by users =0 break
{% endif %}
#
# * The SyncRepl MX replicates can check whether a virtual list is
# active when using a TLS-protected connection.
# * So can Postfix on the MX:es, when connecting a local ldapi:// socket
# from the 'private' directory in one of the non-default instance's
# chroot.
{% if 'MX' in group_names or ('LDAP-provider' in group_names and groups.MX | difference([inventory_hostname])) %}
olcAccess: to dn.regex="^fvl=[^,]+,fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=fripostIsStatusActive
filter=(&(objectClass=FripostVirtualList)(!(objectClass=FripostPendingEntry)))
{% if 'LDAP-provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
- by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
+ by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
{% endif -%}
{% if 'MX' in group_names -%}
- by dn.exact="cn=postfix,ou=services,dc=fripost,dc=org" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
+ by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
{% endif -%}
- by users =0 break
+ by users =0 break
{% endif %}
{% if 'LDAP-provider' in group_names %}
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# TODO: allow users to edit their entry, etc
#
{% endif %}
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Catch-all
#
# * Catch all the breaks above.
# * Deny any access to everyone else.
olcAccess: to dn.subtree="dc=fripost,dc=org"
by dn.children="ou=virtual,dc=fripost,dc=org" +0
by * =0
# vim: set filetype=ldif :
diff --git a/roles/common/files/etc/postfix/master.cf b/roles/common/files/etc/postfix/master.cf
index dd5dfe8..36c016b 100644
--- a/roles/common/files/etc/postfix/master.cf
+++ b/roles/common/files/etc/postfix/master.cf
@@ -30,41 +30,41 @@ proxywrite unix - - n - 1 proxymap
smtp unix - - - - - smtp
smtpl unix - - - - - smtp
-o smtp_bind_address=127.0.0.1
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
127.0.0.1:16132 inet n - - - - smtpd
2525 inet n - - - - smtpd
2526 inet n - - - - smtpd
2527 inet n - - - - smtpd
127.0.0.1:2580 inet n - - - - smtpd
reserved-alias unix - n n - - pipe
- flags=Rhu user=nobody argv=/usr/local/sbin/reserved-alias.pl ${sender} ${original_recipient} @fripost.org
+ flags=Rhu user=nobody argv=/usr/local/bin/reserved-alias.pl ${sender} ${original_recipient} @fripost.org
sympa unix - n n - - pipe
flags=Rhu user=sympa argv=/usr/local/bin/sympa-queue ${user}
# Client part (lmtp) - amavis
amavisfeed unix - - n - 5 lmtp
-o lmtp_destination_recipient_limit=1000
-o lmtp_send_xforward_command=yes
-o lmtp_data_done_timeout=1200s
-o disable_dns_lookups=yes
# Server part (smtpd) - amavis (if the MDA and outgoing proxy are on the
# same machine, we need to create another entry, on another port.)
127.0.0.1:10025 inet n - n - - smtpd
-o content_filter=
-o smtpd_delay_reject=no
-o smtpd_client_restrictions=permit_mynetworks,reject
-o smtpd_helo_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_relay_restrictions=permit_mynetworks,reject
-o smtpd_data_restrictions=reject_unauth_pipelining