Office365 SMTP Relay Information

From Michael's Information Zone
Revision as of 18:08, 10 September 2019 by Michael.mast (talk | contribs) (→‎Postfix)
Jump to navigation Jump to search

This has been a struggle. If you want an internal mail server, without public DNS entries, to send mail to a domain in Office 365 your stuck. The following needed to be accomplished:

  1. Allow printers to scan to email securely
  2. Allow servers to send reports via email
  3. Specify any From address I wanted.
  4. Without the need to add additional public DNS entries.

Really I just wanted to log into the server and masquerade all day long. Think about it, why would I want to create an inbox for an account that will only send? Of course you would need to pay for additional licensing but that is not what we want to do.

I got as far as configuring postfix to send email as a user, but this meant that every email I sent would be shown as coming from THAT user (or any other user that user has send on behalf as). Some of this is legitimate security but in the end it's just a pain for something that requires simple authentication.

[1][2][3][4][5][6][7][8][9][10][11][12]

Docker

WIP

Decided to work off what someone else already did. This is not as easy as I thought it would be, and this config ended up working well for me [13]
Please note that I have several pull requests submitted to update the base scripts, some of the following modifications may not be needed in the future.

Internal Only Relay

  • Initial build
git clone https://github.com/juanluisbaptiste/docker-postfix.git
cd docker-postfix/
sed "s/Set\ needed\ config\ options/&\npostconf\ \-e\ \'mynetworks\ \=\ 10\.0\.0\.0\/8\,\ 172\.16\.0\.0\/12\,\ 192\.168\.0\.0\/16\'/" run.sh
sudo docker build -t localpostfix -f Dockerfile .
  • Starting
docker run --name postfix -e SMTP_SERVER=smtp.office365.com -e SMTP_USERNAME=user@domain.tld -e SMTP_PASSWORD=password -e SERVER_HOSTNAME=relay.domain.tld -d -p 25:25 localpostfix

Externally Accessible Relay

For this one, I had already pulled a letsencrypt certificate using another container.

  • Pull the files needed
git clone https://github.com/juanluisbaptiste/docker-postfix.git
cd docker-postfix/
  • Edit run.sh to add authentication
##Check if TLS is used
if [ ! -z "${TLS_AUTH}" ]; then
[ -z "${USER_NAME}" ] && echo "Specify USER_NAME variable" && exit 1
[ -z "${PASSWORD}" ] && echo "Specify a PASSWORD" && exit 1
useradd ${USER_NAME}
echo -e "${PASSWORD}\n${PASSWORD}" | passwd ${USER_NAME}
postconf -e "smtpd_sasl_auth_enable = yes"
postconf -e "smtpd_sasl_security_options = noanonymous"
postconf -e 'smtpd_sasl_local_domain = $myhostname'
postconf -e "broken_sasl_auth_clients = yes"
postconf -e "smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, check_relay_domains"
postconf -e "smtpd_tls_cert_file = /etc/letsencrypt/live/relay.domain.tld/fullchain.pem"
postconf -e "smtpd_tls_key_file = /etc/letsencrypt/live/relay.domain.tld/privkey.pem"
postconf -e "smtp_tls_security_level = may"
postconf -e "smtpd_tls_security_level = encrypt"
postconf -e "smtp_tls_note_starttls_offer = yes"
postconf -e "smtpd_tls_loglevel = 1"
postconf -e "smtpd_tls_received_header = yes"
fi
  • Edit Dockerfile so letsencrypt is installed, and to have the letsencrypt directory you prepared in advance copied into the container. ie
...
RUN yum install -y epel-release && yum update -y && \
    yum install -y cyrus-sasl cyrus-sasl-plain cyrus-sasl-md5 mailx \
    perl supervisor postfix rsyslog \
    letsencrypt \
...

COPY letsencrypt /etc/letsencrypt
  • Build image
docker build -t postfixtls -f Dockerfile .

Postfix

[14] Make sure to remove sendmail then install postfix and mailx. (don't forget about cyrus-sasl
For the postfix configuration I added the following to the main.cf file

relayhost = [smtp.office365.com]:587
smtp_use_tls = yes
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_tls_CAfile = /etc/ssl/certs/ca-bundle.crt
smtp_sasl_security_options = noanonymous
smtp_sasl_tls_security_options = noanonymous

I then created the auth file mapping using the following format

echo [smtp.office365.com]:587 user@domain.tld:password > /etc/postfix/sasl_passwd
postmap /etc/postfix/sasl_passwd

Then, when I would send the test message, I would specify the sender as being the one listed in the sasl_passwd file

echo "Test Message" | mail -r user@domain.tld -s "Test Subject" michael@domain.tld && tail -f /var/log/maillog

Then I received mail. After much reading I found that people would either build additional mail servers or use something like Amazon's Simple Email Service (https://aws.amazon.com/ses/). Considering I have a lot to do I would just rather let Amazon handle the heavy lifting and move on with my life.

Rewrite sender address

[15] For a simple relay that can only send using one address (i.e. O365) you can perform the steps in two ways.

  1. [16]Generic rewriting will rewrite a matched string for the entire message. Sender and receiver is impacted.
  • Add strings to /etc/postfix/generic (or whatever file you want)
@domain.tld office365@yourdomain.tld
wrong@anotherdomain.tld office365@yourdomain.tld
  • Run postmap /etc/postfix/generic
  • Add entry into /etc/postfix/main with the following "smtp_generic_maps = hash:/etc/postfix/generic"
  1. [17]If you have the same sender and recipient then you would want to process just
  • Add strings to /etc/postfix/canonical (or whatever file you want)
@domain.tld office365@yourdomain.tld
wrong@anotherdomain.tld office365@yourdomain.tld
  • Run postmap /etc/postfix/canonical
  • Add entry into /etc/postfix/main with the following "sender_canonical_maps = hash:/etc/postfix/canonical"

Spam Filtering

[18]