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.


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

Under ‘begin authenticators’ I added

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

Under ‘begin routers’ I added

   driver = manualroute
   domains = ! +local_domains
   transport = mailjet_smtp
   route_list = *

// 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

  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


Thank you for your help.

I carried out the following to get it working with sendgrid

Under ‘begin authenticators’ I added

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

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

Under ‘begin routers’ I added

  driver = manualroute
  domains = ! +local_domains
  transport = sendgrid_smtp
  route_list = "* byname"
  host_find_failed = defer

Under ‘begin transports’ I added

  driver = smtp
  hosts =
  hosts_require_auth = <; $host_address
  hosts_require_tls = <; $host_address

Under router configuration for alias and catchall I also changed:

redirect_router = dnslookup


redirect_router = send_via_sendgrid

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

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

Under ‘begin routers’ I added

driver = manualroute
domains = ! +local_domains
transport = ses_smtp
route_list = * email-smtp…;

Under ‘begin transports’ I have

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

as one can see it’s pretty much the same, external aws guide here:

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:


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 = * : * : *

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
  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
  driver = manualroute
  domains = ! +local_domains
# senders can be used to limit email addresses, for example: senders = [email protected] : *
# senders = [email protected]
  condition =  "${if eq{${lookup{$sender_address_domain}partial-lsearch{/etc/exim4/exim_smarthosts}{$value}}}{}{false}{true}}"
  ignore_target_hosts = :
# 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
  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:
# "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 port=587 user=xxxxxx pass=xxxxxx port=2525

# sending by MailGun
# $domain: domain=$domain [email protected]$domain pass=$MailGun_default_password port=587 [email protected] pass=xxxxxx port=587 [email protected] pass=xxxxxx port=587

# sending by SendPulse
# $domain: domain=$domain user=$SENDPULSE_smtp_user pass=$SENDPULSE_api_password port=587

# sending by SendGrid
# $domain: domain=$domain user=$SENDGRID_smtp_user pass=$SENDGRID_api_password 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 will be sent by MailJet, and by MailGun
1 Like