Graph and PowerShell Blog | About | Links
Advanced Postfix Config
17-Jun-24

Postfix Articles
  • Adding a Postfix server for relay to O365
  • Advanced Postfix configuration
  • Postfix routing by filtering
  • Postfix Receive and Forward

  • Having setup Postfix recently I found the process very straightforward, with a lot of options for configuration. Deciding to dig a bit deeper I looked at the following advanced settings:

  • Full certificate chain
  • Adding DKIM to outgoing mails
  • Allow Internet access through web proxy
  • Setup remote access with PowerShell
  • Apps that can't relay off Postfix


  • Full Certificate Chain
    Most articles you see for setting up your certificate to encrypt emails would point you to having the following config:

    smtp_tls_key_file = /etc/ssl/private.key
    smtp_tls_cert_file = /etc/ssl/relay_cert.cer
    smtp_tls_CAfile = /etc/ssl/inter_cert.cer

    This has been deprecated by Postfix, and you should now use a certificate chain. This means you include your private key, cert, intermediate cert, and if needed your root cert all under one file.

    While not difficult to setup, you need to be careful to get the certs/keys in the correct order, otherwise, it simply won't work.

    smtp_tls_chain_files = /etc/postfix/chain.pem
    smtpd_tls_chain_files = /etc/postfix/chain.pem

    .pem order
    Private Key
    Cert
    Intermediate Cert
    Root Cert (if needed)



    Adding DKIM to Outgoing Mails
    When you relay mails into Office365 via a connector your mail is still subject to DMARC checks. So the first step will probably be to add the public IP of the relay server so that the SPF check will pass.

    Depending on how your DMARC record is setup, that may be enough. But what if your DMARC also requires DKIM to pass, or you just want the extra security of DKIM? OpenDKIM has this covered, the steps to install and configure are:

  • Install via bash: apt-get install opendkim opendkim-tools
  • Generate private key: opendkim-genkey -t -s prelay -d domain.com
  • Copy private key to /etc/Postfix/dkim.key
  • Set opendkim as owner of key file: chown opendkim:opendkim /etc/postfix/dkim.key
  • Also copy the generated DNS record file to the Postfix directory for easy editing
  • Set /etc/opendkim.conf file (see below)
  • Add DKIM entries to /etc/Postfix/main.cf in Postfix (see below)
  • Create DKIM record in DNS

  • Troubleshooting
  • Check file permissions on key file: ls -la /etc/postfix/dkim.key
  • View log file: journalctl -u opendkim -o short-iso
  • Restart service: service opendkim reload
  • Install DNS tools: sudo apt-get install dnsutils
  • Check DNS record with DIG: dig -t txt relay._domainkey.domain.com

  • /etc/opendkim.config
    ====================
    Domain domain.com
    KeyFile /etc/postfix/dkim.key
    Selector relay
    SOCKET inet:8891@localhost
    * There is some debate if SOCKET should be set under /etc/default/opendkim, but this seems to have been there for legacy reasons and is no longer needed.

    /etc/postfix/main.cf
    ====================
    milter_default_action = accept
    milter_protocol = 6
    smtpd_milters = inet:localhost:8891
    non_smtpd_milters = inet:localhost:8891

    ↑ Usually there are three lines of text in double quotes, remove the line breaks and quotes before adding the DNS TXT record. The t=y is for testing and can be removed.

    If you have a transport rule in Exchange that adds a disclaimer to all external mails, then you will want to exclude the Postfix mails (exclude by IP) in order not to break the DKIM body.



    Allow Internet access through web proxy
    If your internet access is via an authenticated proxy then you will need to add your credentials in 2 places:

    General: sudo nano ~/.bashrc
    ============================
    proxy_http=username:password@proxy-server-ip:port
    proxy_https=username:password@proxy-server-ip:port

    Proxy for APT: /etc/apt/apt.conf
    ===============================
    Acquire::http::Proxy "http://[username]:[password]@ [proxy-web-or-IP-address]:[port-number]";
    Acquire::https::Proxy "http://[username]:[password]@ [proxy-web-or-IP-address]:[port-number]";

    Also, settings can be stored in the following locations:
    /etc/wgetrc
    ~/.wgetrc

    * Don't put wget proxy settings in double-quotes.

    If you don't want to worry about password changes then I would suggest setting up a service account in Active Directory and setting the password to never expire.



    Setup remote access with PowerShell
    When setting up Postfix I decided to have a separate log file just from Postfix instead of going into the more general Mail.log. While this is set in the Postfix settings it doesn't control things like the date format, which still comes from the system itself (systemd).

    In Ubuntu 24.04 the default logs are accessed via journalctl, and not the popular rsyslog. Via bash you can use '-output short-iso' to set the date format to ISO, but this will not change the settings for the postfix.log file.

    While I could have spent more time on this I decided to go with what I know and setup remote PowerShell. With this, I could archive the logs daily and parse the log with tools that I already know.

    I won't go into all of the details but having an auth key from the Windows server helps greatly with scripting. A combination of Bash command and PowerShell tools gives lots of options to work with.

    PowerShell on Ubuntu
    ====================
    sudo dpkg --install --ignore-depends=libicu72 powershell_7.4.2-1.deb_amd64.deb # currently there is a compatibility issue so install with this command

    /etc/ssh/sshd_config
    ====================
    Subsystem powershell /opt/microsoft/powershell/7/pwsh -SSHS -NoProfile -NoLogo
    PasswordAuthentication yes



    Apps that can't relay off Postfix
    When migrating the apps from Exchange to Postfix I didn't expect there to be any issues, despite some of the apps being nearly 20 years old. When moving an Alcatel Voicemail server I found the following error in the log:

    /var/logs/postfix.log
    =====================
    improper command pipelining after CONNECT from myserver.domain.local

    While I can't be certain, the most likely cause is a recent vulnerability called SMTP Smuggling. To allow the server to relay you could try the following setting:

    etc/postfix/main.cf
    ===================
    smtpd_forbid_unauth_pipelining = no

    But in my case, I didn't want to reduce the security of Postfix, and as the server will be retired in a few months, I decided to install SMTP Server on IIS.

    It's no longer officially supported by Microsoft, but it is easy to configure. Probably a little worrying that there is no protection against SMTP Smuggling, though it will only be used internally.