4

Until recently my server with Postfix has worked well. Then I enforced some restrictions to a) combat spam b) disable sending emails to me on behalf on my own name -- I have begun receiving emails from my own email address demanding to send bitcoin to someone.

I want to fix both a and b.

And now I can't send email via my own postfix server.

  Client host rejected: cannot find your reverse hostname, [<my ip here>]

Note that I carry my laptot to different places and countries, and connect to WiFi from those. And I want to be able to send email always.

Here's a part of my config of Postfix. For database of the accounts and domains I use Postgresql.

smtpd_helo_required = yes

smtpd_client_restrictions =
  permit_mynetworks,
  permit_sasl_authenticated,
  reject_unknown_reverse_client_hostname,

  reject_unknown_client_hostname,
  reject_unauth_pipelining

smtpd_helo_restrictions =
  permit_mynetworks,
  permit_sasl_authenticated,
  reject_invalid_helo_hostname,

###  reject_non_fqdn_helo_hostname,
  reject_unauth_pipelining

smtpd_sender_restrictions =
  permit_mynetworks,
  reject_sender_login_mismatch,
  permit_sasl_authenticated,
  reject_non_fqdn_sender,
  reject_unknown_sender_domain,
  reject_unauth_pipelining

smtpd_relay_restrictions =
  permit_mynetworks,
  permit_sasl_authenticated,
  reject_non_fqdn_recipient,
  reject_unknown_recipient_domain,

  reject_unauth_destination


smtpd_recipient_restrictions =
  permit_mynetworks,
  permit_sasl_authenticated,
  reject_non_fqdn_recipient,
  reject_unknown_recipient_domain,
  reject_unauth_pipelining

smtpd_data_restrictions =
  permit_mynetworks,
  permit_sasl_authenticated,
  reject_multi_recipient_bounce,
  reject_unauth_pipelining

# deliver mail for virtual users to Dovecot's LMTP socket
virtual_transport = lmtp:unix:private/dovecot-lmtp

#  query to find which domains we accept mail for
virtual_mailbox_domains = pgsql:/etc/postfix/virtual_mailbox_domains.cf

# query to find which email addresses we accept mail for
virtual_mailbox_maps = pgsql:/etc/postfix/virtual_mailbox_maps.cf

# query to find a user's email aliases
virtual_alias_maps = pgsql:/etc/postfix/virtual_alias_maps.cf

virtual_alias_domains = 
alias_database = 
alias_maps = 

mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
inet_interfaces = all
  • 1
    You won't be able to send email from most places with those restriction unless you configure pre-authentication to send emails or create a VPN. – Rui F Ribeiro Nov 3 '18 at 19:06
  • @RuiFRibeiro what do you mean by pre-authentication? It's used -- I have to provide my email/password – nylypej Nov 3 '18 at 23:12
5

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.

Email Header Diagram

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:

  1. Sender Policy Framework (SPF)
  2. Domain Keys Identified Mail (DKIM)
  3. 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.

  • Simple SPF explanation:

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

  • Simple DKIM explanation:

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:webmaster@domain.tld;ruf=mailto:webmaster@domain.tld;

_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.

  1. Stop the postfix and dovecot services.
  2. Stop the web server, if one is running.
  3. Stop any service running that is currently included on the certificate.
  4. 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.

  1. 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=<dlh@xxx.xxx.cq.cnt> to=<gogo@xxxx.com.tw> 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

  1. DMARC/SPF Policy Evaluator
  2. DKIM Public Key Evaluator
  3. MxToolbox Website
  4. Email Security Grader
  • what's example.com REJECT Only I am me? what's dns.host.ip.addr REJECT Only I am me? – nylypej Nov 3 '18 at 23:15
  • have you taken into account that I travel with my laptop and connect to wifi and send email from different places and countries? – nylypej Nov 3 '18 at 23:16
  • @nylypej ... The laptop to email server connection is handled by Dovecot... not postfix... I can adjust my answer for a fairly complete configuration... however, I highly recommend installing LetsEncrypt and obtaining a DV TLS certificate that covers your mail server's IMAP and or POP3 connection. – RubberStamp Nov 3 '18 at 23:58
  • 1) Why do you assume that LetsEncrypt isn't installed? 2) The laptop to email server connection is handled by Dovecot... not postfix --> you're wrong – nylypej Nov 4 '18 at 1:22
  • "example.com" is your domain ---> which domain? I have tens of domains served by postfix and all of them are mine – nylypej Nov 4 '18 at 1:24
3

Use different restriction for the submission interface (MSA - mail submission agent) on port 587, for example (excerpt of master.cf):

submission inet n       -       -       -       -       smtpd
  -o smtpd_enforce_tls=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
  -o smtpd_sender_restrictions=reject_authenticated_sender_login_mismatch
  -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject

It forces STARTTLS and enables sending only after authentication, this is the easiest way. You can also use a VPN or similar as proposed in the comments and whitelist your IP/ranges with this method.

Using different ports for MSA (port 587) and MTA (Mail Transport Agent, ports 25, 465) is recommended as you will need different settings for both of them.

This is a minimal example, extend it to your needs.

  • It forces STARTTLS and enables sending only after authentication, -- I'm required to provide login and password now, how is this not authentication? – nylypej Nov 3 '18 at 23:57
  • The snippet I posted requires the user to first use the correct port for submission, then use starttls, and then authenticate. For non-submission ports starttls can't be enforced and authentication should not be allowed. With the config you posted you can't receive any mails for other servers, as they would need to authenticate, but they can't obviously. – sebix Nov 4 '18 at 15:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.