How to configure HestiaCP / Exim 4 for SMTP Relay (SendGrid, Mailgun, Amazon SES, etc)

Hi Guys,

I would like to use Sendgrid to relay all emails from the server and have followed the below

Sadly the configuration file update-exim4.conf.conf doesn’t seem to be included on loading the service and mail is still being delivered directly from the server.

I’ve been through a number of posts on the VestaCP forums which seem to refer to a different implementation of Exim.

Does anyone have this working? Thanks for your time.

2 Likes

I’ve figured this out for mailjet. You probably want to be editing exim4.conf.template

Under ‘begin authenticators’ I added

mailjet_login:
  driver = plaintext
  public_name = LOGIN
  client_send =:apiuser:apikey

Under ‘begin routers’ I added

 send_via_mailjet:
   driver = manualroute
   domains = ! +local_domains
   transport = mailjet_smtp
   route_list = * in-v3.mailjet.com

// This sends all non-local domains through mailjet. You can add specific domains if you want. The route_list is the name of the mailjet server I’m sending through.

Under ‘begin transports’ I have

mailjet_smtp:
  driver = smtp
  port = 587
  hosts_require_auth = *
  hosts_require_tls = *

That was pretty much it. Chang the port as neccessary. Put your real apiuser and apikey in between the colons

5 Likes

Thank you for your help.

I carried out the following to get it working with sendgrid

Under ‘begin authenticators’ I added

sendgrid_login:
  driver = plaintext
  public_name = LOGIN
  client_send = : apikey : key

Note: username should actually be ‘apikey’, not your sendgrid username

Under ‘begin routers’ I added

send_via_sendgrid: 
  driver = manualroute
  domains = ! +local_domains
  transport = sendgrid_smtp
  route_list = "* smtp.sendgrid.net::587 byname"
  host_find_failed = defer
  no_more

Under ‘begin transports’ I added

sendgrid_smtp: 
  driver = smtp
  hosts = smtp.sendgrid.net
  hosts_require_auth = <; $host_address
  hosts_require_tls = <; $host_address

Under router configuration for alias and catchall I also changed:

redirect_router = dnslookup

to:

redirect_router = send_via_sendgrid
4 Likes

hey guys, thanks a lot for sharing, I am sure this is helpful for other community members as well!

going to add infos about using amazon SES here as well:

Under ‘begin authenticators’ I added

ses_login:
driver = plaintext
public_name = LOGIN
client_send = : user : password

Under ‘begin routers’ I added

send_via_ses:
driver = manualroute
domains = ! +local_domains
transport = ses_smtp
route_list = * email-smtp…amazonaws.com;

Under ‘begin transports’ I have

ses_smtp:
driver = smtp
port = 587
hosts_require_auth = *
hosts_require_tls = *

as one can see it’s pretty much the same, external aws guide here: https://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-email-exim.html

keep in mind that the domains usually need to be verified within your mail relay service first, also the simple configuration above is used for all domains, so if you want to have it more specific - change as needed (and maybe report back) :wink:

3 Likes

So the way to limit to certain domains is under the ‘routers’ stanza.
Where you have this line saying “applies to all non local recipient domains”
domains = ! +local_domains
You can add a 'senders = ’ line to specify which sending addresses this gets applied to eg.

domains = ! +local_domains
senders = *@domain1.com : *@otherdomain.net : *@alt2domain.org

1.4 will come with build in support for mail relay on user level and admin level

Just wanna share 1 more workaround which can be used for multiple domains, and will allow to use different SMTP by domain (MailJet, MailGun, SendPulse, SendGrid etc.).

  1. Edit exim4.conf.template
1.1 Add after begin authenticators
# Smart Host Sending
sendbysmarthosts:
  driver = plaintext
  public_name = LOGIN
  hide client_send = : ${extract{user}{${lookup{$sender_address_domain}lsearch{/etc/exim4/exim_smarthosts}}}} : ${extract{pass}{${lookup{$sender_address_domain}lsearch{/etc/exim4/exim_smarthosts}}}}
1.2 Add after begin routers:
# Smart Host Sending
sendbysmarthostsrouter:
  driver = manualroute
  domains = ! +local_domains
# senders can be used to limit email addresses, for example: senders = [email protected] : *@domain2.com
# senders = [email protected]
  condition =  "${if eq{${lookup{$sender_address_domain}partial-lsearch{/etc/exim4/exim_smarthosts}{$value}}}{}{false}{true}}"
  ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
# headers_add = "${perl{mailtrapheaders}}"
  transport = sendbysmarthoststransport
  route_list = "* ${extract{smtp}{${lookup{$sender_address_domain}lsearch{/etc/exim4/exim_smarthosts}}}}::${extract{port}{${lookup{$sender_address_domain}lsearch{/etc/exim4/exim_smarthosts}}}} byname"
# host_find_failed = defer
# no_more
1.3 Add after begin transports
# Smart Host Sending
sendbysmarthoststransport:
  driver = smtp
  port = ${extract{port}{${lookup{$sender_address_domain}lsearch{/etc/exim4/exim_smarthosts}}}}
  hosts_require_auth = $host_address
  hosts_require_tls = $host_address
  1. Create file /etc/exim4/exim_smarthosts (root:root, 644), with next content:
exim_smarthosts
# "domain" - domain name used in index of the line
# "user" - user (or ID) used in smarthost's SMTP
# "pass" - password (or API secret, or API key, etc.) used for the SMTP user in smarthost
# "smtp" - SMTP server address of smarthost
# "port" - port used in Smarthost (586,25 or another)

# sending by MailJet
# $domain: domain=$domain user=$MAILJET_smtp_user pass=$MAILJET_api_password smtp=in-v3.mailjet.com port=587
domain1.com: domain=domain1.com user=xxxxxx pass=xxxxxx smtp=in-v3.mailjet.com port=2525

# sending by MailGun
# $domain: domain=$domain [email protected]$domain pass=$MailGun_default_password smtp=smtp.eu.mailgun.org port=587
domain1.com: domain=domain1.com [email protected] pass=xxxxxx smtp=smtp.eu.mailgun.org port=587
domain2.com: domain=domain2.com [email protected] pass=xxxxxx smtp=smtp.eu.mailgun.org port=587

# sending by SendPulse
# $domain: domain=$domain user=$SENDPULSE_smtp_user pass=$SENDPULSE_api_password smtp=smtp-pulse.com port=587

# sending by SendGrid
# $domain: domain=$domain user=$SENDGRID_smtp_user pass=$SENDGRID_api_password smtp=smtp.sendgrid.net port=587
  1. Restart Exim: sudo service exim4 restart

Good to know:

  • domains must be verified on SMTP relay account
  • domains not existing in /etc/exim4/exim_smarthosts will use local SMTP
  • in case there are 2 configs for 1 domain in /etc/exim4/exim_smarthosts only upper will be used: In example above emails from domain1.com will be sent by MailJet, and domain2.com by MailGun
1 Like