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