On Fri, Dec 23, 2022 at 06:58:17PM +0400, Samer Afach <samer.af...@msn.com>
wrote:
Dear postfix experts:
I think I'm getting to the end of this problem. I was able to use haproxy to
relay connections to my docker container with correct source information
(and I'm seeing the correct IP addresses in the logs of postfix/dovecot). I
would appreciate it if you could take a look at my settings before going
public and changing the MX records back to this server.
How I tested: I was actively blocking/unblocking firewalls,
starting/stopping containers (start, test, stop), and in every step, I ran
swaks, with one of these configurations (in fact, I'm planning to automate
these tests and run them periodically, what a nice tool this turned out to
be):
swaks --to a...@example.com --from=b...@example.com --server
mail.example.com:587
--tls
swaks --to a...@example.com --from=b...@example.com --server
mail.example.com:465
--tlsc
swaks --to a...@example.com --from=b...@example.com --server mail.example.com:25
--tls
swaks --to a...@example.com --from=b...@example.com --server mail.example.com:25
I was consistently getting the result "Access denied" in swaks, which I hope
means that no relaying is possible anymore. Meanwhile, I succeeded in
sending messages with Thunderbird with proper authentication.
Email relaying was only possible when sending emails with swaks through
localhost (even though it's going through the proxy in localhost), i.e.:
swaks --to a...@example.com --from=b...@example.com --server 127.0.0.1:587 --tls
swaks --to a...@example.com --from=b...@example.com --server 127.0.0.1:465
--tlsc
swaks --to a...@example.com --from=b...@example.com --server 127.0.0.1:25 --tls
swaks --to a...@example.com --from=b...@example.com --server 127.0.0.1:25
Does this constitute proof that relaying isn't possible anymore?
It looks good. You can also employ and external
testing site such as mxtoolbox.com which includes an
open relay test (enter the hostname, click "MX Lookup",
then click "SMTP Test"). This would require that the
HAproxy address and a hostname is publically available
(even if it isn't yet pointed to by any MX record).
There are three components to the configuration I added for this, each for
one port:
I have a few unimportant but informative suggestions below.
1. Port 25
in master.cf:
```
10024 inet n - n - 1 postscreen
smtpd pass - - n - - smtpd
```
and in main.cf:
```
postscreen_upstream_proxy_protocol = haproxy
```
2. Port 587 for strict STARTTLS:
```
10587 inet n - n - - smtpd
-o syslog_name=postfix/haproxy_submission
-o smtpd_tls_security_level=encrypt
-o smtpd_tls_wrappermode=no
smtpd_tls_wrappermode=no is the default and so isn't needed.
It only needs to be set (to yes) for port 465.
-o smtpd_enforce_tls=yes
smtpd_enforce_tls=yes is redundant with smtpd_tls_security_level=encrypt.
It's the obsolete equivalent, and so it's ignored when
smtpd_tls_security_level is present.
-o smtpd_sasl_auth_enable=yes
-o
smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
You probably don't want permit_mynetworks in the above.
"permit_sasl_authenticated,reject" is enough.
-o
smtpd_client_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
Again, permit_mynetworks isn't needed above.
-o smtpd_upstream_proxy_protocol=haproxy
```
3. Port 465 for strict wrapper mode:
```
10465 inet n - n - - smtpd
-o syslog_name=postfix/haproxy_smtps
-o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes
-o
smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
-o
smtpd_client_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
You probably don't need smtpd_client_restrictions since
smtpd_recipient_restrictions
has identical restrictions, and permit_mynetworks isn't needed (SASL is
necessary
and sufficient).
-o smtpd_upstream_proxy_protocol=haproxy
```
The other standard ports (25, 465 and 587) without proxying are unreachable
from the outside.
And finally, `postconf -n` (I fixed the issues indicated in the email chain
after having read their documentation):
```
alias_database = hash:/etc/aliases
alias_maps = hash:/etc/aliases
append_dot_mydomain = no
biff = no
broken_sasl_auth_clients = yes
debug_peer_level = 6
debug_peer_list = 0.0.0.0/0
disable_vrfy_command = yes
inet_interfaces = all
inet_protocols = ipv4
mailbox_size_limit = 0
maillog_file = /dev/stdout
message_size_limit = 0
milter_default_action = accept
milter_protocol = 2
mydestination = localhost
myhostname = example.com
mynetworks_style = subnet
myorigin = localmail.example.com
non_smtpd_milters = inet:docker-email-opendkim:12301
postscreen_upstream_proxy_protocol = haproxy
proxy_read_maps = $local_recipient_maps $mydestination $virtual_alias_maps
$virtual_alias_domains $virtual_mailbox_maps $virtual_mailbox_domains
$relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps
$recipient_canonical_maps $relocated_maps $transport_maps $mynetworks
$smtpd_sender_login_maps
readme_directory = no
recipient_delimiter = +
relay_domains =
relayhost =
smtp_tls_cert_file = /shared-keys/mail.example.com/fullchain.pem
smtp_tls_key_file = /shared-keys/mail.example.com/privkey.pem
The above two parameters should probably be renoved.
Specifying a particular key for outgoing TLS connections
is only important when connecting to specific remote
servers that require your server to use a specific
known key. That doesn't look to be the case here.
Usually, you only need to specify the cert/key files
for the smtpd_ versions of these parameters. See below
for comments on those.
smtp_tls_loglevel = 1
smtp_tls_mandatory_protocols = !SSLv2,!SSLv3,!TLSv1,!TLSv1.1
smtp_tls_protocols = !SSLv2,!SSLv3,!TLSv1,!TLSv1.1
The above parameter isn't needed (and maybe the one
above it too). TLSv1 and TLSv1.1 are better than no
encryption at all. And these settings are for outgoing
connections. So even if your mail server is scanned as
part of a naive cookie-cutter security assessment, the
scanner won't know that you are willing to use those
deprecated protocols for sending mail, and so won't
complain. If you don't exclude TLSv1 and TLSv1.1 in the
similar smtpd_tls_protocols parameter, such a scanner
would complain, even though it's still better than no
encryption. Security scanners usually assume that
policies that should apply to a web server (using
mandatory encryption) should also apply to a mail
server (using opportunistic encryption).
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
smtpd_client_restrictions = permit_mynetworks, reject
smtpd_helo_restrictions = reject_invalid_helo_hostname,
smtpd_milters = inet:docker-email-opendkim:12301
smtpd_recipient_restrictions = check_sender_access
hash:/etc/postfix/sender_access, permit_sasl_authenticated,
permit_mynetworks, reject_unauth_destination, reject_invalid_hostname,
reject_unknown_recipient_domain, reject_unauth_destination,
reject_rbl_client sbl.spamhaus.org, reject_rbl_client
b.barracudacentral.org, reject_rbl_client zen.spamhaus.org,
reject_rbl_client truncate.gbudb.net, reject_rbl_client bl.spamcop.net,
reject_rbl_client cbl.abuseat.org, permit
In smtpd_recipient_restrictions, permit_mynetworks usually appears
before permit_sasl_authenticated, but that might not matter.
It has reject_unauth_destination twice.
I could be wrong but I think zen.spamhaus.org subsumes sbl.spamhaus.org
so sbl.spamhaus.org can be removed (but I'm not 100% sure of that).
smtpd_relay_restrictions = permit_sasl_authenticated permit_mynetworks
reject_unauth_destination
smtpd_relay_restrictions = permit_sasl_authenticated permit_mynetworks
reject_unauth_destination
You have smtpd_relay_restrictions appearing twice.
I'm surprised that that happened with postconf -n.
And permit_mynetworks usually appears before permit_sasl_authenticated.
But note that SASL authentication won't happen over port 25 anyway.
Maybe these references to permit_sasl_authenticated shouldn't appear
in main.cf at all (i.e. only in master.cf when permit_sasl_authenticated
is set to yes).
smtpd_sasl_auth_enable = yes
The above should be removed. Enabling SASL on port 25
just encourages brute force authentication attempts.
Such attempts will happen on ports 587 and 465 anyway,
but there's no need to encourage them on port 25 as
well.
smtpd_sasl_authenticated_header = yes
smtpd_sasl_path = /shared-socks/auth_dovecot
smtpd_sasl_type = dovecot
smtpd_sender_login_maps =
proxy:mysql:/etc/postfix/mysql_sender_login_maps.cf
smtpd_tls_auth_only = yes
smtpd_tls_ciphers = high
smtpd_tls_cert_file = /shared-keys/mail.example.com/fullchain.pem
smtpd_tls_key_file = /shared-keys/mail.example.com/privkey.pem
It's not super important but it would be better to
replace the above two parameters with
smtpd_tls_chain_files referring to a single file that
contains the contents of privkey.pem followed by the
contents of fullchain.pem. If the contents of these
files change on a regular schedule (such as via
LetsEncrypt), then you'd need to automate the creation
of such a file whenever the two source files change.
The benefit of doing this is that it eliminates the
slight chance of a race condition while the files are
being updated and Postfix might read the old version of
one file and the new version of the other file.
smtpd_tls_mandatory_protocols = !SSLv2,!SSLv3,!TLSv1,!TLSv1.1
smtpd_tls_protocols = !SSLv2,!SSLv3,!TLSv1,!TLSv1.1
See the note above about the smtp_ versions of the above two.
smtpd_tls_security_level = may
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
The above parameter isn't needed anymore (since Postfix 2.11).
It should be removed.
smtpd_use_tls = yes
The above is obsolete/redundant when smtpd_tls_security_level is set.
virtual_alias_maps = proxy:mysql:/etc/postfix/mysql_virtual_alias_maps.cf
virtual_gid_maps = static:5000
virtual_mailbox_base = /var/vmail/
virtual_mailbox_domains =
proxy:mysql:/etc/postfix/mysql_virtual_domains_maps.cf
virtual_mailbox_limit = 0
virtual_mailbox_maps =
proxy:mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
virtual_minimum_uid = 104
virtual_transport = lmtp:inet:docker-email-dovecot:10024
virtual_uid_maps = static:5000
```
I would really appreciate your input on this. Have a great day.
Cheers,
Sam
cheers,
raf