1

Making sure postfix isn't an open relay, I tried to send a mail from my mail address towards my mail address, the telnet log goes like this:

Resolving hostname...
Connecting...
SMTP -> FROM SERVER:
220 mail.example.com ESMTP Postfix
SMTP -> FROM SERVER: 
250-mail.example.com
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
MAIL FROM: braiam@example.com
SMTP -> FROM SERVER:
250 2.1.0 Ok
RCPT TO: braiam@example.com
SMTP -> FROM SERVER:
250 2.1.5 Ok
Sending Mail Message Body...
SMTP -> FROM SERVER:
354 End data with .
SMTP -> FROM SERVER:
250 2.0.0 Ok: queued as XXXXXXXX
Message completed successfully.

The non-defaults on my main.cf

postconf -n
alias_database = hash:/etc/aliases
alias_maps = hash:/etc/aliases
append_dot_mydomain = no
biff = no
config_directory = /etc/postfix
inet_interfaces = all
inet_protocols = all
lmtp_tls_mandatory_protocols = !SSLv2, !SSLv3
lmtp_tls_protocols = !SSLv2, !SSLv3
mailbox_size_limit = 0
mydestination = $myhostname, localhost.$mydomain, localhost
mydomain = example.com
myhostname = mail.$mydomain
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
myorigin = $mydomain
non_smtpd_milters = inet:127.0.0.1:8891
policy-spf_time_limit = 3600s
readme_directory = no
recipient_delimiter = +
relayhost =
smtp_generic_maps = hash:/etc/postfix/generic
smtp_tls_ciphers = medium
smtp_tls_exclude_ciphers = EXPORT, LOW, MD5, aDSS, kECDHe, kECDHr, kDHd, kDHr, SEED, IDEA, RC2
smtp_tls_loglevel = 1
smtp_tls_mandatory_protocols = !SSLv2,!SSLv3
smtp_tls_protocols = !SSLv2,!SSLv3
smtp_tls_security_level = may
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_banner = $myhostname ESMTP $mail_name
smtpd_client_connection_rate_limit = 5
smtpd_delay_reject = yes
smtpd_helo_required = yes
smtpd_milters = inet:127.0.0.1:8891
smtpd_recipient_restrictions = reject_invalid_hostname, reject_non_fqdn_hostname, reject_non_fqdn_sender, reject_non_fqdn_recipient, reject_unknown_sender_domain, reject_unauth_destination, reject_unverified_recipient, permit_mynetworks, check_recipient_access pcre:/etc/postfix/recipient_checks.pcre, check_helo_access hash:/etc/postfix/helo_checks, check_policy_service unix:private/policy-spf, reject_rbl_client cbl.abuseat.org, reject_rbl_client sbl.spamhaus.org, reject_rbl_client pbl.spamhaus.org, check_sender_access hash:/etc/postfix/check_backscatterer permit
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated reject_unauth_destination
smtpd_sasl_auth_enable = yes
smtpd_sasl_path = private/auth
smtpd_sasl_security_options = noanonymous,noplaintext
smtpd_sasl_tls_security_options = noanonymous
smtpd_sasl_type = dovecot
smtpd_sender_login_maps = hash:/etc/postfix/virtual/mailboxes
smtpd_tls_auth_only = yes
smtpd_tls_cert_file = /etc/letsencrypt/live/example.com/fullchain.pem
smtpd_tls_ciphers = medium
smtpd_tls_dh1024_param_file = ${config_directory}/dh2048.pem
smtpd_tls_eecdh_grade = strong
smtpd_tls_exclude_ciphers = EXPORT, LOW, MD5, SEED, IDEA, RC2
smtpd_tls_key_file = /etc/letsencrypt/live/example.com/privkey.pem
smtpd_tls_loglevel = 1
smtpd_tls_mandatory_ciphers = high
smtpd_tls_mandatory_protocols = !SSLv2,!SSLv3
smtpd_tls_protocols = !SSLv2,!SSLv3
smtpd_tls_security_level = may
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
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:AES128-SHA
tls_ssl_options = NO_COMPRESSION
tlsproxy_tls_mandatory_protocols = $smtpd_tls_mandatory_protocols
tlsproxy_tls_protocols = $smtpd_tls_protocols
virtual_alias_maps = hash:/etc/postfix/virtual/aliases
virtual_mailbox_domains = example.com
virtual_mailbox_maps = hash:/etc/postfix/virtual/mailboxes
virtual_transport = lmtp:unix:private/dovecot-lmtp

Checking the message headers I see a SPF fail:

Return-Path: <braiam@example.com>
Delivered-To: <braiam@example.com>
Received: from mail.example.com
    by compute.internal (Dovecot) with LMTP id XXXXXXXXXXX
    for <braiam@example.com>; Fri, 08 Apr 2016 01:56:03 +0000
Received-SPF: Fail (SPF fail - not authorized) identity=mailfrom; client-ip=184.72.226.23; helo=www.wormly.com; envelope-from=braiam@example.com; receiver=braiam@example.com 
Received: from www.wormly.com (node-mec2.wormly.com [184.72.226.23])
    by mail.example.com (Postfix) with ESMTP id 1234567890
    for <braiam@example.com>; Fri,  8 Apr 2016 01:56:02 +0000 (UTC)
Date: Fri, 08 Apr 2016 01:56:03 +0000
From: braiam@example.com
To: braiam@example.com

Why is this? Isn't postfix supposed to check before receiving emails using the smptd_recipient_restrictions?

migrated from serverfault.com Apr 14 '16 at 18:35

This question came from our site for system and network administrators.

  • 1
    smtpd_relay_restrictions seems like it's set to warn not fail. Researching – coteyr Apr 19 '16 at 22:12
  • 1
    from howtoforge.com/postfix_spf "If the message is not rejected or deferred, the policy server will PREPEND the appropriate SPF Received header. In the case of multi-recipient mail, multiple headers will get appended." Most notably if the connection passed one of the permit filters already I don't think your check will stop it. – coteyr Apr 19 '16 at 22:21
  • @coteyr I'm not sure why relay restrictions would play if the the RCPT: is from my own managed domain. – Braiam Apr 20 '16 at 2:43
2
+50

Postfix itself checks neither of SPF, DKIM, nor DMARC. It relies on external services to do so. In the above config, the SPF check is performed by a service listening on the private/policy-spf socket. If messages should be rejected on SPF failures, this behavior must be configured in the respective policy service.

There exist Perl and Python implementations for this policy serivce, so the details may differ. With the python implementation, setting the parameters

HELO_reject = SPF_Not_Pass 
Mail_From_reject = fail

in /etc/postfix-policyd-spf-python/policyd-spf.conf should cause instant rejection of messages with SPF mismatches. Otherwise the service will just add a header and accept the message regardless. The latter behavior can be useful if the authentication result is used by another service (see e.g. this article by Skelleton, describing how to setup an OpenDMARC milter).

The DKIM authenticator (I'm guessing that's the milter listed in above conf) would have to be configured, too.

Aside: It's not the case in your example, but it should be noted that the SPF policy check will not be executed if any of the recipient checks listed before the SPF policy check returns OK. So if one was to send mail from the localhost, the SPF check would never be performed.

  • This is what I was trying to say, you have to set it up to reject not just append the header, and that is done in the service config. – coteyr Apr 19 '16 at 22:24
  • You might also be interested in zeitmail, a project aimed at people who want to quickly set up a secure mail server via saltstack. It's alpha-quality, but already quite usable. Disclaimer: I'm the main author. – tarleb Apr 19 '16 at 22:28
  • This was indeed what was happening. Notice that I make no mention of DKIM, just DMARC. – Braiam Apr 20 '16 at 2:44

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.