diff options
author | Aaron LI <aly@aaronly.me> | 2018-03-05 22:51:51 +0800 |
---|---|---|
committer | Aaron LI <aly@aaronly.me> | 2018-03-14 11:35:08 +0800 |
commit | a0eb2564a60b216ebb4f11f42945eeef68eb1579 (patch) | |
tree | be4b9729b5099a7d4fd549befb461b4ae69aea65 | |
parent | ddc53fbccc185bc52adf1050a98531c3750bf1fd (diff) | |
download | ansible-dfly-vps-a0eb2564a60b216ebb4f11f42945eeef68eb1579.tar.bz2 |
mail: setup postfix with dovecot (SASL auth + LDA virtual transport)
-rw-r--r-- | roles/mail/files/postfix/header-checks-submission.pcre | 35 | ||||
-rw-r--r-- | roles/mail/files/postfix/helo-access.pcre | 26 | ||||
-rw-r--r-- | roles/mail/files/postfix/master.cf | 93 | ||||
-rw-r--r-- | roles/mail/handlers/main.yml | 3 | ||||
-rw-r--r-- | roles/mail/tasks/main.yml | 56 | ||||
-rw-r--r-- | roles/mail/templates/postfix/main.cf.j2 | 846 | ||||
-rw-r--r-- | roles/mail/templates/postfix/virtual-domains.j2 | 14 | ||||
-rw-r--r-- | roles/mail/templates/postfix/virtual-users.j2 | 46 | ||||
-rw-r--r-- | roles/mail/templates/postfix/virtual.j2 | 45 |
9 files changed, 1154 insertions, 10 deletions
diff --git a/roles/mail/files/postfix/header-checks-submission.pcre b/roles/mail/files/postfix/header-checks-submission.pcre new file mode 100644 index 0000000..8abd6bf --- /dev/null +++ b/roles/mail/files/postfix/header-checks-submission.pcre @@ -0,0 +1,35 @@ +# +# Header checks policy for mails going through the submission service +# +# See header_checks(5) +# +# Usage: +# 1. In "master.cf" set option "cleanup_service_name=subcleanup" for +# "submission" service; +# 2. set option "header_checks" for "subcleanup" service. +# +# Credits: +# * Anonymize headers in Postfix +# https://www.void.gr/kargig/blog/2013/11/24/anonymize-headers-in-postfix/ +# * Remove sensitive information from email headers with Postfix +# https://major.io/2013/04/14/remove-sensitive-information-from-email-headers-with-postfix/ +# +# +# Aaron LI +# 2017-04-21 +# + +# +# Strip sensitive information for outgoing mails +# +# NOTE: +# * Pattern maching is case insensitive. +# * First matched line will be modified. +# +#/^\s*Received:.*\(Authenticated sender:/ IGNORE +/^\s*(Received: from)[^\n]*(.*)/ REPLACE $1 [127.0.0.1] (localhost [127.0.0.1])$2 +/^\s*User-Agent/ IGNORE +/^\s*X-Enigmail/ IGNORE +/^\s*X-Forward/ IGNORE +/^\s*X-Mailer/ IGNORE +/^\s*X-Originating-IP/ IGNORE diff --git a/roles/mail/files/postfix/helo-access.pcre b/roles/mail/files/postfix/helo-access.pcre new file mode 100644 index 0000000..f678385 --- /dev/null +++ b/roles/mail/files/postfix/helo-access.pcre @@ -0,0 +1,26 @@ +# +# Postfix access control on HELO/EHLO context. +# +# References: +# * Postfix SMTP relay and access control +# http://www.postfix.org/SMTPD_ACCESS_README.html +# +# NOTE: by default, patterns are case insensitive. +# +# Aaron LI +# 2017-08-05 +# + +# +# smtpd_helo_restrictions = +# permit_mynetworks, +# check_helo_access pcre:/usr/local/etc/postfix/helo-access.pcre, +# reject_non_fqdn_helo_hostname, +# reject_invalid_helo_hostname, +# reject_unknown_helo_hostname, +# permit +# + +# Whitelist M$ Exchange Online Protection +# See also: https://technet.microsoft.com/en-us/library/dn163583 +/^.*\.outbound.protection.outlook.com$/ OK diff --git a/roles/mail/files/postfix/master.cf b/roles/mail/files/postfix/master.cf new file mode 100644 index 0000000..dc15319 --- /dev/null +++ b/roles/mail/files/postfix/master.cf @@ -0,0 +1,93 @@ +# +# /usr/local/etc/postfix/master.cf +# +# Postfix master process configuration file. +# See master(5), and http://www.postfix.org/master.5.html +# +# +# Aaron LI +# 2017-04-16 +# + +# +# NOTE: Run "postfix reload" after editing this file! +# + +# ========================================================================== +# service type private unpriv chroot wakeup maxproc command + args +# (yes) (yes) (no) (never) (100) +# ========================================================================== + +# Disable authenticiation via SMTP server port 25, force clients (MUA) to +# use the secure submission service on port 587, therefore to make sure +# that client # connections are always made using secure ciphers. +# +#smtp inet n - n - - smtpd +# -o smtpd_sasl_auth_enable=no +# +# Postscreen service and friends +smtp inet n - n - 1 postscreen + -o smtpd_sasl_auth_enable=no +smtpd pass - - n - - smtpd +dnsblog unix - - n - 0 dnsblog +tlsproxy unix - - n - 0 tlsproxy + +# Secure submission service: require user authentication +# https://wiki2.dovecot.org/HowTo/PostfixAndDovecotSASL +submission inet n - n - - smtpd + -o syslog_name=postfix/submission + -o smtpd_tls_security_level=encrypt + -o tls_preempt_cipherlist=yes + -o smtpd_sasl_auth_enable=yes + -o smtpd_reject_unlisted_recipient=no + -o smtpd_client_restrictions=permit_sasl_authenticated,reject + -o smtpd_helo_restrictions=permit_sasl_authenticated,reject + -o smtpd_sender_restrictions=reject_sender_login_mismatch + -o smtpd_recipient_restrictions=reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_sasl_authenticated,reject + -o smtpd_relay_restrictions=permit_sasl_authenticated,reject + -o milter_macro_daemon_name=ORIGINATING + -o cleanup_service_name=subcleanup + +#628 inet n - n - - qmqpd +pickup unix n - n 60 1 pickup +cleanup unix n - n - 0 cleanup +subcleanup unix n - n - 0 cleanup + -o header_checks=pcre:$config_directory/header-checks-submission.pcre +qmgr unix n - n 300 1 qmgr +#qmgr unix n - n 300 1 oqmgr +tlsmgr unix - - n 1000? 1 tlsmgr +rewrite unix - - n - - trivial-rewrite +bounce unix - - n - 0 bounce +defer unix - - n - 0 bounce +trace unix - - n - 0 bounce +verify unix - - n - 1 verify +flush unix n - n 1000? 0 flush +proxymap unix - - n - - proxymap +proxywrite unix - - n - 1 proxymap +smtp unix - - n - - smtp +relay unix - - n - - smtp +# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 +showq unix n - n - - showq +error unix - - n - - error +retry unix - - n - - error +discard unix - - n - - discard +local unix - n n - - local +virtual unix - n n - - virtual +lmtp unix - - n - - lmtp +anvil unix - - n - 1 anvil +scache unix - - n - 1 scache + +# ==================================================================== +# Interfaces to non-Postfix software. Be sure to examine the manual +# pages of the non-Postfix software to find out what options it wants. +# +# Many of the following services use the Postfix pipe(8) delivery +# agent. See the pipe(8) man page for information about ${recipient} +# and other message envelope options. +# ==================================================================== + +# Dovecot LDA as the `virtual_transport` for Postfix +# https://wiki.dovecot.org/LDA/Postfix +dovecot unix - n n - - pipe + flags=DRhu user=vmail:vmail argv=/usr/local/libexec/dovecot/deliver + -f ${sender} -d ${recipient} diff --git a/roles/mail/handlers/main.yml b/roles/mail/handlers/main.yml index e9b668e..3e97a1d 100644 --- a/roles/mail/handlers/main.yml +++ b/roles/mail/handlers/main.yml @@ -2,6 +2,9 @@ - name: reload-opendkim command: rcreload milter-opendkim +- name: reload-postfix + command: rcreload postfix + - name: reload-dovecot command: rcreload dovecot diff --git a/roles/mail/tasks/main.yml b/roles/mail/tasks/main.yml index f7163fd..ce063b3 100644 --- a/roles/mail/tasks/main.yml +++ b/roles/mail/tasks/main.yml @@ -110,6 +110,13 @@ - name: dovecot - enable and start command: rcenable dovecot + +# +# Postfix +# +# NOTE: Postfix depends on Dovecot (e.g., SASL), so setup Dovecot first. +# + - name: aliases - forward root mails lineinfile: path: /etc/mail/aliases @@ -124,6 +131,17 @@ state: link force: true +- name: postfix - disable sendmail periodic tasks + blockinfile: + path: /etc/periodic.conf + marker: "# {mark} ANSIBLE MANAGED - postfix" + block: | + # Disable sendmail(8) tasks in favor of Postfix + daily_clean_hoststat_enable="NO" + daily_status_mail_rejects_enable="NO" + daily_status_include_submit_mailq="NO" + daily_submit_queuerun="NO" + - name: postfix - enable postfix and disable sendmail blockinfile: path: /etc/rc.conf @@ -136,13 +154,31 @@ sendmail_outbound_enable="NO" sendmail_msp_queue_enable="NO" -- name: postfix - disable sendmail periodic tasks - blockinfile: - path: /etc/periodic.conf - marker: "# {mark} ANSIBLE MANAGED - postfix" - block: | - # Disable sendmail(8) tasks in favor of Postfix - daily_clean_hoststat_enable="NO" - daily_status_mail_rejects_enable="NO" - daily_status_include_submit_mailq="NO" - daily_submit_queuerun="NO" +- name: postfix - copy config files + copy: + src: "{{ item }}" + dest: /usr/local/etc/postfix/{{ item | basename }} + with_fileglob: + - "postfix/*" + notify: reload-postfix + tags: postfix + +- name: postfix - generate config files + template: + src: "{{ item }}" + dest: /usr/local/etc/postfix/{{ item | basename | regex_replace('\.j2', '') }} + with_fileglob: + - "../templates/postfix/*.j2" + notify: reload-postfix + tags: postfix + +- name: postfix - update lookup tables + command: postmap /usr/local/etc/postfix/{{ item }} + with_items: + - virtual + - virtual-users + notify: reload-postfix + tags: postfix + +- name: postfix - start service + command: rcstart postfix diff --git a/roles/mail/templates/postfix/main.cf.j2 b/roles/mail/templates/postfix/main.cf.j2 new file mode 100644 index 0000000..043fdea --- /dev/null +++ b/roles/mail/templates/postfix/main.cf.j2 @@ -0,0 +1,846 @@ +# +# /usr/local/etc/postfix/main.cf +# Postfix main configuration file, see postconf(5) for details. +# +# For best results, change no more than 2-3 parameters at a time, +# and test if Postfix still works after every change. +# +# References +# ---------- +# * Postfix Configuration Parameters +# http://www.postfix.org/postconf.5.html +# * Postfix SASL Howto +# http://www.postfix.org/SASL_README.html +# * Postfix Virtual Domain Hosting Howto +# http://www.postfix.org/VIRTUAL_README.html +# +# +# Aaron LI +# 2017-04-15 +# + +{% set mydomain = mail.domains[0] %} + +# COMPATIBILITY +# +# The compatibility_level determines what default settings Postfix +# will use for main.cf and master.cf settings. These defaults will +# change over time. +# +# To avoid breaking things, Postfix will use backwards-compatible +# default settings and log where it uses those old backwards-compatible +# default settings, until the system administrator has determined +# if any backwards-compatible default settings need to be made +# permanent in "main.cf" or "master.cf". +# +# When this review is complete, update the compatibility_level setting +# below as recommended in the RELEASE_NOTES file. +# +compatibility_level = 2 + +# SOFT BOUNCE +# +# The soft_bounce parameter provides a limited safety net for +# testing. When soft_bounce is enabled, mail will remain queued that +# would otherwise bounce. This parameter disables locally-generated +# bounces, and prevents the SMTP server from rejecting mail permanently +# (by changing 5xx replies into 4xx replies). However, soft_bounce +# is no cure for address rewriting mistakes or mail routing mistakes. +# +#soft_bounce = no + +# INTERNET HOST AND DOMAIN NAMES +# +# The myhostname parameter specifies the internet hostname of this +# mail system. The default is to use the fully-qualified domain name +# from gethostname(). $myhostname is used as a default value for many +# other configuration parameters. +# +myhostname = mail.{{ mydomain }} + +# The mydomain parameter specifies the local internet domain name. +# The default is to use $myhostname minus the first component. +# $mydomain is used as a default value for many other configuration +# parameters. +# +mydomain = {{ mydomain }} + +# SENDING MAIL +# +# The myorigin parameter specifies the domain that locally-posted +# mail appears to come from. The default is to append $myhostname, +# which is fine for small sites. If you run a domain with multiple +# machines, you should (1) change this to $mydomain and (2) set up +# a domain-wide alias database that aliases each user to +# user@that.users.mailhost. +# +# For the sake of consistency between sender and recipient addresses, +# myorigin also specifies the default domain name that is appended +# to recipient addresses that have no @domain part. +# +myorigin = $mydomain + +# SHOW SOFTWARE VERSION OR NOT +# +# The smtpd_banner parameter specifies the text that follows the 220 +# code in the SMTP server's greeting banner. +# +# You MUST specify $myhostname at the start of the text. That is an +# RFC requirement. Postfix itself does not care. +# +# NOTE: Give out as little information as possible :-) +# +smtpd_banner = $myhostname ESMTP + + +## +## RECEIVING MAIL +## + +# The inet_interfaces parameter specifies the network interface +# addresses that this mail system receives mail on. By default, +# the software claims all active interfaces on the machine. The +# parameter also controls delivery of mail to user@[ip.address]. +# +# See also the proxy_interfaces parameter, for network addresses that +# are forwarded to us via a proxy or network address translator. +# +# Note: you need to stop/start Postfix when this parameter changes. +# +inet_interfaces = all + +# The Internet protocols Postfix will attempt to use when making or +# accepting connections. 'all' for both IPv4 and IPv6. +# +inet_protocols = all + +# The mydestination parameter specifies the list of domains that this +# machine considers itself the final destination for. +# +# These domains are routed to the delivery agent specified with the +# local_transport parameter setting. By default, that is the UNIX +# compatible delivery agent that lookups all recipients in /etc/passwd +# and /etc/aliases or their equivalent. +# +# The default is $myhostname + localhost.$mydomain + localhost. +# On a mail domain gateway, you should also include $mydomain. +# +# Do not specify the names of virtual domains - those domains are +# specified elsewhere (see VIRTUAL_README). +# +# Do not specify the names of domains that this machine is backup MX +# host for. Specify those names via the relay_domains settings for +# the SMTP server, or use permit_mx_backup if you are lazy (see +# STANDARD_CONFIGURATION_README). +# +# The local machine is always the final destination for mail addressed +# to user@[the.net.work.address] of an interface that the mail system +# receives mail on (see the inet_interfaces parameter). +# +# Specify a list of host or domain names, /file/name or type:table +# patterns, separated by commas and/or whitespace. A /file/name +# pattern is replaced by its contents; a type:table is matched when +# a name matches a lookup key (the right-hand side is ignored). +# Continue long lines by starting the next line with whitespace. +# +# NOTE: If the machine is a mail server for its entire domain, then +# "$mydomain" must be listed as well. +# NOTE: In order to avoid mail delivery loops, you must list all +# hostnames of the machine, including $myhostname, and +# localhost.$mydomain +# +# WARNING: NEVER list "virtual_mailbox_domains" or "virtual_alias_domains" +# names as "mydestination" domains here! +# See also the below $virtual_mailbox_domains . +# +# NOTE: Since we will use the virtual(8) mailbox delivery agent (i.e., +# invoke "dovecot") for $mydomain, we should list $mydomain under +# $virtual_mailbox_domains instead here! +# +mydestination = $myhostname, localhost.$mydomain, localhost + + +## +## TRUST AND RELAY CONTROL +## + +# The mynetworks parameter specifies the list of "trusted" SMTP +# clients that have more privileges than "strangers". +# +# In particular, "trusted" SMTP clients are allowed to relay mail +# through Postfix. See the 'smtpd_recipient_restrictions' parameter. +# +# You can specify the list of "trusted" network addresses by hand +# or you can let Postfix do it for you (which is the default). +# +# By default (mynetworks_style = subnet), Postfix "trusts" SMTP +# clients in the same IP subnetworks as the local machine. +# +# Specify "mynetworks_style = class" when Postfix should "trust" SMTP +# clients in the same IP class A/B/C networks as the local machine. +# Don't do this with a dialup site - it would cause Postfix to "trust" +# your entire provider's network. Instead, specify an explicit +# mynetworks list by hand, as described below. +# +# Specify "mynetworks_style = host" when Postfix should "trust" +# only the local machine. +# +mynetworks_style = host + +# The relay_domains parameter restricts what destinations this system will +# relay mail to. See the smtpd_recipient_restrictions description in +# postconf(5) for detailed information. +# +# By default, Postfix relays mail +# - from "trusted" clients (IP address matches $mynetworks) to any destination, +# - from "untrusted" clients to destinations that match $relay_domains or +# subdomains thereof, except addresses with sender-specified routing. +# The default relay_domains value is $mydestination. +# +# In addition to the above, the Postfix SMTP server by default accepts mail +# that Postfix is final destination for: +# - destinations that match $inet_interfaces or $proxy_interfaces, +# - destinations that match $mydestination +# - destinations that match $virtual_alias_domains, +# - destinations that match $virtual_mailbox_domains. +# These destinations do not need to be listed in $relay_domains. +# +# Specify a list of hosts or domains, /file/name patterns or type:name +# lookup tables, separated by commas and/or whitespace. Continue +# long lines by starting the next line with whitespace. A file name +# is replaced by its contents; a type:name table is matched when a +# (parent) domain appears as lookup key. +# +# NOTE: Postfix will not automatically forward mail for domains that +# list this system as their primary or backup MX host. See the +# permit_mx_backup restriction description in postconf(5). +# +#relay_domains = $mydestination + + +## +## Mail delivery for system users +## + +# ALIAS DATABASE +# +# The alias_maps parameter specifies the list of alias databases used +# by the local delivery agent. The default list is system dependent. +# +# If you change the alias database, run "postalias /etc/aliases" +# (or wherever your system stores the mail alias file), or simply run +# "newaliases" to build the necessary DBM or DB file. +# +alias_maps = hash:/etc/mail/aliases +# +# The alias_database parameter specifies the alias database(s) that +# are built with "newaliases" or "sendmail -bi". This is a separate +# configuration parameter, because alias_maps (see above) may specify +# tables that are not necessarily all under control by Postfix. +# +alias_database = $alias_maps + +# ADDRESS EXTENSIONS (e.g., user+foo) +# +# The recipient_delimiter parameter specifies the separator between +# user names and address extensions (user+foo). See canonical(5), +# local(8), relocated(5) and virtual(5) for the effects this has on +# aliases, canonical, virtual, relocated and .forward file lookups. +# Basically, the software tries user+foo and .forward+foo before +# trying user and .forward. +# +recipient_delimiter = + + +# The mailbox_command parameter specifies the optional external +# command to use instead of mailbox delivery. The command is run as +# the recipient with proper HOME, SHELL and LOGNAME environment settings. +# Exception: delivery for root is done as $default_user. +# +# Other environment variables of interest: USER (recipient username), +# EXTENSION (address extension), DOMAIN (domain part of address), +# and LOCAL (the address localpart). +# +# Unlike other Postfix configuration parameters, the mailbox_command +# parameter is not subjected to $parameter substitutions. This is to +# make it easier to specify shell syntax. +# +# Avoid shell meta characters because they will force Postfix to run +# an expensive shell process. +# +# IF YOU USE THIS TO DELIVER MAIL SYSTEM-WIDE, YOU MUST SET UP AN +# ALIAS THAT FORWARDS MAIL FOR ROOT TO A REAL USER. +# +# See also: https://wiki.dovecot.org/LDA/Postfix +# +mailbox_command = + /usr/local/libexec/dovecot/deliver + -f "$SENDER" -a "$RECIPIENT" + + +## +## SASL authentication and authorization with Dovecot +## +## See: https://wiki2.dovecot.org/HowTo/PostfixAndDovecotSASL +## + +# Use the Dovecot SASL implementation +smtpd_sasl_type = dovecot + +# Path to the Dovecot authentication server. +# Here the path relative to the Postfix queue directory is used, +# so that it will work whether or not the Postfix SMTP server +# runs chrooted. +smtpd_sasl_path = private/auth + +# Enable SASL authentication +smtpd_sasl_auth_enable = yes + +# SMTP server policies on SASL mechanisms available to the clients. +# +# SASL mechanism properties: +# - noanonymous : don't use mechanisms that permit anonymous +# authentication (i.e., disable ANONYMOUS auth); +# - noplaintext : don't use mechanisms that transmit unencrypted +# username and password information +# (i.e., disable PLAIN auth); +# - nodictionary : don't use mechanisms that are vulnerable to +# dictionary attacks; +# - forward_secrecy : require forward secrecy between sessions (breaking +# one session does not break earlier sessions); +# - mutual_auth : use only mechanisms that authenticate both the +# client and the server to each other. +# +# NOTE: Always set at least the 'noanonymous' option! +# Otherwise, the Postfix SMTP server can give strangers the same +# authorization as a properly-authenticated client! +# +# Allows plaintext mechanisms (e.g., PLAIN, LOGIN), but only over a +# TLS-encrypted connection: +smtpd_sasl_security_options = noanonymous, noplaintext +smtpd_sasl_tls_security_options = noanonymous + +# Offer SASL authentication only after a TLS-encrypted session has +# been established. +smtpd_tls_auth_only = yes + +# The name of the Postfix SMTP server's local SASL authentication realm, +# which tells Postfix append a domain name (or any other string) to a +# SASL login name that does not have a domain part (e.g., "username" +# instead of "username@example.com"). +# This is useful as a default setting and safety net for misconfigured +# clients. +#smtpd_sasl_local_domain = $mydomain + +# Report the SASL authenticated user name in "Received:" message headers. +# NOTE: The SASL login names will be shared with the entire world. +smtpd_sasl_authenticated_header = yes + + +## +## Access control & address verification +## + +# By default, Postfix has a moderately restrictive approach to mail +# relaying. See the "smtpd_relay_restrictions" parameter for a +# description of the default mail relay policy. +# +# References: +# * Postfix SMTP Relay and Access Control +# http://www.postfix.org/SMTPD_ACCESS_README.html +# * Postfix Address Verficiation Howto +# http://www.postfix.org/ADDRESS_VERIFICATION_README.html +# * CentOS Wiki - HowTos - Postfix Restrictions +# https://wiki.centos.org/HowTos/postfix_restrictions +# + +# Example SMTP session explaining the various restrictions/checks: +#+--------------------------------------------------------------------+ +#| $ telnet <server> 25 +#| <- 220 mail.example.com ESMTP Postfix # smtpd_client_restrictions +#| -> HELO mail.example.com # smtpd_helo_restrictions +#| <- 250 mail.example.com +#| -> MAIL FROM:<sender@example.com> # smtpd_sender_restrictions +#| <- 250 2.1.0 Ok +#| -> RCPT TO:<recipient@example.com> # smtpd_recipient_restrictions +#| <- 250 2.1.5 Ok +#| -> DATA # smtpd_data_restrictions +#| <- 354 End data with <CR><LF>.<CR><LF> +#| -> To:<recipient@example.com> # header_checks +#| -> From:<sender@example.com> +#| -> Subject:SMTP test +#| -> This is a test meesage. # body_checks +#| -> . +#| <- 250 2.0.0 Ok: queued as xxxxxxxxxx +#| -> QUIT +#| <- 221 2.0.0 Bye +#+--------------------------------------------------------------------+ + +# NOTE: +# The HELO name is not related to and doesn't matter for +# 'reject_unknown_client_hostname'. Note that there are two different +# context of hostname: client (rDNS) vs. HELO (SMTP). +# The *client* hostname is determined by an rDNS lookup of the connecting +# IP. The resulting rDNS hostname is then looked up, and must resolve +# to the connecting IP. This is also referred to as "Forward Confirmed +# reverse DNS" (FCrDNS). + +# Wait until the "RCPT TO" or "ETRN" commands before evaluating the +# corresponding restriction rules. (default: yes) +# +# This allows Postfix to log recipient address information when rejecting +# a client name/address or sender address. +# +smtpd_delay_reject = yes + +# Require that the client sends the HELO/EHLO command before sending +# the MAIL FROM or TERN command, i.e., senders must identify themselves +# before we'll accept e-mail commands from them. This is important +# because we can use the way the remote server identities itself as a +# basis for accepting or rejecting mail from it --- spammers often +# don't issue proper HELO/EHLO response. +# +# NOTE: This may cause problems with home-grown clients, therefore, +# this requirement is disabled by default. +# +smtpd_helo_required = yes +# +# Restrictions that the Postfix SMTP server applies in the context of +# a client HELO command. +# +# * reject_non_fqdn_helo_hostname : reject connections if the hostname +# supplied with the HELO command is not a fully qualified domain +# name as required by the RFC guidelines. +# * reject_invalid_helo_hostname : reject connection attempts when the +# HELO hostname syntax is invalid. +# * reject_unknown_helo_hostname : reject messages if the hostname +# supplied with the helo command doesn't have either a valid DNS +# A or MX record. +# +# NOTE: set 'smtpd_helo_required=yes' to fully enforce this restriction. +# +# WARNING: +# Do note that the HELO/EHLO check that requires a valid hostname is +# going to drop legitimate mail. Yes, people running mail servers +# should know better, but there are way to many Exchange servers out +# there that will spit out a HELO line like "localhost.localdomain" +# or "SERVER1.LOCAL" or other nonsense. Therefore, maintaining a +# whitelist (which is a pain) may be necessary. In addition, the +# rejections will show up in your logs, so it's possible to enable +# the check and then see who you're blocking. +# +# WARNING: +# The 'reject_unknown_helo_hostname' policy should be used with +# *caution* as it # will reject email from legitimate systems with +# temporary DNS problems and can lead to false positives. +# +smtpd_helo_restrictions = + permit_mynetworks, + check_helo_access pcre:$config_directory/helo-access.pcre, + reject_non_fqdn_helo_hostname, + reject_invalid_helo_hostname, + warn_if_reject reject_unknown_helo_hostname, + permit + +# Relay control +# Only local clients and authenticated clients may specify any +# destination domain. +# +# WARNING: The 'reject_unauth_destination' is critically important! +# The server would be an *open relay* without this! +# +smtpd_relay_restrictions = + permit_mynetworks, + permit_sasl_authenticated, + reject_unauth_destination + +# WARNING: Recipient address verficiation may cause an increased load +# on down-stream servers in the case of a dictionary attack +# or a flood of backscatter bounces. +# +smtpd_recipient_restrictions = + reject_unknown_reverse_client_hostname, + warn_if_reject reject_unknown_client_hostname, + reject_non_fqdn_recipient, + reject_unknown_sender_domain, + reject_unknown_recipient_domain, + permit_mynetworks, + permit_sasl_authenticated, + reject_invalid_hostname, + reject_non_fqdn_sender + +# Block clients that speak too early. +# Reject the request when the client sends SMTP commands ahead of +# time where it is not allowed, or when the client sends SMTP commands +# ahead of time without knowing that Postfix actually supports ESMTP +# command pipelining. +# +smtpd_data_restrictions = reject_unauth_pipelining + +# Envelope sender address control +# +# * reject_unknown_sender_domain: +# Don't accept mail from domains that don't exist. +# * reject_sender_login_mismatch: +# Reject the sender address in the "MAIL FROM" command if +# $smtpd_sender_login_maps does not specify the SMTP client's login +# name (i.e., SASL authenticated) as an owner of that address. +# +# WARNING: Sender address verficiation may cause your site to be +# blacklisted by some providers. +# +# NOTE: +# By default an SMTP client may specify *any* envelope sender address +# in the "MAIL FROM" command, because the server only knows the remote +# client's hostname and IP address, but not the user who controls the +# remote client. +# But the Postfix SMTP server knowns who the sender is once the SASL +# authentication is used. Given a table of envelope sender addresses +# and SASL login names ($smtpd_sender_login_maps), the server can +# decide if the SASL authenticated client is allowed to use a particular +# envelope sender address. +# +smtpd_sender_restrictions = + reject_unknown_sender_domain, + reject_sender_login_mismatch + +# A lookup table maps between the envelope sender addresses and SASL +# login names (i.e., the owners). +# +smtpd_sender_login_maps = $virtual_mailbox_maps + +# Use permanet 550 errors for rejections, to stop retries. +# Tell Postfix to reject messages that match the rejection criteria +# with a 550 error, which should tell the remote server that its +# message wasn't delivered and it shouldn't try to send it again +# (as opposed to the default 450 error, which implies that the +# remote server should retry sending). +# +#unknown_address_reject_code = 550 +#unknown_client_reject_code = 550 +#unknown_hostname_reject_code = 550 + + +## +## SMTP server TLS settings +## + +# Ask remote servers to identify themselves with a certificate. +# +smtpd_tls_ask_ccert = yes + +# TLS certificate and key for this server (host) +# +smtpd_tls_cert_file = /usr/local/etc/ssl/acme/$mydomain/fullchain.pem +smtpd_tls_key_file = /usr/local/etc/ssl/acme/private/$mydomain.pem + +# A CA bundle used by Postfix to validate remote servers' certificate. +# NOTE: install package 'ca_root_nss'. +# +smtpd_tls_CAfile = /usr/local/etc/ssl/cert.pem + +# File with Diffie-Hellman parameters that the Postfix SMTP server +# should use with non-export EDH/DHE ciphers. +# +smtpd_tls_dh1024_param_file = /usr/local/etc/ssl/dhparam4096.pem + +# The minimum TLS cipher grade that the Postfix SMTP server will use +# with opportunistic TLS encryption. +# Do not use weak encryption ciphers. +# +smtpd_tls_ciphers = high + +# Enable EECDH key exchange for Forward Security +# +smtpd_tls_eecdh_grade = ultra + +# The SMTP TLS security level for the Postfix SMTP server. +# Value "may" tells Postfix that it should use SSL/TLS if the remote +# host supports it, i.e., opportunistic TLS. +# There is a stricter option ("encrypt") to force Postfix to *always* +# encrypt, but that makes your server non-compliant with IETF RFC 2487. +# +smtpd_tls_security_level = may + +# Enable additional Postfix SMTP server logging of TLS activity. +# 1 : log only a summary message on TLS handshake completion; +# no logging of client certificate trust-chain verification +# errors if client certificate verfication is not required. +# NOTE: do NOT use level 2 or higher except in case of problems. +# +smtpd_tls_loglevel = 1 + +# The SSL/TLS protocols accepted by the Postfix SMTP server with +# mandatory/opportunistic TLS encryption. +# +smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3 +smtpd_tls_protocols = !SSLv2, !SSLv3 + +# The minimum TLS cipher grade that the Postfix SMTP server will +# use with mandatory TLS encryption. +# +smtpd_tls_mandatory_ciphers = high + +# Request that the Postfix SMTp server produces "Received:" message +# headers that include information about the protocol and cipher +# used, as well as the remote SMTP client CommonName and client +# certificate issuer CommonName. +# NOTE: This is disabled by default, as the information may be modified +# in transit through other mail servers. Only information that +# was recorded by the *final destination* can be trusted. +# +smtpd_tls_received_header = yes + +# Name of the file containing the optional Postfix SMTP server TLS +# session cache. Specify a database type that supports enumeration, +# such as "btree" or "sdbm"; there is no need to support concurrent +# access. The file is created if it does not exist. +# +smtpd_tls_session_cache_database = btree:$data_directory/smtpd_scache +# +# The expiration time of Postfix SMTP server TLS session cache +# information. A cache cleanup is performed periodically every +# such time. +# +smtpd_tls_session_cache_timeout = 3600s + + +## +## Virtual domain hosting with Dovecot delivery +## + +# Postfix virtual MAILBOX: separate domains, non-UNIX accounts, +# and non-Postfix mailbox store (use $virtual_transport). +# +# With the Postfix virtual(8) mailbox delivery agent, every recipient +# address can have its own virtual mailbox. virtual mailbox domains +# ($virtual_mailbox_domains) do not need the clumsy translation from +# each recipient addresses into a different address, and owners of a +# virtual mailbox address do not need to have a UNIX system account. +# + +# Tell Postfix which domain(s) its virtual users live in. +# The specified domain(s) is also the final destination; mail is +# delivered via the $virtual_transport mail delivery transport. +# +# WARNING: NEVER list a "virtual_mailbox_domains" name as a +# "mydestination" domain above! +# +virtual_mailbox_domains = $config_directory/virtual-domains + +# Tell Postfix the virtual users for which its actually responsible +# for mail delivery. +# +virtual_mailbox_maps = hash:$config_directory/virtual-mailbox-users + +# Link alias e-mail addresses to real e-mail addresses. +# +# WARNING: NEVER put a virtual MAILBOX wild-card in the virtual +# ALIAS file!! +# +virtual_alias_maps = hash:$config_directory/virtual + +# With delivery to a non-Postfix mailbox store for hosted domains, +# the 'virtual_transport' parameter usually specifies the Postfix LMTP +# client, or the name of a "master.cf" entry that executes non-Postfix +# software via the 'pipe' delivery agent, which is responsible for the +# next-hop destination for final delivery to domains listed with +# $virtual_mailbox_domains . +# +# NOTE: Add the appropriate service definition in "master.cf" before +# restart Postfix. +# +virtual_transport = dovecot +dovecot_destination_recipient_limit = 1 + + +## +## Other settings +## + +# Do not sends "new mail" notifications to users who have requested +# new mail notification with the UNIX command "biff y". +# +biff = no + +# The maximal size of any 'local(8)' individual mailbox or maildir +# file, or zero (no limit). +mailbox_size_limit = 0 +# +# The maximal size (byte) of a message, including envelope information. +message_size_limit = 52428800 + +# The default maximal number of parallel deliveries to the same +# destination. This is the default limit for delivery via the 'lmtp(8)', +# 'pipe(8)', 'smtp(8)' and 'virtual(8)' delivery agents. +# +default_destination_concurrency_limit = 5 + +# The maximal number of parallel deliveries to the same destination +# via the relay message delivery transport. This limit is enforced +# by the queue manager. +# +relay_destination_concurrency_limit = 1 + +# Disable the SMTP "VRFY" command, which is used to verify that an email +# address exists prior to sending a message, therefore stops some +# techniques used to harvest email addresses. +# +disable_vrfy_command = yes + +# Require strictly RFC821 compliant envelopes, which requires that +# addresses received in "MAIL FROM" and "RCPT TO" commands are enclosed +# with <> and do not contain other comments or phrases, e.g., +# <user@example.com>. +# This stops mail from poorly written software (may reduce spams). +# +strict_rfc821_envelopes = yes + +# List or bit-mask of OpenSSL options to enable. +# +# * NO_COMPRESSION : disable SSL compression even if supported by +# the OpenSSL library. Compression is CPU-intensive, +# and compression before encryption does not always +# improve security. +tls_ssl_options = NO_COMPRESSION + +# The OpenSSL cipherlist for "high" grade ciphers. +# +# WARNING: you are strongly encouraged to NOT change this settings. +# +tls_high_cipherlist = EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA256:EECDH:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!IDEA:!ECDSA:kEDH:CAMELLIA128-SHA:AES12 + +# Log the hostname of a remote SMTP server that offers STARTTLS, when +# TLS is not already enabled for that server. +# +smtp_tls_note_starttls_offer = yes + +# The minimum TLS cipher grade that the Postfix SMTP client will use +# with opportunistic TLS encryption. +# Do not use weak encryption ciphers. +# +smtp_tls_ciphers = high + +# The default SMTP TLS security level for the Postfix SMTP client. +# - may : opportunistic TLS. Use TLS if this is supported by the +# remote SMTP server, otherwise use plaintext. +# - encrypt : mandatory TLS! +# +smtp_tls_security_level = may + +# Enable additional Postfix SMTP client logging of TLS activity. +# +smtp_tls_loglevel = 1 + +# The SSL/TLS protocols accepted by the Postfix SMTP client with +# mandatory/opportunistic TLS encryption. +# +smtp_tls_mandatory_protocols = !SSLv2, !SSLv3 +smtp_tls_protocols = !SSLv2, !SSLv3 + +# Name of the file containing the optional Postfix SMTP client TLS +# session cache. +# +smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache + + +## +## Mail filter (milter) settings +## + +# The default action when a Milter (mail filter) application is +# unavailable or mis-configured. +# +milter_default_action = accept + +# A list of Milter applications for new mail that arrives via the +# Postfix SMTP server. +# +# * inet:localhost:{{ mail.dkim.port }} - OpenDKIM +# +smtpd_milters = inet:localhost:{{ mail.dkim.port }} + +# A list of Milter applications for new mail that does not arrive +# via the Postfix SMTP server. +# +non_smtpd_milters = $smtpd_milters + + +## +## Postscreen and additional filtering +## +## NOTE: Enable the corresponding daemons/utilities in "master.cf". +## + +postscreen_access_list = permit_mynetworks + +# Enforce non-spammy connection behavior (and not accept connections +# from clients that try to short-circuit the process to deliver +# spam faster). +# +postscreen_greet_action = enforce + +# Enable DNS blacklist checking. +# DNSRBLs (DNS real-time black hole lists) are lists maintained +# by various entities, some companies, and some individuals, filled +# with IP addresses and ranges from which the list maintainer +# believes spam has originated. +# +postscreen_dnsbl_action = enforce +# +# Increase the DNS lookup timeout for the configured local recursive +# resolver by "unbound". +# Default: 10s +# +postscreen_dnsbl_timeout = 30s +# +# Lists: +# * zen.spamhaus.org +# * bl.spamcop.net +# * b.barracudacentral.org +# +# NOTE: +# The "b.barracudacentral.org" RBL requires registration! +# To test the access to this RBL: +# $ host 2.0.0.127.b.barracudacentral.org +# If nothing returns, then access not granted to the used DNS, and +# registration is required. +# It seems that this RBL do not accept IPv6 address registration! +# See: http://www.barracudacentral.org/rbl/how-to-use +# +# Credit: https://serverfault.com/a/14256 +# +# Useful tools: +# * Spam Database Lookup: http://www.dnsbl.info/ +# +postscreen_dnsbl_sites = + zen.spamhaus.org, + bl.spamcop.net + + +## +## DEBUGGING CONTROL +## + +# The debug_peer_level parameter specifies the increment in verbose +# logging level when an SMTP client or server host name or address +# matches a pattern in the debug_peer_list parameter. +# +debug_peer_level = 2 + +# The debugger_command specifies the external command that is executed +# when a Postfix daemon program is run with the -D option. +# +# Use "command .. & sleep 5" so that the debugger can attach before +# the process marches on. If you use an X-based debugger, be sure to +# set up your XAUTHORITY environment variable before starting Postfix. +# +# If you can't use X, use this to capture the call stack when a +# daemon crashes. The result is in a file in the configuration +# directory, and is named after the process name and the process ID. +# +debugger_command = + PATH=/bin:/usr/bin:/usr/local/bin; export PATH; (echo cont; + echo where) | gdb $daemon_directory/$process_name $process_id 2>&1 + >$config_directory/$process_name.$process_id.log & sleep 5 + +# vim: set ft=pfmain: diff --git a/roles/mail/templates/postfix/virtual-domains.j2 b/roles/mail/templates/postfix/virtual-domains.j2 new file mode 100644 index 0000000..3997d1b --- /dev/null +++ b/roles/mail/templates/postfix/virtual-domains.j2 @@ -0,0 +1,14 @@ +# +# /usr/local/etc/postfix/virtual-domains +# Postfix: $virtual_mailbox_domains +# +# The list of domains for which Postfix is the final destination, +# i.e., the (virtual) domains hosted. +# +# Aaron LI +# 2018-03-05 +# + +{% for domain in mail.domains %} +{{ domain }} +{% endfor %} diff --git a/roles/mail/templates/postfix/virtual-users.j2 b/roles/mail/templates/postfix/virtual-users.j2 new file mode 100644 index 0000000..4de0a60 --- /dev/null +++ b/roles/mail/templates/postfix/virtual-users.j2 @@ -0,0 +1,46 @@ +# +# /usr/local/etc/postfix/virtual-users +# Postfix: $virtual_mailbox_maps +# +# Tell Postfix the virtual users for which its actually responsible +# for mail delivery. +# +# References: +# * Postfix SASL HOWTO - Envelope sender address authorization +# http://www.postfix.org/SASL_README.html#server_sasl_authz +# +# Aaron LI +# + +#======# +# NOTE # Once modified this file, run "postmap" on it! +#======# + +# NOTE +# ---- +# Make sure to have two columns, since this file will be used to map +# e-mail addresses to allowed SASL-authenticated accounts --- in other +# words, one of the things we're defining here is that when you +# authenticate to Dovecot as "you@yourdomain.com," Postfix knows that +# you're allowed to send e-mail from the "you@yourdomain.com" e-mail +# address. +# +# NOTE +# ---- +# By default an SMTP client may specify *any* envelope sender address +# in the "MAIL FROM" command, because the server only knows the remote +# client's hostname and IP address, but not the user who controls the +# remote client. +# But the Postfix SMTP server knowns who the sender is once the SASL +# authentication is used. This table file provides the maps betwee +# envelope sender addresses and SASL login names, which is used by the +# server to decide if the SASL authenticated client is allowed to use +# a particular envelope sender address. +# + +# Envelope sender | Owner (SASL login names) +# --------------------------------------------------------------------- +{% set mydomain = mail.domains[0] %} +{% for user in ["aly", "wt", "lulu", "root"] %} +{{ user }}@{{ mydomain }} {{ user }}@{{ mydomain }} +{% endfor %} diff --git a/roles/mail/templates/postfix/virtual.j2 b/roles/mail/templates/postfix/virtual.j2 new file mode 100644 index 0000000..191d38d --- /dev/null +++ b/roles/mail/templates/postfix/virtual.j2 @@ -0,0 +1,45 @@ +# +# /usr/local/etc/postfix/virtual +# Postfix: $virtual_alias_maps +# +# Link alias e-mail addresses to real e-mail addresses. +# +# Aaron LI +# + +#======# +# NOTE # Once modified this file, run "postmap" on it! +#======# + +# NOTE +# ---- +# Virtual alias domains are used for forwading email from an email +# address to one or more other email addresses. They cannot receive +# and save email, but only forward email somewhere else. +# The $virtual_alias_maps mapping contains forwarding (source, +# destination) of users or domains to other email addresses or entire +# domains. This maps can return multiple right-hand side +# destinations (to forward to) for one left-hand side source, therefore +# one can forward copies of an email to several recipients. +# +# Credit: https://workaround.org/ispmail/wheezy/virtual-domains +# + +# alias mail address | local address for virtual(8) delivery +# --------------------------------------------------------------------- +{% set mydomain = mail.domains[0] %} +{% for domain in mail.domains %} +{% for user in ["aly", "wt", "lulu"] %} +{{ user }}@{{ domain }} {{ user }}@{{ mydomain }} +{% endfor %} +{% endfor %} +# +{% for domain in mail.domains %} +weitian@{{ domain }} wt@{{ mydomain }} +{% endfor %} +# +{% for domain in mail.domains %} +{% for user in ["postmaster", "hostmaster", "webmaster", "root", "abuse"] %} +{{ user }}@{{ domain }} root@{{ mydomain }} +{% endfor %} +{% endfor %} |