On Sat, Nov 06, 2021 at 11:38:26PM -0500, Tyler Montney <montneyty...@gmail.com> wrote:
> Sorry for the long delay, wanted to do more research before posting it. > I've replaced some real values, like myhostname, with generic ones. I expect it's all fine or you would have had a response by now. I'll have a look and make comments, but be warned that I might easily misunderstand something and say something dumb. So don't take it too seriously. > postconf -nf > > command_directory = /usr/sbin You seem to be explicitly setting many parameters to their defaults. That's harmless but unnecessary. > content_filter = smtp-amavis:[127.0.0.1]:10024 With a content filter, you want to only do address mappings before or after the filter, not both. You have the address mappings happening before, which means that the filter doesn't have access to the original addresses. It only has access to the mapped addresses. That might be want you want. You have suppressed address mappings after the filter by having this in master.cf for the 127.0.0.1:10025 service: receive_override_options=no_header_body_checks,no_unknown_recipient_checks,no_address_mappings If you'd prefer to make the original addresses available to the content filter, you could instead have "receive_override_options = no_address_mappings" in main.cf and remove "no_address_mappings" from master.cf. Both ways are fine. However, I think you might want to add "no_milters" to the receive_override_options parameter in master.cf. Otherwise, the milters will probably run both before and after the filter. It's unlikely that that's what you want (but it might be - I don't know what the milter on port 11332 is doing). > header_checks = regexp:/etc/postfix/header_checks > mime_header_checks = regexp:/etc/postfix/header_checks If you have pcre available (it's a separate package on Debian), you might want to use that instead of regexp because pcre is faster. > inet_interfaces = 192.168.0.3, 127.0.0.1 This probably isn't needed unless there are other IP addresses that you want to exclude. > inet_protocols = ipv4 This probably isn't needed unless you have IPv6 but don't want to use it. > message_size_limit = 52428800 > virtual_mailbox_limit = 5242880000 message_size_limit needs to be less than or equal to virtual_mailbox_limit. Your virtual_mailbox_limit is 100 times message_size_limit. So that's fine, but they could also be equal. I don't know if there's a reason for virtual_mailbox_limit to be so much larger than message_size_limit. > milter_default_action = accept > milter_mail_macros = i {mail_addr} {client_addr} {client_name} {auth_authen} I don't know enough to comment sensibly on this. The only milters I use are opendkim and opendmarc, and I leave milter_mail_macros at it's default value. But even if the milter on port 11332 needs the addition of {client_addr} {client_name}, there's probably no reason to remove {auth_type} {auth_author} {mail_host}. But I expect that you understand this much better than I do, so ignore the above. :-) > mydestination = localhost.$mydomain, localhost > myhostname = mail.foo.com > mailbox_transport = lmtp:unix:private/dovecot-lmtp Removing $myhostname from mydestination looks unusual to me. I assume there's a good reason, but since you have local delivery (using lmtp and dovecot in mailbox_transport), it seems odd that the mail server's hostname can't be used in an email address for the local users. I assume that you just want locally originating email for local users, and you want that local email to be delivered to a dovecot mailbox. So it's probably all fine. > smtp_tls_mandatory_protocols = >=TLSv1.2 > smtp_tls_protocols = >=TLSv1.2 This can lead to your mail server transmitting email unencrypted if the receiving server doesn't support TLSv1.2 but does support TLSv1.0 or TLSv1.1. That doesn't really do anyone any favours. Remember that SMTP encryption is opportunistic. If you are too fussy, you get nothing. SSLv2 and SSLv3 should be excluded because they are broken, but TLSv1.0 and TLSv1.1 are still OK to use for mail (even though they are deprecated). Even if you have some security theatre requirements not to accept TLSv1.0 on your mail server, that is achieved with the smtpd_ equivalents of these parameters (below). As far as I am aware, nothing scans which protocols are supported by your server for outgoing mail. > smtp_tls_security_level = may This is fine, but you might be able to do better. If your mail server runs a local DNSSEC-validating name resolver (e.g., Bind9 or Unbound), then you could make Postfix DANE-aware and avoid falling prey to man-in-the-middle attacks when sending mail to remote SMTP servers that implement DANE. To do this, your /etc/resolv.conf would need to look something like this: nameserver 127.0.0.1 options trust-ad (with no other nameserver entries), and then you would replace "smtp_tls_security_level = may" in main.cf with: smtp_dns_support_level = dnssec smtp_tls_security_level = dane When sending mail to servers that don't implement DANE, this is the same as "may". > smtpd_discard_ehlo_keywords = chunking You might want to add "silent-discard" to the above to suppress warnings in your log files about it. > smtpd_helo_required = yes > smtpd_helo_restrictions = check_helo_access hash:/etc/postfix/helo, > reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, > reject_unknown_helo_hostname, permit > smtpd_milters = local:opendkim/opendkim.sock, > local:opendmarc/opendmarc.sock, > inet:127.0.0.1:11332 > smtpd_proxy_options = speed_adjust > smtpd_recipient_restrictions = reject_non_fqdn_recipient, > reject_non_fqdn_sender, reject_unknown_sender_domain, > reject_unknown_recipient_domain, reject_unauth_pipelining, > permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, > check_recipient_access hash:/etc/postfix/specialaccounts, > reject_multi_recipient_bounce, reject_unknown_client_hostname, > check_policy_service inet:127.0.0.1:10023, reject_rhsbl_helo > dbl.spamhaus.org, reject_rhsbl_reverse_client dbl.spamhaus.org, > reject_rhsbl_sender dbl.spamhaus.org, reject_rbl_client zen.spamhaus.org, > permit This looks fine. I assume port 10023 is running Postgrey. Postgrey is great. > smtpd_sasl_auth_enable = yes > smtpd_sasl_local_domain = foo.mylocal > smtpd_sasl_path = private/auth > smtpd_sasl_security_options = noanonymous > smtpd_sasl_type = dovecot smtpd_sasl_auth_enable shouldn't be in main.cf. Having it here means that port 25 offers authentication. It's better to remove it from main.cf, and add it to the submission service in master.cf. You can leave the other smtpd_sasl_ parameters here in main.cf, or move them as well, whichever you prefer. It might not really matter. It just means that people that want to bombard your server with brute force authentication attempts have to do it on port 587 rather than port 25, but it's generally recommended on this mailing list not to support authentication on port 25. But if you can restrict access to port 587 to known non-mobile clients, then it might make a difference. If you can't do that, you can limit brute force authentication attempts with something like this: smtpd_client_auth_rate_limit = 10 That limits authentication attempts (successful or not) to that many every $anvil_rate_time_unit (default: 60s). > smtpd_tls_cert_file = > /etc/letsencrypt/live/mail.foo.com/fullchain.pem > smtpd_tls_key_file = /etc/letsencrypt/live/mail.foo.com/privkey.pem It's better to use the new smtpd_tls_chain_files parameter rather than smtpd_tls_cert_file and smtpd_tls_key_file. But it's better still if you can also set up a certbot renewal hook to combine the privkey.pem and fullchain.pem files into a single file every time it renews the certificate. That way, you eliminate the chance of a race condition when Postfix reads the new key and chain. For example, if you set up a renewal hook that executes a script like this: #!/bin/sh -e # Postfix recommends a single file, containing both the private key # and the certificate chain, as that makes it possible to rollover # keys atomically and avoid race conditions. # See http://www.postfix.org/TLS_README.html # This needs to run automatically when the LetsEncrypt certificate is renewed. # Note: a Postfix reload is not required after this. # Note: this puts the file in $RENEWED_LINEAGE (i.e., /etc/letsencrypt/live/CERTNAME) # so that multiple lineages for the same domain can coexist. This is needed for use # with danectl(1). When using danectl, refer to /etc/letsencrypt/current rather # than /etc/letsencrypt/live in main.cf. [ -n "$RENEWED_LINEAGE" -a -d "$RENEWED_LINEAGE" ] || exit 1 cd "$RENEWED_LINEAGE" chain=privkey-then-fullchain-for-postfix.pem umask 077 touch $chain.tmp chmod 600 $chain.tmp cat privkey.pem fullchain.pem > $chain.tmp mv $chain.tmp $chain chmod 600 $chain Then you can wait for the next certificate renewal and then put this in main.cf: smtpd_tls_chain_files = /etc/letsencrypt/live/mail.foo.com/privkey-then-fullchain-for-postfix.pem > smtpd_tls_mandatory_protocols = >=TLSv1.2 > smtpd_tls_protocols = >=TLSv1.2 See the above note for the smtp_ versions of these parameters. > postconf -Mf > > smtp inet n - y - - smtpd > dovecot unix - n n - - pipe flags=DRhu > user=vmail:mail argv=/usr/lib/dovecot/dovecot-lda -f ${sender} -d > ${recipient} > submission inet n - y - - smtpd > -o syslog_name=postfix/submission > -o smtpd_tls_security_level=encrypt > -o smtpd_relay_restrictions=permit_sasl_authenticated,reject > -o content_filter=smtp-amavis:[127.0.0.1]:10026 I didn't realise you had a separate Amavis service running for authenticated users when I mentioned receive_override_options earlier. I think the same would apply here. > pickup unix n - y 60 1 pickup > cleanup unix n - y - 0 cleanup > qmgr unix n - n 300 1 qmgr > tlsmgr unix - - y 1000? 1 tlsmgr > rewrite unix - - y - - trivial-rewrite > bounce unix - - y - 0 bounce > defer unix - - y - 0 bounce > trace unix - - y - 0 bounce > verify unix - - y - 1 verify > flush unix n - y 1000? 0 flush > proxymap unix - - n - - proxymap > proxywrite unix - - n - 1 proxymap > smtp unix - - y - - smtp > relay unix - - y - - smtp > -o syslog_name=postfix/$service_name > showq unix n - y - - showq > error unix - - y - - error > retry unix - - y - - error > discard unix - - y - - discard > local unix - n n - - local > virtual unix - n n - - virtual > lmtp unix - - y - - lmtp > anvil unix - - y - 1 anvil > scache unix - - y - 1 scache > postlog unix-dgram n - n - 1 postlogd > smtp-amavis unix - - n - 2 smtp > -o syslog_name=postfix/amavis > -o smtp_data_done_timeout=1200 > -o smtp_send_xforward_command=yes > -o disable_dns_lookups=yes It's best not to disable_dns_lookups. The Amavis guide says to do it, but the Postfix documentation says to ignore old guides that say to do it (See http://www.postfix.org/postconf.5.html#smtp_dns_support_level). > -o max_use=20 > -o smtp_tls_security_level=none This is probably unnecessary. The amavis smtp client probably doesn't offer STARTTLS. > 127.0.0.1:10025 inet n - n - - smtpd > -o syslog_name=postfix/10025 > -o content_filter= > -o mynetworks_style=host This is the default and wasn't modified in main.cf. It could be removed. > -o mynetworks=127.0.0.0/8 I don't think that this isn't needed since it's only listening on 127.0.0.1 anyway, but I think you might need: -o smtpd_authorized_xforward_hosts=127.0.0.0/8 > -o local_recipient_maps= > -o relay_recipient_maps= These are the default and weren't modified in main.cf. It could be removed. > -o strict_rfc821_envelopes=yes It might make more sense to move this to main.cf to have an effect for all mail when it first arrives. > -o smtp_tls_security_level=none > -o smtpd_tls_security_level=none These probably aren't needed. > -o smtpd_restriction_classes= This is the default and wasn't modified in main.cf. It could be removed. > -o smtpd_delay_reject=no This is harmless because you aren't using any restrictions that could be broken by it, but it also probably doesn't do any good. Not delaying rejections makes more sense when the client is a remote mail client, not Amavis running locally. At least, I think so. But I could be wrong. > -o smtpd_client_restrictions=permit_mynetworks,reject This could probably be removed since it's the default, wasn't modified in main.cf, and smtpd_recipient_restrictions (below) does the same thing. But it does no harm. > -o smtpd_sender_restrictions= This is the default and wasn't modified in main.cf. It could be removed. > -o smtpd_recipient_restrictions=permit_mynetworks,reject Yep. > -o smtpd_end_of_data_restrictions= This is the default and wasn't modified in main.cf. It could be removed. > -o smtpd_error_sleep_time=0 > -o smtpd_soft_error_limit=1001 > -o smtpd_hard_error_limit=1000 > -o smtpd_client_connection_count_limit=0 > -o smtpd_client_connection_rate_limit=0 Yep. > -o > receive_override_options=no_header_body_checks,no_unknown_recipient_checks,no_address_mappings See comments above about probably wanting to add "no_milters" to the above, and possibly wanting to move "no_address_mappings" from here to main.cf. Having said all that, I think it all looks fine and workable, except that "no_milters" should probably be added to "receive_override_options" in master.cf, to prevent milters running twice. Am I mistaken about that? It's possible. One other thing. Since you are using OpenDKIM and OpenDMARC, you might also want to add SPF checking (for domains that use SPF but not DMARC). For example, on Debian, install the postfix-policyd-spf-perl package (there's also a Python alternative), and add this to master.cf: # SPF check policy service (https://www.linuxbabe.com/mail-server/setting-up-dkim-and-spf) spfcheck unix - n n - 0 spawn user=policyd-spf argv=/usr/sbin/postfix-policyd-spf-perl And add this to smtpd_recipient_restrictions in main.cf: check_policy_service unix:private/spfcheck cheers, raf > On Sun, Oct 17, 2021 at 6:25 PM raf <post...@raf.org> wrote: > > > On Fri, Oct 15, 2021 at 12:20:55PM -0500, Tyler Montney < > > montneyty...@gmail.com> wrote: > > > > > One other thing while I wait... > > > > > > Once I'm done researching (in a week or two), I'd like someone to > > provide a > > > sanity check on my Postfix config by posting it here. Is that allowed? > > > > Sure. When you're ready, post the output of "postconf -nf" and "postconf > > -Mf". > > > > cheers, > > raf > > > >