Short Answer
Your postfix
configuration is unnecessarily complex. It seems likely that some of the restrictions placed in your configuration either negate one another or are so restrictive that you may need to ssh
into your server and manually send each outgoing mail.
Rather than go through the posted configuration, this answer will provide an overview of what is generally required to configure a reasonably safe email system for most purposes. It's not intended to be an exhaustive tutorial on how to configure each component. However, there is a list of online resources at the end which I have found to be rather helpful and valuable in configuring my own email servers.
There are a few extra requirements from your comments which will not be addressed, such as handling multiple domains using a single postfix
installation. It is assumed that a reasonably adept administrator will be able to tweak the settings and add the necessary multi-domain configuration elements.
Overview of Elements for Modern Small Email Service Providers
Graphical View of Security and Reputation Related Email Headers
Modern email systems have evolved to include many security and domain related reputation elements. Perhaps the easiest way to begin is looking at a diagram of some of the more important newer elements contained in an email's header.
Protecting a Domain from Spoof Attempts and Reputation Problems
There are three essential components to configure for ensuring the authenticity of email traffic that seems to originate from a domain.
These are:
- Sender Policy Framework (SPF)
- Domain Keys Identified Mail (DKIM)
- Domain-based Message Authentication Reporting & Conformance (DMARC)
Each of these has a daemon running on the server as well as DNS records for connecting servers in order to automate checking of domain policies and verifying cryptographic signatures.
Postfix passes outgoing email through the SPF daemon which evaluates whether or not the sender matches the outgoing mail policy. The receiving mail server retrieves the domain's SPF record from DNS and checks the record against the SPF header the sending server placed on the email.
postfix compatible SPF implementation
Postfix passes outgoing email through the DKIM daemon which automatically signs the message and includes a hash of the message in the email headers. The receiving mail server retrieves the domain's DKIM public key from a DNS record and verifies the body hash of the message.
postfix compatible DKIM implementation
- Simple DMARC explanation:
The receiving mail server retrieves the DMARC policy record from DNS and accepts or rejects the message or performs a soft fail of the message.
postfix compatible DMARC implementation
It is considered Best Security Practices to enter a "reject" DMARC policy record even if your domain is not sending any email.
Example of DNS entries for SPF, DKIM, and DMARC
MX 10 mail.domain.tld.
TXT "v=spf1 a:mail.domain.tld -all"
mail._domainkey IN TXT ( "v=DKIM1; h=sha256; k=rsa; "
"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0w7N0fWtTndtlR+zOTbHyZOlvFiM73gyjjbHDN1OhhcPCbhRUqTsA7A8uXHGHao6nZ5qejlVtn6NfZwbn7rdhJ0MTjlgTnTsVa8E9rgS6dFo0bEIzeFecDr/4XOF9wpNjhHlnHm4wllkPheFnAWpZQiElZeYDN5Md47W1onwZ3DwcYJNX/3/GtfVZ0PrjisC4P0qeu+Z8jIgZc"
"MLvBm8gj2pX3V6ntJY9QY09fWSVskvC6BQhi6ESOrqbM63f8ZJ4N/9ixPAMiD6k/lyGCokqc6sMuP6EC7z5McEOBbAVEuNy3idKi1sjwQH8WZHrvlSBlzx1wwmpFC1gqWcdTiEGwIDAQAB" ) ; ----- DKIM key mail for domain
_dmarc IN TXT v=DMARC1;p=reject;sp=reject;fo=0:d;adkim=s;aspf=s;rua=mailto:[email protected];ruf=mailto:[email protected];
_domainkey IN TXT o=-;
You may notice that the DNS record named mail._domainkey
contains a cryptographic public key. This key and associated record can be generated using the opendkim-genkey
program installed when the opendkim
package installed on your server.
Key generation is rather simple:
opendkim-genkey -b 2048 -d yourdomain -h sha256 -s mail
This command will generate a private key, public key, and correctly formatted DNS record. The private key needs to be placed in the directory listed in your opendkim configuration. While the public key and its associated DNS record is placed in your domain's DNS zone file. Unfortunately, some DNS providers have length restrictions on records. So, make sure your DNS provider can accommodate the public key's length.
Adding SPF and DKIM Milters
SPF
Excerpt from the policyd-spf
man page:
POSTFIX INTEGRATION
1. Add the following to /etc/postfix/master.cf:
policyd-spf unix - n n - 0 spawn
user=policyd-spf argv=/usr/bin/policyd-spf
2. Configure the Postfix policy service in /etc/postfix/main.cf:
smtpd_recipient_restrictions =
...
reject_unauth_destination
check_policy_service unix:private/policyd-spf
...
policyd-spf_time_limit = 3600
DKIM
The opendkim
daemon runs on a UNIX socket which is configurable either as a standard UNIX socket or running on an inetd
service port. On my Debian installations, this configuration is located at /etc/default/opendkim
. Once opendkim
is running, the milter needs to be added to the postfix
configuration in /etc/postfix/main.cf
.
Here's an example from a working server:
# DKIM
milter_default_action = accept
milter_protocol = 2
smtpd_milters = inet:localhost:8891
DMARC
For small or personal email servers, DMARC can be simply limited to the DNS record. The DMARC checking daemon allows for rejecting incoming mail per sending domain's policy as well as sending any requested reporting back to the sending domain. The reporting is considered being "well-behaved neighbors". However, I generally don't enable it for small or personal systems since the configuration overhead is quite high.
The DMARC DNS record, however, is very important to maintain domain reputation. The record is used by all modern large email providers to accept or reject mails that seem to originate from your domain. So, without the DMARC record, all incoming mail that looks like it was sent by your domain gets counted toward your domain's reputation score. Thus, a domain that doesn't expect to send any mail at all should publish a "reject" DMARC record to avoid reputation problems from spoofed messages sent by spammers.
TLS Connections for Email Servers and Clients
Your configuration information indicates you are running Dovecot and Postfix.
Dovecot connects with Postfix on your server. In many small installations, the server connection is performed on the same physical/logical hardware through Unix sockets.
So, the Mail User Agent (MUA) connection is handled by the middleware and not the actual mail server. In your case, that would be Dovecot.
TLS should be enabled and setup properly in Dovecot in order to securely transmit your username and password from your MUA (ex: Evolution, Sylpheed, Mutt, etc).
For reference, see Dovecot's TLS setup documentation.
It's possible, but not necessary for the "server-to-server" or "middleware" to postfix connection be encrypted by the same TLS certificate. However, in the case of a small email server, the "middleware" to postfix connection doesn't necessarily need to be encrypted since it's on the same hardware.
Obtaining a LetsEncrypt TLS Certificate for your Mail Server and MUA interface (POP3, IMAP, etc)
The LetsEncrypt project has done a very good job simplifying obtaining Domain Validated TLS certificates. Assuming your domain already has a certificate, you can add the mail server's sub-domain to the certificate using the --expand
option.
- Stop the postfix and dovecot services.
- Stop the web server, if one is running.
- Stop any service running that is currently included on the certificate.
- Expand the certificate
certbot certonly --expand -d domain.tld,www.domain.tld,mail.domain.tld
Then add the certificate path to your main.cf
configuration.
smtpd_tls_key_file = /etc/letsencrypt/live/domain.tld/privkey.pem
smtpd_tls_cert_file = /etc/letsencrypt/live/domain.tld/fullchain.pem
And also add the certificate path to your Dovecot configuration, per Dovecot's documentation listed above.
- Restart all services and check that the configuration works.
It should be noted that SMTP TLS connection is the connection your server makes with other servers. While, the Dovecot TLS connection is generally what someone would connect to in order to send email from a non-webmail client.
SMTP Server to Server TLS Compatibility Setting
Some mail servers are still not utilizing TLS encrypted connections for mails received from other servers. In such cases, strict TLS enforcement will result in undeliverable mail to those servers and domains. However, many large email providers will mark an incoming email as suspicious if the connection is not secured with TLS. So, in order to maintain the best compatibility include the following setting in your /etc/postfix/main.cf
smtpd_tls_security_level = may
It's also important to note that most email providers do not require this server to server connection to use a CA approved certificate and validation checks are generally not performed even if the certificate is CA approved.
However, the TLS certificate included in Dovecot should be CA approved. A self-signed certificate in Dovecot will result in a warning when using most MUAs such as sylpheed
, evolution
, or thunderbird
.
Reasonable SMTP Client Restrictions
In my experience, 99% of spam can be rejected via SPF, DKIM checking along with RBL checking.
Here's a portion of my "standard" client restrictions. It's important to note that the restrictions are processed in order. The order I have below works very well in my experience:
smtpd_client_restrictions = permit_mynetworks
permit_sasl_authenticated
check_helo_access hash:/etc/postfix/helo_access
check_client_access hash:/etc/postfix/client_checks
reject_unauth_destination
check_policy_service unix:private/policy-spf
reject_rbl_client cbl.abuseat.org
reject_rbl_client pbl.spamhaus.org
reject_rbl_client sbl.spamhaus.org
reject_rbl_client bl.blocklist.de
reject_unknown_client
SMTPD Client Restrictions Compatibility Setting
The restriction that will have the most exceptions will be the reject_unknown_client
setting. Many online services do not configure their reverse domain correctly and/or utilize a series of sending domains which may or may not be mapped properly. So, for the most compatibility with poorly configured email providers, remove that restriction.
However, nearly 100% of spam is sent from email servers without proper reverse domain records.
HELO Checks
It's common for spammers to attempt to spoof a HELO by sending your domain's name or IP address, or localhost. These spoof attempts can be rejected immediately using the check_helo_access
option as shown above. The HELO text database consists of a domain name or IP address or IP address range followed by the action and a message to send back.
A fairly simple HELO check follows:
# helo access
# check_helo_access hash:/etc/postfix/helo_access
localhost REJECT Only I am me
127.0.0.1 REJECT Only I am me
example.com REJECT Only I am me
dns.host.ip.addr REJECT Only I am me
"example.com" is your domain, and "dns.host.ip.addr" is your server's DNS listed IP address.
This database example results in something like this from one my actual server logs:
Oct 30 06:32:49 <domain> postfix/smtpd[22915]: NOQUEUE: reject: RCPT from xxx-161-xxx-132.dynamic-ip.xxxx.net[xxx.161.xxx.132]: 554 5.7.1 <xxx.xxx.xxx.xxx>: Helo command rejected: Only I am me; from=<[email protected]> to=<[email protected]> proto=SMTP helo=<xxx.xxx.xxx.xxx>
The potential spammer/spoofer gets the message "Only I am me". It doesn't matter what the message is, but at least the spammer/spoofer knows you know.
Make sure to generate the postfix
database using:
postmap helo_access
Adding Exceptions to the Restrictions via a client_check whitelist
Individual client checking goes something like this:
ip.addr.hack.attmpt REJECT
misconfig.server.but.good OK
Make sure to generate the postfix
database using:
postmap client_checks
And that's about it. I get about 3 spam mails a month, with hundreds of spam rejected.
Resources
- DMARC/SPF Policy Evaluator
- DKIM Public Key Evaluator
- MxToolbox Website
- Email Security Grader