Code Father's Blog

/dev/null/Projects - Nov 4, 2020

Setup Amazon SES for a Single Domain(s) in Exim (WHM)

So, you’ve got your own cPanel server, domain and you’ve signed up for Amazon SES. I’m not going to go into what Amazon SES is and why you should (or should not) use it, that’s documented quite well around the Internet, but you’ve run into a snag: all of the documentation out there for setting up Amazon SES is for all domains on the server. What if you just want one domain? Perhaps only two domains? How does one set that up?

Well, it’s actually a lot more complicated than the setup for all domains, but with some basic help, you can set this up yourself.

Step 1

The first thing you need to do is setup your Amazon SES account and get the SMTP username and password. Again, this process is well documented, so do that first, then come back here.

Step 2

Now, you need to setup Exim to actually use the Amazon SES service. To do that, open WHM and navigate to the Exim Configuration Manager (hint: use the search box under the WHM logo). Once there, click on the Advanced Editor tab.

Here, we’re going to edit the AUTH, ROUTERSTART and TRANSPORTSTART sections.

In the AUTH section, you’re going to need to add the authentication data that you got in Step 1. So, use the CTRL-F (Command-F for Mac users) option to find the AUTH section. There’s a box there, so you can add the following into it:

# Added for Amazon SES
ses_login: driver = plaintext
public_name = LOGIN
client_send = : USERNAME: PASSWORD
###

Make sure you replace the above USERNAME and PASSWORD entries that you got from your Amazon SES setup.

Now, move to the ROUTERSTART section and in the box there add:

# Added for Amazon SES
smarthost_dkim:
  driver = manualroute
  domains = !"+local_domains +smart_hosts"
  condition = "${if eq{${lookup{$sender_address_domain}partial-lsearch{/etc/staticroutes}{$value}}}{}{false}{true}}"
  ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8 : YOUR_SERVER_IP
  headers_add = "${perl{mailtrapheaders}}"
  require_files = "+/var/cpanel/domain_keys/private/${sender_address_domain}"
  transport = remote_smtp_smart_dkim
  route_list = !+local_domains "${lookup{$sender_address_domain}partial-lsearch{/etc/staticroutes}}"
smarthost_regular:
  driver = manualroute
  domains = !"+local_domains +smart_hosts"
  condition = "${if eq{${lookup{$sender_address_domain}partial-lsearch{/etc/staticroutes}{$value}}}{}{false}{true}}"
  ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8 : YOUR_SERVER_IP
  headers_add = "${perl{mailtrapheaders}}"
  transport = remote_smtp_smart_regular
  route_list = !+local_domains "${lookup{$sender_address_domain}partial-lsearch{/etc/staticroutes}}"
###

Now, before you move on, make sure you change the YOUR_SERVER_IP item above to the IP address of your server. If you have more than one, then you’ll want to add each IP you use to this line. So, if you have IPs 1.2.3.4 and 5.6.7.8, then your line will look like:

ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8 : 1.2.3.4 : 5.6.7.8

Now, move to the TRANSPORTSTART section and add this in the text box:

# Added for Amazon SES
remote_smtp_smart_dkim:
  driver = smtp
  hosts_require_auth = *
  hosts_require_tls = *
  interface = ${if exists {/etc/mailips}{${lookup{$sender_address_domain}lsearch*{/etc/mailips}{$value}{}}}{}}
  helo_data = ${if exists {/etc/mailhelo}{${lookup{$sender_address_domain}lsearch*{/etc/mailhelo}{$value}{$primary_hostname}}}{$primary_hostname}}
  dkim_domain = $sender_address_domain
  dkim_selector = default
  dkim_private_key = "/var/cpanel/domain_keys/private/${dkim_domain}"
  dkim_canon = relaxed
remote_smtp_smart_regular:
  driver = smtp
  hosts_require_tls = *
  hosts_require_auth = *
  interface = ${if exists {/etc/mailips}{${lookup{$sender_address_domain}lsearch*{/etc/mailips}{$value}{}}}{}}
  helo_data = ${if exists {/etc/mailhelo}{${lookup{$sender_address_domain}lsearch*{/etc/mailhelo}{$value}{$primary_hostname}}}{$primary_hostname}}
###

OK, you’re done with your setup inside of WHM.

Step 3

Now it’s time to move to the command line. You can use an SSH session or the terminal inside of WHM. Either way, you need Root access to change the next set of files.

There are 3 files we’ll be editing, they are the /etc/exim.conf.local, /etc/smarthosts and /etc/staticroutes files. Starting with the /etc/exim.conf.local, add the following under the @CONFIG@ section:

# Added for Amazon SES
hostlist smart_hosts = lsearch;/etc/smarthosts
###


Save and close the file.

Now, for the /etc/smarthosts file, add:

# Added for Amazon SES
domain_1.tld: Amazon_SES_Server
domain_2.tld: Amazon_SES_Server
###

Here, you’ll need to change the domain_1.tld entry to the domain you’ll be having email sent through Amazon SES. The Amazon_SES_Server entry should be changed to the appropriate Amazon server given to you during your setup, such as email-smtp.us-west-1.amazonaws.com or something similar.

You’ll do the same for domain_2.tld and add any additional domains that you want to use the Amazon SES domain on.

Save and close the file.

Now, for the /etc/staticroutes file, you’ll configure it the exact same as the /etc/smarthosts file.  It’s not clear if a symlink will work and I haven’t tried it, so if you decide to try and it works for you, let me know in the comments!

Step 4

Now, your files are all setup, the Exim configuration on your cPanel server is all setup. Just one more step. Run:

/scripts/buildeximconf

That’ll rebuild the Exim configuration and put all the changes that you have done into action. It’ll also check for syntax errors, so if you have any, pay attention to the errors and correct as needed.

From here, perform some email sending to validate that it’s all working and you should be well on your way to having a setup that uses Amazon SES, but only for the domains listed in the /etc/smarthosts and /etc/staticroutes configuration files.