Setup Exim4 with Gmail Send-Only

Exim4 can use Gmail to send its email under masked local recipient using Gmail's SMTP interface. This way, one does not need to manually setup an email exchange server just to send out some system-level information. This section guides you on how to setup Gmail Send-Only SMTP interface for Exim4.

NOTE: This section assumed you had installed Exim4 inside your operating system as instructed in the Exim4 main page guide. If you haven't, please visit: Exim4.

NOTE: Keep in mind that Gmail has a send limit specified here: https://support.google.com/mail/answer/22839?hl=en to combat spamming. Hence, please ensure you operate within the limitations.

IMPORTANT NOTE: Using Gmail exposes local machine sensitive data to Google. Please make sure you're comfortable to let Google read these data before implementing.

Understand How Enveloped Recipient Email Works

Before we start, you must understand that email recipients field can be "enveloped" as specified in RFC5322 Section 3.6.6. Since your local machine has its own server and you're using Gmail account to send out the email, there is a conflicting domain name like "@gmail.com". If we re-write the email, we cannot tell which email is this for.

So, to perform optimally, one can envelopes the "To" recipient to the local domain while having BCC to the actual email address. One example would be as such:

Bcc: hollowaykeanho@gmail.com
Return-Path: <cory.galyna@gmail.com>
Received: from holloway-seraphim ([2001:e68:542d:aef1:8e16:45ff:feb5:99b9])
        by smtp.gmail.com with ESMTPSA id i128sm8395585pfc.149.2020.05.04.02.28.37
        for <hollowaykeanho@gmail.com>
        (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
        Mon, 04 May 2020 02:28:38 -0700 (PDT)
From: cory.galyna@gmail.com
X-Google-Original-From: hollowaykeanho@gmail.com
Received: from root by holloway-seraphim with local (Exim 4.92) (envelope-from <hollowaykeanho@gmail.com>) id 1jVXOt-0004JX-Qc for root@holloway-seraphim; Mon, 04 May 2020 17:28:35 +0800
Subject: Root message
To: <root@holloway-seraphim>
X-Mailer: mail (GNU Mailutils 3.5)
Message-Id: <E1jVXOt-0004JX-Qc@holloway-seraphim>
Date: Mon, 04 May 2020 17:28:35 +0800

Root are you there?

Notice that the email was enveloped and sent to root account into my holloway-seraphim machine. Then Exim4 sent the email from cory.galyna@gmail.com and BCC it to hollowaykeanho@gmail.com. This is the kind of email that Exim4 will send to its intended recipient.

When enveloping an email, one must not provide a domain compliant email as shown above:

  1. "holloway-seraphim" is a hostname of the machine which is sufficient for identification and,
  2. not "holloway-seraphim.local" or "holloway-seraphim.com" etc.

If you provide a domain compliant name, Gmail will try to send to those addresses and of course, bounces back for no such service provider.

In this guide, we will setup the integrated gmail account: cory.galyna@gmail.com to send to the final admin located in hollowaykeanho@gmail.com, via root@holloway-seraphim in local address.

Configure Exim4

To start configuring Exim4, you must use root account to perform the following:

$ dpkg-reconfigure exim4-config

From this point out, please be extra careful to teach Exim4 about your configurations. The menu can be different from others and they may or may not be in sequence. You should search for that option.

Select Mail Sent by Smarthost; No Local Mail

When prompted to set server configuration type, you select "mail sent by smarthost; no local mail". This will set Exim4 to send email only and will not perform any receiving.

Use Local Hostname as Local Domain

When prompted for local FQDN name, to avoid Gmail getting silly by sending email to your enveloped local domain (that does not exist), you should supply your hostname instead of a domain name. This hostname should be the same as /etc/hostname. This hostname is for you as the final email recipient to know which local machine is sending you the email using that Gmail account. This is the one that is responsible for the "To" field in the email.

Based on the example below:

  • emailing to root account (root) will be enveloped as: root@holloway-seraphim

Set Local IP for Incoming Email Fetching

When prompted to listen for incoming SMTP connections, you should strictly set it to localhost IP address only. That means:

127.0.0.1 ; ::1

This is because we do not want Exim4 to download and store email from Gmail into the system where user will likely going to check them via Webmail or some MUA+MDA integrated email client such as Thunderbird or Icedove. The lesser the access point the better.

Setting to local IP is mainly due to some daemon services like logcheck will send service-level email to administrator automatically. Hence, Exim4 is required to fetch those emails from these services.

Other Local Domain Names

When prompted for local domains other destinations, this is to tell Exim4 that there are other possible permutations for the local domain names. Hence, please fill all other permutations in it. How it works is that should the local machine sent email, it will be re-write into the final destination address set earlier in "system mail name" above. If you have none, you can leave it blank or re-enter the "system mail name" you had entered earlier.

For example, based on the example below and our "system mail name" is "holloway-seraphim", say we sent email via Exim4 to:

  • root@holloway-seraphim --convert to--> root@holloway-seraphim
  • root@holloway-seraphim.seraphim.local --convert to--> root@holloway-seraphim
  • root@seraphim-local --convert to--> root@holloway-seraphim

Local Domain Mask

When prompted for local domain masking (visible domain name), you can either leave it blank or use the "system mail name" specified earlier.

Setting Outbound Mailbox Destination

As of to date specified by https://support.google.com/a/answer/176600?hl=en, you should set the SMTP outbox destination as follows:

Address: smtp.gmail.com

Port (TLS): 587

Port (SSL): 465

The recommended choice is the TLS version which is: smtp.gmail.com:587

Disable Dail-On-Demand

Unless you are still living in 1997 era, you should disable the costly dial-on-demand feature. This is for backward-compatible with legacy hardware that uses dail-up to connect into Internet.

Small Config Files

When prompted to either save the file into small config file or otherwise, it's entirely an option for you. Personally, I prefer small config file because I can version control and easier to develop/debug the configurations.

Root Account Redirect

If this is the first time configuration, it is never a practice to bind root account to a particular email address. Hence, one should forward it instead to the administrator. Here, you can fill in all the username (an alias) you wish to send. Example, "holloway", "admin", etc. We will update the aliases in the next step.

Update /etc/aliases

The next step is to update the /etc/aliases as root. Here, you can update the aliases carefully. Here is an example:

# /etc/aliases
mailer-daemon: postmaster
postmaster: root
nobody: root
hostmaster: root
usenet: root
news: root
webmaster: root
www: root
ftp: root
abuse: root
noc: root
security: root
holloway: hollowaykeanho@gmail.com
u0: holloway
root: u0

Notice that:

  1. I have an alias "holloway" that points to my email address.
  2. Then, my local user acccount "u0" is pointed to "holloway" alias.
  3. Then lastly, "root" is pointed to "u0".

For the rest, you should not edit it unless you know what you're doing. They are daemon services level aliases where "postmaster" is sent to "root" alias, thus, points to "u0", then to "holloway", then to my email address.

Once done, save it and exit.

Configure /etc/exim4/passwd.client

This step is to setup the Gmail SMTP integration into Exim4.

Getting App-Specific Password from Google Account

You can obtain an "App-Specific Password" from your Google Account for local Exim4 authentication. The guide is here: Get Google User's App-Specific Password.

Configure passwd.client

Once done, you should edit the password client in /etc/exim4/passwd.client for setting up the SMTP authentication. Here, you need to formulate the statement using the following pattern:

smtp.gmail.com:<gmail account name>:<app specific password>

Based on the pattern above, here is an example:

smtp.gmail.com:cory.galyna:abcdefghik    # for cory.galyna@gmail.com

IMPORTANT NOTE

  1. For compulsory security reason, DO NOT use your Gmail Account's Original Password. You MUST only use App-Specific Password.
  2. As of 2020, the address is now set to smtp.gmail.com rather than *.google.com.
  3. You only need the account name from your gmail account. This is because Exim4 knows how to match them. Based on the example above, it means cory.galyna from cory.galyna@gmail.com.

Once done, save the file and exit.

Set Correct File Permission

Last but not least, you must make sure you set the correct file permission since it contains password. The proper instructions are:

$ chown root:Debian-exim /etc/exim4/passwd.client
$ chmod 640 /etc/exim4/passwd.client

Configure /etc/email-addresses

This step is optional since Google rewrites the sender email address based on the integrated Google account. However, to be on the safe side, you should setup properly just in case there is another infrastructure changes. This is to ensure Exim4 knows when and what to fallback during those situation.

To do that, you should add all possible permutations account pointing to the generated Gmail account using the following pattern:

username@hostnameORdomain: <integrated gmail address>

This is my /etc/email-addresses:

# This is /etc/email-addresses. It is part of the exim package
#
# This file contains email addresses to use for outgoing mail. Any local
# part not in here will be qualified by the system domain as normal.
#
# It should contain lines of the form:
#
#user: someone@isp.com
#otheruser: someoneelse@anotherisp.com
u0: cory.galyna@gmail.com
root: cory.galyna@gmail.com
root@localhost: cory.galyna@gmail.com
root@holloway-seraphim: cory.galyna@gmail.com
root@holloway-seraphim.seraphim.local: cory.galyna@gmail.com

Configure /etc/hosts

With most configurations are done, the last thing is to ensure the local domain or hostname you registered are indeed resolvable in your /etc/hosts. This is done by routing those addresses to 127.0.0.1. Based on the example above, 2 more addresses must exists:

  • 127.0.0.1 holloway-seraphim
  • 127.0.0.1 holloway-seraphim.seraphim.local

In some systems like Debian, the additional hostname or domain name is routed to 127.0.1.1 with clustered name instead. The IP has no issue BUT the clustered name must be separated.

For your information, this works like a Domain Name Resolver where a given domain name or hostname is routed to a particular IP address. Therefore, the IP can retain its 127.0.X.X profile. If you're concerned, you can point it back to 127.0.0.1.

Hence, you should split them into multiple statements as such:

127.0.0.1       localhost
127.0.0.1       holloway-seraphim
127.0.0.1       holloway-seraphim.seraphim.local

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

Once done, save it and exit.

Restart Exim4

Now that all the configurations are done, you should restart Exim4 for testing the sending. You can execute the following as root:

$ update-exim4.conf
$ invoke-rc.d exim4 restart
$ exim4 -qff

Test Sending An Email

Once ready, you can try send an email to your root account as root, here is an example:

echo "Root are you there?" | mail -s "Root message" root

Verify by Local Log

Once the email indicated sent, you can check by reading from /var/exim4/mainlog:

$ tail /var/log/exim4/mainlog
...

If everything is good, then will not have any error.

Verify by Gmail

Next is to check the integrated Gmail Sent box, you should see the sent email like the one above. The few things you need to take note is:

  1. Ensure the "To" address is pointing to your username@hostname but not a compatible domain name. Otherwise, Gmail will send to that that email address and you will get a bounced failure notice for every single Exim4 sent email.
  2. Ensure "To" can identify which account and which local machine you're using.
  3. Ensure "Bcc" is sending to the correct recipient.

Verify by Recipient

Lastly, if your recipient receives the email properly. You're all good. Exim4 is working properly for send-email only with integrated Gmail account.

That's all for setup Exim4 with Gmail send-only configurations.