summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem@fripost.org>2014-07-09 01:23:01 +0200
committerGuilhem Moulin <guilhem@fripost.org>2015-06-07 02:52:49 +0200
commit55e9b2a0ebc87a353f9c9496a77b313e41e47bd4 (patch)
tree30b5abd316a31688c494f03ee4cd2ae4fccc38f5
parent368540caee8fff8aa90b1542897188e9f98ac585 (diff)
Perform the alias resolution and address validation solely on the MX:es.
We can therefore spare some lookups on the MDA, and use static:all instead.
-rw-r--r--roles/IMAP/files/etc/postfix/transport1
-rw-r--r--roles/IMAP/files/etc/postfix/virtual/mailbox.cf9
l---------roles/IMAP/files/etc/postfix/virtual/mailbox_domains.cf1
-rw-r--r--roles/IMAP/files/etc/postfix/virtual/transport_content_filter.cf9
-rw-r--r--roles/IMAP/tasks/mda.yml33
-rw-r--r--roles/IMAP/templates/etc/postfix/main.cf.j211
-rw-r--r--roles/MX/tasks/main.yml5
-rw-r--r--roles/MX/templates/etc/postfix/main.cf.j22
-rw-r--r--roles/MX/templates/etc/postfix/virtual/alias.cf.j22
-rw-r--r--roles/MX/templates/etc/postfix/virtual/alias_domains.cf.j21
-rw-r--r--roles/MX/templates/etc/postfix/virtual/catchall.cf.j21
-rw-r--r--roles/MX/templates/etc/postfix/virtual/list.cf.j22
-rw-r--r--roles/MX/templates/etc/postfix/virtual/mailbox.cf.j22
-rw-r--r--roles/MX/templates/etc/postfix/virtual/mailbox_domains.cf.j22
-rw-r--r--roles/MX/templates/etc/postfix/virtual/reserved_alias.pcre.j22
-rw-r--r--roles/MX/templates/etc/postfix/virtual/transport.j22
-rw-r--r--roles/common/templates/etc/iptables/services.j22
17 files changed, 36 insertions, 51 deletions
diff --git a/roles/IMAP/files/etc/postfix/transport b/roles/IMAP/files/etc/postfix/transport
new file mode 100644
index 0000000..d40ac5d
--- /dev/null
+++ b/roles/IMAP/files/etc/postfix/transport
@@ -0,0 +1 @@
+filter.mda.fripost.org amavisfeed:[127.0.0.1]:10041
diff --git a/roles/IMAP/files/etc/postfix/virtual/mailbox.cf b/roles/IMAP/files/etc/postfix/virtual/mailbox.cf
deleted file mode 100644
index e69343b..0000000
--- a/roles/IMAP/files/etc/postfix/virtual/mailbox.cf
+++ /dev/null
@@ -1,9 +0,0 @@
-server_host = ldapi://%2Fprivate%2Fldapi/
-version = 3
-search_base = fvl=%u,fvd=%d,ou=virtual,dc=fripost,dc=org
-domain = static:all
-scope = base
-bind = none
-query_filter = (&(objectClass=FripostVirtualUser)(fvl=%u))
-result_attribute = fvl
-result_format = OK
diff --git a/roles/IMAP/files/etc/postfix/virtual/mailbox_domains.cf b/roles/IMAP/files/etc/postfix/virtual/mailbox_domains.cf
deleted file mode 120000
index 05f7ed9..0000000
--- a/roles/IMAP/files/etc/postfix/virtual/mailbox_domains.cf
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../MX/templates/etc/postfix/virtual/mailbox_domains.cf.j2 \ No newline at end of file
diff --git a/roles/IMAP/files/etc/postfix/virtual/transport_content_filter.cf b/roles/IMAP/files/etc/postfix/virtual/transport_content_filter.cf
deleted file mode 100644
index 642b722..0000000
--- a/roles/IMAP/files/etc/postfix/virtual/transport_content_filter.cf
+++ /dev/null
@@ -1,9 +0,0 @@
-server_host = ldapi://%2Fprivate%2Fldapi/
-version = 3
-search_base = fvl=%u,fvd=%d,ou=virtual,dc=fripost,dc=org
-domain = static:all
-scope = base
-bind = none
-query_filter = (&(objectClass=FripostVirtualUser)(objectClass=AmavisAccount)(fvl=%u))
-result_attribute = fvl
-result_format = amavisfeed:[127.0.0.1]:10041
diff --git a/roles/IMAP/tasks/mda.yml b/roles/IMAP/tasks/mda.yml
index 698fd4f..897a61d 100644
--- a/roles/IMAP/tasks/mda.yml
+++ b/roles/IMAP/tasks/mda.yml
@@ -1,66 +1,61 @@
- name: Install Postfix
apt: pkg={{ item }}
with_items:
- postfix
- postfix-ldap
- 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
-
-- name: Copy lookup tables
- copy: src=etc/postfix/virtual/{{ item }}
- dest=/etc/postfix-{{ postfix_instance[inst].name }}/virtual/{{ item }}
+- name: Copy the transport and recipient canonical maps
+ copy: src=etc/postfix/{{ item }}
+ dest=/etc/postfix-{{ postfix_instance[inst].name }}/{{ item }}
owner=root group=root
mode=0644
with_items:
- - mailbox_domains.cf
- - mailbox.cf
- - transport_content_filter.cf
-
-- name: Copy recipient canonical
- # no need to reload upon change, as cleanup(8) is short-running
- copy: src=etc/postfix/recipient_canonical.pcre
- dest=/etc/postfix-{{ postfix_instance[inst].name }}/recipient_canonical.pcre
- owner=root group=root
- mode=0644
+ # no need to reload upon change, as cleanup(8) is short-running
+ - recipient_canonical.pcre
+ - transport
- name: Build the Postfix relay clientcerts map
sudo: False
# smtpd_tls_fingerprint_digest MUST be sha256!
local_action: shell openssl x509 -in certs/postfix/{{ item }}.pem -noout -fingerprint -sha256 | sed -nr 's/^.*=(.*)/\1 {{ item }}/p'
with_items: groups.MX | difference([inventory_hostname]) | sort
register: relay_clientcerts
changed_when: False
tags:
- tls_policy
- name: Copy the Postfix relay clientcerts map
template: src=etc/postfix/relay_clientcerts.j2
dest=/etc/postfix-{{ postfix_instance[inst].name }}/relay_clientcerts
owner=root group=root
mode=0644
tags:
- tls_policy
- name: Compile the Postfix relay clientcerts map
postmap: cmd=postmap src=/etc/postfix-{{ postfix_instance[inst].name }}/relay_clientcerts db=cdb
owner=root group=root
mode=0644
tags:
- tls_policy
+- name: Compile the Postfix transport maps
+ # trivial-rewrite(8) is a long-running process, so it's safer to reload
+ postmap: cmd=postmap src=/etc/postfix-{{ postfix_instance[inst].name }}/transport db=cdb
+ owner=root group=root
+ mode=0644
+ notify:
+ - Reload Postfix
+
- meta: flush_handlers
- name: Start Postfix
service: name=postfix state=started
diff --git a/roles/IMAP/templates/etc/postfix/main.cf.j2 b/roles/IMAP/templates/etc/postfix/main.cf.j2
index 5758146..5a17fe2 100644
--- a/roles/IMAP/templates/etc/postfix/main.cf.j2
+++ b/roles/IMAP/templates/etc/postfix/main.cf.j2
@@ -28,49 +28,50 @@ multi_instance_enable = yes
# This server is a Mail Delivery Agent
mynetworks_style = host
inet_interfaces = all
# No local delivery
mydestination =
local_transport = error:5.1.1 Mailbox unavailable
alias_maps =
alias_database =
local_recipient_maps =
message_size_limit = 67108864
recipient_delimiter = +
# No relay: this server is inbound-only
relay_transport = error:5.1.1 Relay unavailable
default_transport = error:5.1.1 Transport unavailable
-# Virtual transport (the alias resolution is already done by the MX:es)
+# Virtual transport (the alias resolution and address validation is
+# performed on the MX:es only)
virtual_transport = lmtp:unix:private/dovecot-lmtpd
lmtp_bind_address = 127.0.0.1
-virtual_mailbox_domains = ldap:$config_directory/virtual/mailbox_domains.cf
-virtual_mailbox_maps = ldap:$config_directory/virtual/mailbox.cf
-transport_maps = ldap:$config_directory/virtual/transport_content_filter.cf
+virtual_mailbox_domains = static:all
+virtual_mailbox_maps = static:all
+#transport_maps = cdb:$config_directory/transport
# Restore the original envelope recipient
-relay_domains = $myhostname
+relay_domains =
recipient_canonical_classes = envelope_recipient
recipient_canonical_maps = pcre:$config_directory/recipient_canonical.pcre
# Don't rewrite remote headers
local_header_rewrite_clients =
relay_clientcerts = cdb:$config_directory/relay_clientcerts
smtpd_tls_security_level = may
smtpd_tls_cert_file = /etc/postfix/ssl/{{ ansible_fqdn }}.pem
smtpd_tls_key_file = /etc/postfix/ssl/{{ ansible_fqdn }}.key
smtpd_tls_session_cache_database= btree:$data_directory/smtpd_tls_session_cache
smtpd_tls_received_header = yes
smtpd_tls_ask_ccert = yes
smtpd_tls_session_cache_timeout = 3600s
smtpd_tls_fingerprint_digest = sha256
strict_rfc821_envelopes = yes
smtpd_delay_reject = yes
diff --git a/roles/MX/tasks/main.yml b/roles/MX/tasks/main.yml
index a372cf4..a6c68f6 100644
--- a/roles/MX/tasks/main.yml
+++ b/roles/MX/tasks/main.yml
@@ -38,36 +38,39 @@
state=directory
owner=root group=root
mode=0755
- name: Copy lookup tables
template: src=etc/postfix/virtual/{{ item }}.j2
dest=/etc/postfix-{{ postfix_instance[inst].name }}/virtual/{{ item }}
owner=root group=root
mode=0644
with_items:
- mailbox_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
- transport
-- name: Compile the Reserved Transport Maps
+- 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
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 8785c5a..b0da1bc 100644
--- a/roles/MX/templates/etc/postfix/main.cf.j2
+++ b/roles/MX/templates/etc/postfix/main.cf.j2
@@ -37,41 +37,41 @@ local_transport = error:5.1.1 Mailbox unavailable
alias_maps =
alias_database =
local_recipient_maps =
message_size_limit = 67108864
recipient_delimiter = +
# Forward everything to our internal outgoing proxy
{% if 'out' in group_names %}
relayhost = [127.0.0.1]:{{ postfix_instance.out.port }}
{% else %}
relayhost = [outgoing.fripost.org]:{{ postfix_instance.out.port }}
{% endif %}
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_transport = error:5.1.1 Virtual transport unavailable
virtual_mailbox_domains = ldap:$config_directory/virtual/mailbox_domains.cf
virtual_alias_maps = pcre:$config_directory/virtual/reserved_alias.pcre
# first we do the alias resolution...
ldap:$config_directory/virtual/alias.cf
# ...and unless there is matching mailbox/list...
ldap:$config_directory/virtual/mailbox.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
virtual_mailbox_maps =
transport_maps = cdb:$config_directory/virtual/transport
# Don't rewrite remote headers
local_header_rewrite_clients =
# Pass the client information along to the content filter
smtp_send_xforward_command = yes
# Avoid splitting the envelope and scanning messages multiple times
smtp_destination_recipient_limit = 1000
diff --git a/roles/MX/templates/etc/postfix/virtual/alias.cf.j2 b/roles/MX/templates/etc/postfix/virtual/alias.cf.j2
index 31a23ce..c0ab405 100644
--- a/roles/MX/templates/etc/postfix/virtual/alias.cf.j2
+++ b/roles/MX/templates/etc/postfix/virtual/alias.cf.j2
@@ -1,10 +1,10 @@
server_host = ldapi://%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
-query_filter = (&(objectClass=FripostVirtualAlias)(fvl=%u))
+query_filter = (&(objectClass=FripostVirtualAlias)(fvl=%u)(fripostIsStatusActive=TRUE))
result_attribute = fripostMaildrop
diff --git a/roles/MX/templates/etc/postfix/virtual/alias_domains.cf.j2 b/roles/MX/templates/etc/postfix/virtual/alias_domains.cf.j2
index b338c8c..7679a9c 100644
--- a/roles/MX/templates/etc/postfix/virtual/alias_domains.cf.j2
+++ b/roles/MX/templates/etc/postfix/virtual/alias_domains.cf.j2
@@ -1,11 +1,12 @@
server_host = ldapi://%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
+# 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/templates/etc/postfix/virtual/catchall.cf.j2 b/roles/MX/templates/etc/postfix/virtual/catchall.cf.j2
index 3d86ecf..818ad02 100644
--- a/roles/MX/templates/etc/postfix/virtual/catchall.cf.j2
+++ b/roles/MX/templates/etc/postfix/virtual/catchall.cf.j2
@@ -1,10 +1,11 @@
server_host = ldapi://%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
+# 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/templates/etc/postfix/virtual/list.cf.j2 b/roles/MX/templates/etc/postfix/virtual/list.cf.j2
index a39343b..a2ff325 100644
--- a/roles/MX/templates/etc/postfix/virtual/list.cf.j2
+++ b/roles/MX/templates/etc/postfix/virtual/list.cf.j2
@@ -1,13 +1,13 @@
server_host = ldapi://%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
-query_filter = (&(objectClass=FripostVirtualList)(fvl=%u))
+query_filter = (&(objectClass=FripostVirtualList)(!(objectClass=FripostPendingEntry))(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@lists.fripost.org
diff --git a/roles/MX/templates/etc/postfix/virtual/mailbox.cf.j2 b/roles/MX/templates/etc/postfix/virtual/mailbox.cf.j2
index 083b638..9b584c9 100644
--- a/roles/MX/templates/etc/postfix/virtual/mailbox.cf.j2
+++ b/roles/MX/templates/etc/postfix/virtual/mailbox.cf.j2
@@ -1,13 +1,13 @@
server_host = ldapi://%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
-query_filter = (&(objectClass=FripostVirtualUser)(fvl=%u))
+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/templates/etc/postfix/virtual/mailbox_domains.cf.j2 b/roles/MX/templates/etc/postfix/virtual/mailbox_domains.cf.j2
index fde355e..1cb8add 100644
--- a/roles/MX/templates/etc/postfix/virtual/mailbox_domains.cf.j2
+++ b/roles/MX/templates/etc/postfix/virtual/mailbox_domains.cf.j2
@@ -1,10 +1,10 @@
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
-query_filter = (&(objectClass=FripostVirtualDomain)(fvd=%s))
+query_filter = (&(objectClass=FripostVirtualDomain)(!(objectClass=FripostPendingEntry))(fvd=%s)(fripostIsStatusActive=TRUE))
result_attribute = fvd
result_format = OK
diff --git a/roles/MX/templates/etc/postfix/virtual/reserved_alias.pcre.j2 b/roles/MX/templates/etc/postfix/virtual/reserved_alias.pcre.j2
index 6f62a01..f1c79c7 100644
--- a/roles/MX/templates/etc/postfix/virtual/reserved_alias.pcre.j2
+++ b/roles/MX/templates/etc/postfix/virtual/reserved_alias.pcre.j2
@@ -1,5 +1,5 @@
/^(?:postmaster|abuse)(?:\+.*)?@fripost\.org$/ admin@fripost.org
# For other domains, RFC 822 section 6.3 and RFC 2142 section 4
# mandatory aliases are forwarded to OUR admin team and to the domain
# owner or postmaster, if there are any.
-/^((?:postmaster|abuse)(?:\+.*)?@.*)/ $1@reserved.locahost.localdomain
+/^(postmaster|abuse)(?:\+.*)?@(.*)/ $2/$1@reserved.fripost.org
diff --git a/roles/MX/templates/etc/postfix/virtual/transport.j2 b/roles/MX/templates/etc/postfix/virtual/transport.j2
index a34dcad..85715a0 100644
--- a/roles/MX/templates/etc/postfix/virtual/transport.j2
+++ b/roles/MX/templates/etc/postfix/virtual/transport.j2
@@ -1,13 +1,13 @@
-reserved.locahost.localdomain reserved-alias:
+reserved.fripost.org reserved-alias:
{% if 'LDA' in group_names %}
mda.fripost.org smtpl:[127.0.0.1]:{{ postfix_instance.IMAP.port }}
{% else %}
mda.fripost.org smtp:[mda.fripost.org]:{{ postfix_instance.IMAP.port }}
{% endif %}
{% if 'lists' in group_names %}
lists.fripost.org smtpl:[127.0.0.1]:{{ postfix_instance.lists.port }}
{% else %}
lists.fripost.org smtp:[lists.fripost.org]:{{ postfix_instance.lists.port }}
{% endif %}
diff --git a/roles/common/templates/etc/iptables/services.j2 b/roles/common/templates/etc/iptables/services.j2
index 4e78d1e..d24b55d 100644
--- a/roles/common/templates/etc/iptables/services.j2
+++ b/roles/common/templates/etc/iptables/services.j2
@@ -3,40 +3,42 @@
#
# direction protocol destination port source port
# (in|out|inout)[46]? (tcp|udp|..) (port|port:port|port,port) (port|port:port|port,port)
out tcp 80,443 # HTTP/HTTPS
out udp 53 # DNS
out udp 67 # DHCP
{% if 'NTP-master' in group_names %}
out udp 123 123 # NTP
{% endif %}
in tcp {{ ansible_ssh_port|default('22') }} # SSH
{% if 'LDAP-provider' in group_names %}
in tcp 636 # LDAPS
{% elif 'MX' in group_names or 'lists' in group_name %}
out tcp 636 # LDAPS
{% endif %}
{% if 'MX' in group_names %}
in tcp 25 # SMTP
+out tcp {{ postfix_instance.IMAP.port }}
+out tcp {{ postfix_instance.lists.port }}
{% endif %}
{% if 'out' in group_names %}
in tcp {{ postfix_instance.out.port }}
out tcp 25 # SMTP
{% else %}
out tcp {{ postfix_instance.out.port }}
{% endif %}
{% if 'IMAP' in group_names %}
in tcp 993 # IMAPS
in tcp 4190 # ManageSieve
{% endif %}
{% if 'MDA' in group_names %}
in tcp {{ postfix_instance.IMAP.port }}
{% endif %}
{% if 'MSA' in group_names %}
in tcp 587 # SMTP-AUTH
{% endif %}
{% if 'webmail' in group_names %}
in tcp 80,443 # HTTP/HTTPS
out tcp 993 # IMAP # TODO imapc