Configuring SmarterMail for Failover on Linux
| This feature is only available in SmarterMail Enterprise for Windows. |
Who Should Use This
This document is intended for use by administrators deploying SmarterMail in high-volume environments and/or for organizations that want to ensure maximum uptime. It provides minimal system requirements and considerations for deploying SmarterMail in a failover environment on Linux.
Failover Overview
SmarterMail Enterprise allows organizations to decrease the likelihood of service interruptions and virtually eliminate downtime by installing SmarterMail on a standby server that is available should the primary mail server suffer a service interruption. For businesses that use their mail server as a mission-critical part of their operations, failover functionality ensures that the business continues to communicate and that productivity remains at the highest levels possible, even if there is a primary server failure.
Understanding How Failover Works
The main components of failover functionality are; a primary server that acts as the default SmarterMail server and manages the licensing of the server cluster, and a secondary server that remains connected and available in a “hot standby” mode until the primary server experiences problems with network access or system hardware. It's considered a "hot standby" because the server is "hot", in that it's powered on, but the SmarterMail service (and possibly the web server) are inactive/disabled. Shared storage is used to provide a single point of data for all SmarterMail services that both servers (nodes) point to. The Primary or Secondary servers would be where domains and users are accessed, but the share holds all of the data.
If the primary server fails, SmarterMail can be configured to automatically enable services on the secondary server. When this occurs, the secondary server then takes over responsibility for processing background threads and supporting all email functionality. This server will remain in active status until another failure occurs or the primary mail server is able to be brought back online.
Failover promotion is manual/scripted. There is no active self-monitoring between nodes to trigger takeover on its own; the monitoring + service cutover script provided at the end is a required part of this deployment, not an optional extra.
Minimal System Requirements
- A minimum of two Linux VMs (same distro/version pair recommended), same hostname conventions you'd use for any two-server deploy; clock synchronized (chrony/ntp).
- 1 free IP for the floating VIP (or an LB appliance with a front IP).
- Both servers must have their server times synchronized
- An NFS server / NAS/SAN for the share (RAID 10 recommended), exported to both servers.
- Shared storage such as NFS export (recommended) mounted at the same path on both servers.
- Web server on both primary and secondary servers. We recommend SmarterMail's built-in web server or nginx/caddy reverse proxy.
- Install prerequisites per distro: curl and libicu (e.g. Ubuntu 22.04: apt install curl libicu70).
- Firewall: open the mail ports (25, 110, 143, 465, 587, 993, 995 as used), plus 80/443 TCP and 443/UDP (HTTP/3) for the web interface.
1. Prepare the Shared Storage
Create this layout on the share (paths are an example; the share should be mounted identically on both servers):
/mnt/smartermail-shared/
└── Service/└── Settings/
"Settings/" on the share becomes the service's configuration store. On the active node it will contain: failover .json, mailConfig.json (global settings, including the domains root), settings.json (system settings, including the failover node list), ServiceLocker.dat (created automatically), plus the domains data if you host domains there.
nas01:/export/smartermail /mnt/smartermail-shared nfs rw,hard,intr,timeo=600 0 0
Using "hard" plus a generous timeout (timeo) is recommended for a mail store; NFSv4 or later flor lock behavior.
2. Install and Configure the Primary Server
Install SmarterMail on the primary following the standard Linux procedure: install curl + libicu, then run the installer for your build. During setup choose Enterprise and complete the first-run wizard.
Configure the Web Server
When running the installation of SmarterMail, select SmarterMail's built-in web server. This opens ports 80/443 and has the service serve the web interface directly. (It binds HTTP on 90 and HTTPS on 443 with SNI-based certificate selection using certificates from the SmarterMail Certificate Manager.) You do have the option to put nginx or Caddy in front on the same ports, proxying to the internal port. However, for a failover pair the built-in web server is the "path of least resistance". (Be sure to use the same choice on both servers.)
Migrate Data to the Share
This step can be skipped for a fresh installation of a failover system.
- First, stop the service.
sudo systemctl stop smartermail
- Next, copy the local config store and mail data to the share:
rsync -a /etc/smartermail/ /mnt/smartermail-shared/Service/Settings/
andrsync -a /var/lib/smartermail/Domains/ /mnt/smartermail-shared/Domains/
- Then, point the config at the new locations: edit mailConfig.json on the share and change path_smartermail_root to the domains root on the share (e.g. /mnt/smartermail-shared/Domains/). Search the shared settings.json for any absolute local paths (/var/lib/smartermail) and replace them with the share equivalents. Every domain's stored data_path must reference the share, not the local disk.
- Then, create/edit failover.json in the shared Settings folder (e.g.
. /mnt/smartermail-shared/Service/Settings/failover.json) and in the local Settings folder of the install (/opt/smartertools/smartermail/Settings/failover.json — this is the copy the service reads before it knows about the share):
{FailoverIPAddress is the floating VIP / load-balancer front address.
"NodeId": "PUT-A-SINGLE-GUID-HERE-SAME-ON-BOTH-SERVERS",
"FailoverIPAddress": "[YOUR IP]",
"IsEnabled": true,
"SharedSystemFilesPath": "/mnt/smartermail-shared/Service/Settings"
}
SharedSystemFilesPath is the shared Settings folder itself, with forward slashes.
A NodeID is only generated automatically if the file is absent; keep the GUID format (e.g . a51eba87-c8c6-49e3-812f-84e46ab617e7). Use the same NodeID on both servers. - Start the service:
sudo systemctl start smartermail
On boot it should now read its config from the share and create ServiceLocker.dat in the shared Settings folder. - Verify the domains and data resolve from the share, then re-check your Enterprise activation.
Install the Standby Server
- Install SmarterMail just as you did above. However, DO NOT add domains or activate a license during the setup wizard.
- Stop the mail service
sudo systemctl stop smartermail
- Place the same failover.json in /opt/smartertools/smartermail/Settings/ on the standby.
- Configure the web server exactly as on the Primary (i.e., same choice of web server, same ports, etc.)
- DO NOT start the mail service. The standby stays offline until cutover is required. Also, disable
auto-start for the service so a random reboot doesn't double activate:
sudo systemctl disable smartermail
Set Up the Load Balancer
The goal is Single-Active behavior: the Virtual IP (VIP) is served by exactly one node, matching the Windows NLB "Single Host" filtering mode. keepalived does this natively on Linux and also gives you the hook points for scripted cutover, so that's what's recommended.
Create/edit the keepalived CONF file on the PRIMARY server: /etc/keepalived/keepalived.conf
vrrp_script chk_sm {
script "/usr/local/bin/sm-health.sh"
interval 3
fall 2
rise 2
}
vrrp_instance VI_SMARTERMAIL {
state MASTER
interface eth0
virtual_router_id 51
priority 150
advert_int 1
track_script { chk_sm }
virtual_ipaddress { [REDACTED]/24 }
notify_master "/usr/local/bin/sm-cutover.sh master"
notify_backup "/usr/local/bin/sm-cutover.sh backup"
}
For the STANDBY server, you'll create the same keepalived CONF file in the same location. However, you set the following:
state BACKUP
priority 100
The standby keeps the chk_sm script, too, so it only takes the VIP whe its own service is healthy.
Next, create the sm-cutover.sh file on both servers. This is the service cutover script:
#!/bin/bash
# Called by keepalived when this node gains (master) or loses (backup) the VIP
STATE="$1"
if [ "$STATE" = "master" ]; then
systemctl start smartermail
else
systemctl stop smartermail
fi
Next, create the sm-health.sh file in /usr/local/bin on both servers:
#!/bin/bash
systemctl is-active --quiet smartermail && \
curl -sk -o /dev/null -m 5 https://[REDACTED]/interface/ && exit 0
exit 1
With this design: if the primary's service dies, keepalived fails the health check, the VIP floats to the standby, notify_masterstarts the standby's service. If the primary's machine dies entirely, the standby stops hearing VRRP advertisements and takes over after ~3 s. SMTP/IMAP/POP traffic rides the same VIP (the service binds all its ports on all interfaces), so the VIP covers web and mail protocols in one mechanism — no per-port load-balancer rules needed.
Now, there IS an HAProxy alternative (if a dedicated LB appliance is preferred): create an active/backup backend pool (server primary .. . check + server standby ... check backup) pointing at each node's Port 443, with the standby's service started/stopped by your external monitor of choice calling the same cutover script. Note the standby answers nothing while its service is stopped, so HAProxy alone can't start it — you still need a monitor+script for service start on the standby.
Activation and Testing
First thing you'll want to do is activate your license on both the primary and secondary servers, and make sure the activation succeeds.
Next, test failover by stopping the primary server (systemctl stop smartermail) and verifying that the standby takes over. Within the health-check window the VIP should float to the standby, whose cutover hook starts its service. Verify that you can login via webmail and that VIP works, mail delivery works, new mail lands on the share, etc.
Next, check you can fail BACK to the primary server. Stop the standby's service, then start the primary's (or let keepalived's priority do it during a controlled window — prefer explicit scripts so the shared data is never accessed by two services at once). Reactivate/confirm licensing if prompted, and re-verify the Failover Servers tab shows the primary ACTIVE.