summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem@fripost.org>2015-06-04 20:26:53 +0200
committerGuilhem Moulin <guilhem@fripost.org>2015-06-07 02:54:26 +0200
commit2c925ea17fcb6f71826e5c0f30f99c5daba10e14 (patch)
tree90f0cbed686e3f5704b4440ab6239046412d91d6
parentf3d93ac759ee2ac08ecc7308d3019796e2285797 (diff)
Make the webmail connect directly to the outgoing SMTP proxy.
(Hence delete the 'webmail' Postfix instance.) This shortens the delay caused by the recipient verification probes.
-rw-r--r--group_vars/all.yml1
-rw-r--r--roles/common/files/etc/logcheck/ignore.d.server/postfix-local6
-rw-r--r--roles/common/files/etc/postfix/master.cf1
-rw-r--r--roles/webmail/handlers/main.yml4
-rw-r--r--roles/webmail/tasks/mail.yml42
-rw-r--r--roles/webmail/tasks/main.yml1
-rw-r--r--roles/webmail/tasks/roundcube.yml2
-rw-r--r--roles/webmail/templates/etc/postfix/main.cf.j2107
-rw-r--r--roles/webmail/templates/etc/stunnel/postfix.conf.j255
-rw-r--r--webmail.yml2
10 files changed, 96 insertions, 125 deletions
diff --git a/group_vars/all.yml b/group_vars/all.yml
index ef9fc82..25356bf 100644
--- a/group_vars/all.yml
+++ b/group_vars/all.yml
@@ -1,11 +1,10 @@
---
postfix_instance:
# The keys are the group names associated with a Postfix role, and the
# values are the name and group (optional) of the instance dedicated
# to that role.
IMAP: { name: mda, port: 2526 }
MX: { name: mx, group: mta }
out: { name: out, group: mta, port: 2525 }
MSA: { name: msa }
- webmail: { name: webmail }
lists: { name: lists, port: 2527 }
diff --git a/roles/common/files/etc/logcheck/ignore.d.server/postfix-local b/roles/common/files/etc/logcheck/ignore.d.server/postfix-local
index fd6cbcb..45327b1 100644
--- a/roles/common/files/etc/logcheck/ignore.d.server/postfix-local
+++ b/roles/common/files/etc/logcheck/ignore.d.server/postfix-local
@@ -14,43 +14,43 @@
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/scache\[[[:digit:]]+\]: statistics: max simultaneous domains=[[:digit:]]+ addresses=[[:digit:]]+ connection=[[:digit:]]+$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/smtpd\[[[:digit:]]+\]: [[:alnum:]]+: client=[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/cleanup\[[[:digit:]]+\]: [[:alnum:]]+: (resent-|)message-id=(<[^>]*>|[[:alnum:]_/+.@-]+)( \(added by [^[:space:]]+\))?$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/qmgr\[[[:digit:]]+\]: [[:alnum:]]+: from=<[^[:space:]]*>, size=[[:digit:]]+, nrcpt=[[:digit:]]+ \(queue active\)$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/n?qmgr\[[[:digit:]]+\]: [[:alnum:]]+: from=<.*>, status=expired, returned to sender$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/n?qmgr\[[[:digit:]]+\]: [[:alnum:]]+: message-id=(<[^>]*>|[[:alnum:]_/+.@-]+)( \(added by [^[:space:]]+\))?
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/n?qmgr\[[[:digit:]]+\]: [[:alnum:]]+: removed$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/n?qmgr\[[[:digit:]]+\]: [[:alnum:]]+: skipped, still being delivered$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/verify\[[[:digit:]]+\]: close database /var/lib/postfix\1/verify_cache\.db: No such file or directory \(possible Berkeley DB bug\)$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/verify\[[[:digit:]]+\]: cache btree:/var/lib/postfix\1/verify_cache full cleanup: retained=[[:digit:]]+ dropped=[[:digit:]]+ entries$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: lost connection after (AUTH|DATA \([[:digit:]]+ bytes\)) from [._[:alnum:]-]+\[[[:digit:].]{7,15}\]$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-\w+/smtpd\[[[:digit:]]+\]: lost connection after (CONNECT|STARTTLS) from [._[:alnum:]-]+\[([[:digit:].]{7,15}|unknown)\]$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/cleanup\[[[:digit:]]+\]: [[:xdigit:]]{10}: replace: header\s
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: [[:xdigit:]]{10}: client=[^[:space:]]+, sasl_method=[-[:alnum:]]+, sasl_username=[-_.@[:alnum:]]+(, sasl_sender=[-_.@[:alnum:]]+)?$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: warning: [-._[:alnum:]]+\[[.[:digit:]]+\]: SASL (PLAIN|LOGIN) authentication failed(:[ [:alnum:]]*)?$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: improper command pipelining after EHLO from [._[:alnum:]-]+\[[[:digit:].]{7,15}\]:\s
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: warning: hostname [._[:alnum:]-]+ does not resolve to address [[:xdigit:].:]{3,39}(: Name or service not known)?$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: warning: Connection concurrency limit exceeded: [0-9]+ from [._[:alnum:]-]+\[[[:digit:].]{7,15}\] for service smtpd$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: timeout after [-[:upper:]]+( \([[:digit:]]+ bytes\))? from [^[:space:]]+$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-((msa|mx)/smtpd|out/smtp)\[[[:digit:]]+\]: warning: (tls_text_name: [-._[:alnum:]]+\[[[:xdigit:].:]{3,39}\]: )?peer certificate has no (subject CN|issuer Organization)$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|webmail)/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: [[:upper:]]+ from [^[:space:]]+: 450( 4\.1\.2)? <[^>]*>: Recipient address rejected: Domain not found;( from=<[^>]*> to=<[^[:space:]]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|webmail)/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: [[:upper:]]+ from [^[:space:]]+: 450( 4\.1\.8)? <[^>]*>: Sender address rejected: Domain not found;( from=<[^>]*> to=<[^[:space:]]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|webmail)/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: [[:upper:]]+ from [^[:space:]]+: 504( 5\.5\.2)? <[^>]*>: (Recipient|Sender) address rejected: need fully-qualified address;( from=<[^>]*> to=<[^[:space:]]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: [[:upper:]]+ from [^[:space:]]+: 450( 4\.1\.2)? <[^>]*>: Recipient address rejected: Domain not found;( from=<[^>]*> to=<[^[:space:]]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: [[:upper:]]+ from [^[:space:]]+: 450( 4\.1\.8)? <[^>]*>: Sender address rejected: Domain not found;( from=<[^>]*> to=<[^[:space:]]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: [[:upper:]]+ from [^[:space:]]+: 504( 5\.5\.2)? <[^>]*>: (Recipient|Sender) address rejected: need fully-qualified address;( from=<[^>]*> to=<[^[:space:]]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 554 5\.7\.1 <[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]>: Client host rejected: Access denied;( from=<[^>]*> to=<[^[:space:]]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mda/lmtp\[[[:digit:]]+\]: [[:xdigit:]]{10}: to=<[^[:space:]]+>,( orig_to=<[^[:space:]]+>,)? relay=[._[:alnum:]-]+\[private/dovecot-lmtpd\],( conn_use=[[:digit:]]+,)? delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=2(\.[[:digit:]]+){2})?, status=sent \(2[[:digit:]][[:digit:]] .+\)$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-\w+/(error|n?qmgr|smtp)\[[[:digit:]]+\]: [[:alnum:]]+: to=<[^[:space:]]+>,( orig_to=<[^[:space:]]+>,)? relay=(none|[^[:space:]]+\[[[:digit:].]{7,15}\]:[[:digit:]]+),( conn_use=[[:digit:]]+,)? delay=[[:digit:].]+,( delays=[[:digit:]./]+,)?( dsn=[45]\.[[:digit:]]\.[[:digit:]],)? status=(deferred|undeliverable) \((delivery temporarily suspended: )?((lost connection with [^[:space:]]+|conversation with [^[:space:]]+ timed out) while (sending [[:alnum:]]+( [[:alnum:]]+)?|performing the (HELO|EHLO) handshake|receiving the initial server greeting|sending [[:alnum:]]+( [/[:alnum:]]+)?|sending end of data -- message may be sent more than once)|connect to [^[:space:]]+: (Connection timed out|read timeout|Connection refused)|host [^[:space:]]+ refused to talk to me: [45][[:digit:]][[:digit:]].*|Host or domain name not found. Name service errorfor name=[^[:space:]]+ type=MX: Host not found, try again|User unknown in virtual alias table|host [^[:space:]]+\[[[:digit:].]{7,15}\] said: [45][[:digit:]][[:digit:]] [45](\.[[:digit:]]+){2} <[^>]+>: (Temporarily rejected\. Try again later\.|Recipient address rejected: (undeliverable|unverified) address:) .*)\)$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:alnum:]]+: lost connection with [._[:alnum:]-]+\[[[:digit:].]{7,15}\] while (receiving the initial server greeting|sending [[:upper:] ]+)$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:alnum:]]+: conversation with [^[:space:]]+ timed out while sending message body$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:upper:][:digit:]]+: to=<[^[:space:]]+>(, orig_to=<[^[:space:]]+>)?, relay=[._[:alnum:]-]+\[[[:digit:].]{7,15}\](:[[:digit:]]{1,5})?,( conn_use=[[:digit:]]+,)? delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=[45](\.[[:digit:]]+){2})?, status=(deferred|bounced|undeliverable|SOFTBOUNCE) \(host [._[:alnum:]-]+\[[[:digit:].]{7,15}\] said: [45][[:digit:]][[:digit:]][- ]+.* \(in reply to (HELO|EHLO|MAIL FROM|RCPT TO|DATA|end of DATA) command\)\)$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: connect to [^[:space:]]+: (read timeout|Connection (refused|timed out)|Network is unreachable|No route to host)( \(port [[:digit:]]+\))?$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/[ls]mtp\[[[:digit:]]+\]: [[:upper:][:digit:]]+: to=<[^[:space:]]+>, relay=(none|[._[:alnum:]-]+\[[[:digit:].]{7,15}\](:[[:digit:]]{1,5})?), (conn_use=[[:digit:]]+, )?delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=[45](\.[[:digit:]]+){2})?, status=(deferred|bounced|undeliverable) \((host [._[:alnum:]-]+\[[[:digit:].]{7,15}\] said: [45][[:digit:]][[:digit:]] .+ \(in reply to (HELO|EHLO|MAIL FROM|RCPT TO|end of DATA) command\)|connect to [^[:space:]]+: (read timeout|Connection (refused|timed out)|Network is unreachable|No route to host)( \(port [[:digit:]]+\))?)\)$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:upper:][:digit:]]+: host [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\] said: [45][[:digit:]][[:digit:]][- ]+.* \(in reply to (HELO|EHLO|MAIL FROM|RCPT TO|(end of )?DATA) command\)$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mda|out)/smtpd\[[[:digit:]]+\]: [[:xdigit:]]{10}: client=[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\], orig_queue_id=[[:xdigit:]]{10}, orig_client=[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [A-Z[:digit:]]+: to=<[^[:space:]]+>,( orig_to=<[^[:space:]]+>,) relay=[^[:space:]]+, delay=[[:digit:]]+, status=deferred \(host [^[:space:]]+ said: [45][[:digit:]]{2} <[^[:space:]]*>: Recipient address rejected: Greylisted for [[:digit:]]+ (seconds|minutes)(\(see http://isg.ee.ethz.ch/tools/postgrey/help/[.[:alnum:]-]+.html\))? \(in reply to (HELO|EHLO|MAIL FROM|RCPT TO|DATA|end of DATA) command\)\)$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:alnum:]]+: to=<.*>,( orig_to=<[^[:space:]]+>,)? relay=[^[:space:]]+\](:[[:digit:]]+)?,( conn_use=[[:digit:]]+,)? delay=[[:digit:].]+,( delays=[[:digit:]./]+,)?( dsn=4\.[[:digit:]]\.[[:digit:]],)? status=deferred \(host [^[:space:]]+\] said: .*$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mda|out)/smtpd?\[[[:digit:]]+\]: warning: numeric domain name in resource data of MX record for [._[:alnum:]-]+: [[:xdigit:].:]{3,39}$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: SSL_accept error from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: (lost connection|Connection reset by peer|-?[[:digit:]]+|Connection timed out)$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:SSL3_READ_BYTES:(sslv3|tlsv1) alert (unknown ca|certificate unknown):s3_pkt.c:[0-9]+:SSL alert number [[:digit:]]+:$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(out|mx)/bounce\[[[:digit:]]+\]: [[:xdigit:]]+: sender (delay|non-delivery|delivery status) notification: [[:xdigit:]]+$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:upper:][:digit:]]+: host [^[:space:]]+ refused to talk to me: [45][[:digit:]][[:digit:]].*$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:upper:][:digit:]]+: enabling PIX <CRLF>\.<CRLF> workaround for [._[:alnum:]-]+\[[[:digit:].]{7,15}\](:[[:digit:]]{1,5})?$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:upper:][:digit:]]+: enabling PIX workarounds:( (disable_esmtp|delay_dotcrlf))+ for [._[:alnum:]-]+\[[[:digit:].]{7,15}\](:[[:digit:]]{1,5})?$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:upper:][:digit:]]+: to=<[^>]+>, relay=[-_.[:alnum:]]+, delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=4(\.[[:digit:]]+){2})?, status=deferred \(connect to [._[:alnum:]-]+\[(unknown|[[:xdigit:].:]{3,39})\]:[[:digit:]]+: (Network is unreachable|No route to host)\)$
diff --git a/roles/common/files/etc/postfix/master.cf b/roles/common/files/etc/postfix/master.cf
index 36c016b..9b81c70 100644
--- a/roles/common/files/etc/postfix/master.cf
+++ b/roles/common/files/etc/postfix/master.cf
@@ -28,41 +28,40 @@ flush unix n - - 1000? 0 flush
proxymap unix - - n - - proxymap
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/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=
diff --git a/roles/webmail/handlers/main.yml b/roles/webmail/handlers/main.yml
index 76084e4..f7e403e 100644
--- a/roles/webmail/handlers/main.yml
+++ b/roles/webmail/handlers/main.yml
@@ -1,6 +1,6 @@
---
-- name: Reload Postfix
- service: name=postfix state=reloaded
+- name: Restart stunnel
+ service: name=stunnel4 pattern=/usr/bin/stunnel4 state=restarted
- name: Restart Nginx
service: name=nginx state=restarted
diff --git a/roles/webmail/tasks/mail.yml b/roles/webmail/tasks/mail.yml
index e2dea38..7603a56 100644
--- a/roles/webmail/tasks/mail.yml
+++ b/roles/webmail/tasks/mail.yml
@@ -1,15 +1,39 @@
-- name: Install Postfix
- apt: pkg=postfix
+- name: Install stunnel
+ apt: pkg=stunnel4
-- name: Configure Postfix
- template: src=etc/postfix/main.cf.j2
- dest=/etc/postfix-{{ postfix_instance[inst].name }}/main.cf
+- name: Auto-enable stunnel
+ lineinfile: dest=/etc/default/stunnel4
+ regexp='^(\s*#)?\s*ENABLED='
+ line='ENABLED=1'
+ owner=root group=root
+ mode=0644
+
+- name: Create /etc/stunnel/certs
+ file: path=/etc/stunnel/certs
+ state=directory
+ owner=root group=root
+ mode=0755
+
+- name: Copy the SMTP outgoing proxy's X.509 certificate
+ assemble: src=certs/postfix regexp="{{ groups.out | difference([inventory_hostname]) | join('|') }}\.pem$" remote_src=no
+ dest=/etc/stunnel/certs/postfix.pem
owner=root group=root
mode=0644
+ register: r1
notify:
- - Reload Postfix
+ - Restart stunnel
-- meta: flush_handlers
+- name: Configure stunnel
+ template: src=etc/stunnel/postfix.conf.j2
+ dest=/etc/stunnel/postfix.conf
+ owner=root group=root
+ mode=0644
+ register: r2
+ notify:
+ - Restart stunnel
-- name: Start Postfix
- service: name=postfix state=started
+- name: Start stunnel
+ service: name=stunnel4 pattern=/usr/bin/stunnel4 state=started
+ when: not (r1.changed or r2.changed)
+
+- meta: flush_handlers
diff --git a/roles/webmail/tasks/main.yml b/roles/webmail/tasks/main.yml
index a6eeee2..030a547 100644
--- a/roles/webmail/tasks/main.yml
+++ b/roles/webmail/tasks/main.yml
@@ -1,2 +1,3 @@
- include: mail.yml tags=postfix,mail
+ when: "'out' not in group_names"
- include: roundcube.yml tags=roundcube,webmail
diff --git a/roles/webmail/tasks/roundcube.yml b/roles/webmail/tasks/roundcube.yml
index ebe93c8..5392242 100644
--- a/roles/webmail/tasks/roundcube.yml
+++ b/roles/webmail/tasks/roundcube.yml
@@ -19,41 +19,41 @@
owner=root group=root
mode=0644
- name: Configure Roundcube
lineinfile: dest=/etc/roundcube/main.inc.php
"regexp=^\\s*\\$rcmail_config\\['{{ item.var }}'\\]\\s*="
"line=$rcmail_config['{{ item.var }}'] = {{ item.value }};"
owner=root group=www-data
mode=0640
with_items:
# Logging/Debugging
- { var: smtp_log, value: "FALSE" }
# IMAP
- { var: default_host, value: "'localhost'" }
- { var: default_port, value: "143" }
- { var: imap_auth_type, value: "'plain'" }
- { var: imap_cache, value: "null" }
- { var: messages_cache, value: "null" }
# SMTP
- { var: smtp_server, value: "'localhost'" }
- - { var: smtp_port, value: "2580" }
+ - { var: smtp_port, value: "2525" }
# System
- { var: force_https, value: "TRUE" }
- { var: login_autocomplete, value: "2" }
- { var: skin_logo, value: "'skins/logo_webmail.png'" }
- { var: username_domain, value: "'fripost.org'" }
- { var: product_name, value: "'Fripost'" }
# Plugins
- { var: plugins, value: "array('additional_message_headers','managesieve','password')" }
# User Interface
- { var: skin, value: "'classic'" }
- { var: language, value: "'sv_SE'" }
- { var: create_default_folders, value: "TRUE" }
# User Preferences
- { var: htmleditor, value: "TRUE" }
- { var: skip_deleted, value: "TRUE" }
- { var: check_all_folders, value: "FALSE" }
- name: Make the logo a hyperlink to the website
lineinfile: dest=/usr/share/roundcube/skins/{{ item }}/templates/login.html
regexp='^(<roundcube:object name="logo" src="/images/roundcube_logo.png"[^>]* />)$'
diff --git a/roles/webmail/templates/etc/postfix/main.cf.j2 b/roles/webmail/templates/etc/postfix/main.cf.j2
deleted file mode 100644
index f4079d6..0000000
--- a/roles/webmail/templates/etc/postfix/main.cf.j2
+++ /dev/null
@@ -1,107 +0,0 @@
-########################################################################
-# Webmail configuration
-#
-# {{ ansible_managed }}
-# Do NOT edit this file directly!
-
-smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
-biff = no
-readme_directory = no
-mail_owner = postfix
-
-delay_warning_time = 4h
-maximal_queue_lifetime = 5d
-
-myorigin = /etc/mailname
-myhostname = webmail{{ webmailno | default('') }}.$mydomain
-mydomain = fripost.org
-append_dot_mydomain = no
-
-# Turn off all TCP/IP listener ports except that necessary for the webmail.
-master_service_disable = !127.0.0.1:2580.inet inet
-
-queue_directory = /var/spool/postfix-{{ postfix_instance[inst].name }}
-data_directory = /var/lib/postfix-{{ postfix_instance[inst].name }}
-multi_instance_group = {{ postfix_instance[inst].group | default('') }}
-multi_instance_name = postfix-{{ postfix_instance[inst].name }}
-multi_instance_enable = yes
-
-# This server is a nullclient
-mynetworks_style = host
-inet_interfaces = loopback-only
-
-# 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 = +
-
-# 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 =
-
-
-# Don't rewrite remote headers
-local_header_rewrite_clients =
-# Avoid splitting the envelope and scanning messages multiple times
-smtp_destination_recipient_limit = 1000
-# 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
-
-
-strict_rfc821_envelopes = yes
-smtpd_delay_reject = yes
-disable_vrfy_command = yes
-
-# UCE control
-unknown_client_reject_code = 554
-unverified_recipient_reject_code = 550
-
-smtpd_client_restrictions =
- permit_mynetworks
- reject
-
-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
- reject_unknown_sender_domain
-
-smtpd_relay_restrictions =
- permit_mynetworks
- reject
-
-smtpd_recipient_restrictions =
- reject_non_fqdn_recipient
- reject_unknown_recipient_domain
- reject_unverified_recipient
-
-smtpd_data_restrictions =
- reject_unauth_pipelining
-
-# vim: set filetype=pfmain :
diff --git a/roles/webmail/templates/etc/stunnel/postfix.conf.j2 b/roles/webmail/templates/etc/stunnel/postfix.conf.j2
new file mode 100644
index 0000000..78922c8
--- /dev/null
+++ b/roles/webmail/templates/etc/stunnel/postfix.conf.j2
@@ -0,0 +1,55 @@
+; **************************************************************************
+; * Global options *
+; **************************************************************************
+
+; setuid()/setgid() to the specified user/group in daemon mode
+setuid = stunnel4
+setgid = stunnel4
+
+; PID is created inside the chroot jail
+pid = /var/run/stunnel4/postfix.pid
+
+; Only log messages at severity warning (4) and higher
+debug = 4
+
+; **************************************************************************
+; * Service defaults may also be specified in individual service sections *
+; **************************************************************************
+
+; Certificate/key is needed in server mode and optional in client mode
+cert = /etc/postfix/ssl/{{ ansible_fqdn }}.pem
+key = /etc/postfix/ssl/{{ ansible_fqdn }}.key
+client = yes
+socket = a:SO_BINDTODEVICE=lo
+
+; Some performance tunings
+socket = l:TCP_NODELAY=1
+socket = r:TCP_NODELAY=1
+
+; Prevent MITM attacks
+verify = 4
+
+; Disable support for insecure protocols
+options = NO_SSLv2
+options = NO_SSLv3
+options = NO_TLSv1
+options = NO_TLSv1.1
+
+; These options provide additional security at some performance degradation
+options = SINGLE_ECDH_USE
+options = SINGLE_DH_USE
+
+; Select permitted SSL ciphers
+ciphers = EECDH+AES:EDH+AES:!MEDIUM:!LOW:!EXP:!aNULL:!eNULL:!SSLv2:!SSLv3:!TLSv1:!TLSv1.1
+
+; **************************************************************************
+; * Service definitions (remove all services for inetd mode) *
+; **************************************************************************
+
+[smtp]
+accept = localhost:2525
+connect = outgoing.fripost.org:{{ postfix_instance.out.port }}
+CAfile = /etc/stunnel/certs/postfix.pem
+protocol = smtp
+
+; vim:ft=dosini
diff --git a/webmail.yml b/webmail.yml
index d8a6a1e..0ef0487 100644
--- a/webmail.yml
+++ b/webmail.yml
@@ -1,5 +1,5 @@
---
- name: Configure the webmail
hosts: webmail
roles:
- - { role: webmail, inst: webmail }
+ - webmail