View Categories

cPanel

cPanel Mailbaby Configuration

Recommended cPanel Configuration (v108+ with SRS Rewriting)

To ensure optimal mail delivery and security across all cPanel systems, we highly recommend applying the following baseline configurations before setting up your smarthost.

Step 1: Verify DNS and Deliverability

  • Ensure your server’s hostname resolves correctly and has a valid Reverse DNS (rDNS) record.
  • Navigate to WHM > Email Deliverability to confirm your hostname has both SPF and DKIM keys configured. cPanel will also verify your rDNS here.

Step 2: Update Exim Configuration Manager

Navigate to WHM > Home > Service Configuration > Exim Configuration Manager and adjust the following settings:

  • Use the reverse DNS entry for the mail HELO/EHLO if available: Set to OFF
  • SPF include hosts for all domains on this system: Set to spf-c.mailbaby.net
  • Enable Sender Rewriting Scheme (SRS) Support: Set to ON

Step 3: Optional (But Recommended) Anti-Spam Tweaks

cPanel includes excellent built-in outbound spam filtering. Having these enabled prevents easily detectable spam from leaving your server and protects your IP reputation. In the Exim Configuration Manager, we recommend enabling:

  • Scan messages for malware from authenticated senders (exiscan)
  • Scan outgoing messages for malware
  • Scan outgoing messages for spam and reject based on defined Apache SpamAssassin™ score
  • Do not forward mail to external recipients based on the defined Apache SpamAssassin™ score (Minimum: 0.1; Maximum: 99.9)

Note: We also recommend limiting outbound emails per hour per domain by navigating to WHM > Tweak Settings.


Configuring the Smarthost

You can configure Exim to use Mailbaby using one of two methods: manually through the WHM interface, or directly via the command line.

Option 1: Manual Editing via WHM (Advanced Editor)

In WHM, go to Home > Service Configuration > Exim Configuration Manager and click the Advanced Editor tab.

1. Find the AUTH section and add:

mailbaby_login: 
  driver = plaintext 
  public_name = LOGIN 
  client_send = : YOURUSERNAME : YOURPASSWORD

Replace YOURUSERNAME and YOURPASSWORD with your Mailbaby credentials.

2. Find the POSTMAILCOUNT section and add the routing rules.
Important: Only use ONE of the following blocks based on your cPanel version. Do not use both.

For cPanel v108 and Newer (with SRS):

remoteserver_route: 
  driver = manualroute
.ifdef SRSENABLED
  # if outbound, and forwarding has been done, use an alternate transport
  transport = ${if eq {$local_part@$domain} \
  {$original_local_part@$original_domain} \
  {mailbaby_smtp} {mailbaby_forward_smtp}}
.else
  transport = mailbaby_smtp
.endif
  domains = !+local_domains 
  ignore_target_hosts = 127.0.0.0/8 
  route_list = * relay.mailbaby.net::25 randomize byname 
  host_find_failed = defer 
  no_more

For cPanel v106 and Older:

remoteserver_route:
  driver = manualroute
  transport = mailbaby_smtp
  domains = !+local_domains
  ignore_target_hosts = 127.0.0.0/8
  route_list = * relay.mailbaby.net::25 randomize byname
  host_find_failed = defer
  no_more

3. Find the TRANSPORTSTART section and add the transport rules.
Important: Ensure X-AuthUser is kept intact. Removing this will result in stricter email filtering. Again, only pick the version that matches your cPanel installation.

For cPanel v108 and Newer (with SRS):

mailbaby_smtp:
  driver = smtp
  hosts_require_auth = *
  tls_tempfail_tryclear = true
  headers_add = X-AuthUser: ${if match {$authenticated_id}{.*@.*}\
  {$authenticated_id} {${if match {$authenticated_id}{.+}\
  {$authenticated_id@$primary_hostname}{$authenticated_id}}}}
  dkim_domain = ${perl{get_dkim_domain}}
  dkim_selector = default
  dkim_canon = relaxed
  dkim_private_key = "/var/cpanel/domain_keys/private/${dkim_domain}"
  # uncomment this if users get errors message has line too long for transport
  #message_linelength_limit = 65536

mailbaby_forward_smtp:
  driver = smtp
  hosts_require_auth = *
  tls_tempfail_tryclear = true
  headers_add = X-AuthUser: ${if match {$authenticated_id}{.*@.*}\
  {$authenticated_id} {${if match {$authenticated_id}{.+}\
  {$authenticated_id@$primary_hostname}{$authenticated_id}}}}
  dkim_domain = ${perl{get_dkim_domain}}
  dkim_selector = default
  dkim_canon = relaxed
  dkim_private_key = "/var/cpanel/domain_keys/private/${dkim_domain}"
  # uncomment this if users get errors message has line too long for transport
  #message_linelength_limit = 65536
.ifdef SRSENABLED
  return_path = ${srs_encode {SRS_SECRET} {$return_path} {$original_domain}}
.endif
  max_rcpt = 1

For cPanel v106 and Older:

mailbaby_smtp:
  driver = smtp
  hosts_require_auth = *
  tls_tempfail_tryclear = true
  headers_add = X-AuthUser: ${if match {$authenticated_id}{.*@.*} {$authenticated_id} {${if match {$authenticated_id}{.+} {$authenticated_id@$primary_hostname}{$authenticated_id}}}}
  dkim_domain = ${perl{get_dkim_domain}}
  dkim_selector = default
  dkim_private_key = "/var/cpanel/domain_keys/private/${dkim_domain}"
  # uncomment this if users get errors message has line too long for transport
  #message_linelength_limit = 65536

4. Optional Retry Configurations

If you want to customize how Exim handles temporary failures, find RETRYSTART and add:

* data_4xx F,4h,1m
* rcpt_4xx F,4h,1m
* timeout F,4h,1m
* refused F,1h,5m
* lost_connection F,1h,1m
* * F,6h,5m

Then find RETRYBLOCK and add:

+secondarymx * F,4h,5m; G,16h,1h,1.5; F,4d,8h
* * F,2h,15m; G,16h,1h,1.5; F,4d,8h
* auth_failed

Scroll to the bottom and click Save.


Option 2: Creating /etc/exim.conf.local (CLI Method)

If you prefer working via SSH, you can edit or create /etc/exim.conf.local. If the file already exists, carefully merge the configuration below into your existing blocks. Be sure to replace your credentials in the @AUTH@ section.

%RETRYBLOCK%
+secondarymx * F,4h,5m; G,16h,1h,1.5; F,4d,8h
* * F,2h,15m; G,16h,1h,1.5; F,4d,8h
* auth_failed

@AUTH@
mailbaby_login:
  driver = plaintext
  public_name = LOGIN
  client_send = : YOURUSERNAME : YOURPASSWORD

@BEGINACL@

@CONFIG@
chunking_advertise_hosts = ""
local_from_check = true
# Mailbaby max size limit is 100MB (cPanel defaults may be less)
#message_size_limit = 100M
ignore_bounce_errors_after = 1h
timeout_frozen_after = 12h

@DIRECTOREND@
@DIRECTORMIDDLE@
@DIRECTORSTART@
@ENDACL@

@POSTMAILCOUNT@
remoteserver_route: 
  driver = manualroute
.ifdef SRSENABLED
  # if outbound, and forwarding has been done, use an alternate transport
  transport = ${if eq {$local_part@$domain} \
  {$original_local_part@$original_domain} \
  {mailbaby_smtp} {mailbaby_forward_smtp}}
.else
  transport = mailbaby_smtp
.endif
  domains = !+local_domains 
  ignore_target_hosts = 127.0.0.0/8 
  route_list = * relay.mailbaby.net::25 randomize byname 
  host_find_failed = defer 
  no_more

@PREDOTFORWARD@
@PREFILTER@
@PRELOCALUSER@
@PRENOALIASDISCARD@
@PREROUTERS@
@PREVALIASNOSTAR@
@PREVALIASSTAR@
@PREVIRTUALUSER@
@RETRYEND@

@RETRYSTART@
* data_4xx F,4h,1m
* rcpt_4xx F,4h,1m
* timeout F,4h,1m
* refused F,1h,5m
* lost_connection F,1h,1m
* * F,6h,5m

@REWRITE@
@ROUTEREND@
@ROUTERMIDDLE@
@ROUTERSTART@
@TRANSPORTEND@
@TRANSPORTMIDDLE@

@TRANSPORTSTART@
mailbaby_smtp:
  driver = smtp
  hosts_require_auth = *
  tls_tempfail_tryclear = true
  headers_add = X-AuthUser: ${if match {$authenticated_id}{.*@.*}\
  {$authenticated_id} {${if match {$authenticated_id}{.+}\
  {$authenticated_id@$primary_hostname}{$authenticated_id}}}}
  dkim_domain = ${perl{get_dkim_domain}}
  dkim_selector = default
  dkim_canon = relaxed
  dkim_private_key = "/var/cpanel/domain_keys/private/${dkim_domain}"
  #message_linelength_limit = 65536

mailbaby_forward_smtp:
  driver = smtp
  hosts_require_auth = *
  tls_tempfail_tryclear = true
  headers_add = X-AuthUser: ${if match {$authenticated_id}{.*@.*}\
  {$authenticated_id} {${if match {$authenticated_id}{.+}\
  {$authenticated_id@$primary_hostname}{$authenticated_id}}}}
  dkim_domain = ${perl{get_dkim_domain}}
  dkim_selector = default
  dkim_canon = relaxed
  dkim_private_key = "/var/cpanel/domain_keys/private/${dkim_domain}"
  #message_linelength_limit = 65536
.ifdef SRSENABLED
  return_path = ${srs_encode {SRS_SECRET} {$return_path} {$original_domain}}
.endif

Once you have saved the file, rebuild the Exim configuration by running this command in your terminal:

/scripts/buildeximconf

Greylisting Trusted Hosts

If your server uses Greylisting (cPHulk/Exim), you must add Mailbaby’s IP ranges to your trusted mailhosts so legitimate mail isn’t delayed. Run the following commands via CLI/Terminal as the root user:

whmapi1 --output=jsonpretty create_cpgreylist_trusted_host ip='162.220.160.0/28' comment='MailBaby'
whmapi1 --output=jsonpretty create_cpgreylist_trusted_host ip='68.168.211.160/28' comment='MailBaby'
whmapi1 --output=jsonpretty create_cpgreylist_trusted_host ip='66.45.233.16/29' comment='MailBaby'
whmapi1 --output=jsonpretty create_cpgreylist_trusted_host ip='209.159.153.232/29' comment='MailBaby'
whmapi1 --output=jsonpretty create_cpgreylist_trusted_host ip='208.73.205.248/29' comment='MailBaby'
whmapi1 --output=jsonpretty create_cpgreylist_trusted_host ip='67.217.63.248/29' comment='MailBaby'
whmapi1 --output=jsonpretty create_cpgreylist_trusted_host ip='199.231.189.152/29' comment='MailBaby'
whmapi1 --output=jsonpretty create_cpgreylist_trusted_host ip='64.20.38.24/29' comment='MailBaby'
whmapi1 --output=jsonpretty create_cpgreylist_trusted_host ip='174.138.190.32/29' comment='MailBaby'
whmapi1 --output=jsonpretty create_cpgreylist_trusted_host ip='64.20.36.192/29' comment='MailBaby'
whmapi1 --output=jsonpretty create_cpgreylist_trusted_host ip='199.231.189.96/29' comment='MailBaby'
whmapi1 --output=jsonpretty create_cpgreylist_trusted_host ip='206.72.200.40/29' comment='MailBaby'
whmapi1 --output=jsonpretty create_cpgreylist_trusted_host ip='66.45.229.224/28' comment='MailBaby'
whmapi1 --output=jsonpretty create_cpgreylist_trusted_host ip='174.138.180.168/29' comment='MailBaby'
whmapi1 --output=jsonpretty create_cpgreylist_trusted_host ip='174.138.180.160/29' comment='MailBaby'
whmapi1 --output=jsonpretty create_cpgreylist_trusted_host ip='174.138.180.152/29' comment='MailBaby'
whmapi1 --output=jsonpretty create_cpgreylist_trusted_host ip='67.217.53.0/24' comment='MailBaby'
whmapi1 --output=jsonpretty create_cpgreylist_trusted_host ip='205.209.127.0/24' comment='MailBaby'
whmapi1 --output=jsonpretty create_cpgreylist_trusted_host ip='68.168.210.0/24' comment='MailBaby'
whmapi1 --output=jsonpretty create_cpgreylist_trusted_host ip='205.209.124.0/24' comment='MailBaby'

Advanced Routing Examples

Note: These configurations were tested on cPanel v11.106 and Exim 4.95. Newer versions of Exim may require slight syntax adjustments. As a smarthost, Mailbaby accepts and scans the email your server sends using valid credentials. If you need to stop specific local domains from using the relay, you must configure that locally in Exim. These advanced changes should be applied by a qualified system administrator.

Most advanced routing modifications happen in the POSTMAILCOUNT section. Keeping these rules inside POSTMAILCOUNT ensures cPanel can still enforce its “emails per hour” limits.

To test if your routing works via SSH, use the exim -bt command:

exim -bt [email protected]

If successful, it should output that the router is remoteserver_route and the transport is mailbaby_smtp.

Scenario A: Exclude a Domain from the Smarthost

If you want all traffic to go through Mailbaby except for a specific domain, add a senders line to your remoteserver_route block with an exclamation point (!) to negate it.

remoteserver_route: 
  driver = manualroute
.ifdef SRSENABLED
  transport = ${if eq {$local_part@$domain} \
  {$original_local_part@$original_domain} \
  {mailbaby_smtp} {mailbaby_forward_smtp}}
.else
  transport = mailbaby_smtp
.endif
  domains = !+local_domains
  
  # Add your exclusions here:
  senders = : [email protected] : !*@domain1.com
  
  ignore_target_hosts = 127.0.0.0/8 
  route_list = * relay.mailbaby.net::25 randomize byname 
  host_find_failed = defer 
  no_more

Scenario B: Only Use Mailbaby for Specific Local Domains

If you only want Mailbaby to process outgoing mail for a few specific domains on your server, change the domains rule from !+local_domains to a custom list file.

First, update the block in Exim:

remoteserver_route:
  driver = manualroute
  
  # Point this to your new include file
  domains = lsearch:/etc/exim_domains_include
  
.ifdef SRSENABLED
  transport = ${if eq {$local_part@$domain} \
  {$original_local_part@$original_domain} \
  {mailbaby_smtp} {mailbaby_forward_smtp}}
.else
  transport = mailbaby_smtp
.endif
  ignore_target_hosts = 127.0.0.0/8
  route_list = * relay.mailbaby.net::25 randomize byname
  host_find_failed = defer
  no_more

Next, create the file /etc/exim_domains_include via SSH and list your domains one per line:

domain1.com
domain2.com

Finally, ensure Exim can read the file by setting the correct permissions:

chown root:mail /etc/exim_domains_include

Scenario C: Only Route Mail Based on Sender Email

If you want to restrict Mailbaby usage by the sender’s address rather than the domain, add a senders line without the exclamation points.

remoteserver_route:
  driver = manualroute
.ifdef SRSENABLED
  transport = ${if eq {$local_part@$domain} \
  {$original_local_part@$original_domain} \
  {mailbaby_smtp} {mailbaby_forward_smtp}}
.else
  transport = mailbaby_smtp
.endif
  ignore_target_hosts = 127.0.0.0/8
  
  # Add approved senders here:
  senders = *@DOMAIN1.com : *@DOMAIN2.com : [email protected]
  
  domains = !+local_domains
  route_list = * relay.mailbaby.net::25 randomize byname
  host_find_failed = defer
  no_more