Securing SMTP Server with SSL
May 21, 2025
SSL certificate is never generated for the IP. It is generated for the domain or subdomain. It is also never generated for any specific ports. A certificate of the domain works for all ports as well.
For example smtp.example.com:456 and smtp.example.com:2525 uses the same ssl certificates and you once only need to generate it once for the domain and pass it to the each service running on various ports.
Securing SMTP servers
First, enable all your smtp ports through the firewall. Below is the example to enable it in UFW.
Install Certbot and related dependencies. We are using snap here. You can use any package managers you want, to install these packages.
Now point your domain like
smtp.example.comto the public IP address of your server using your DNS Provider. The IP address needs to be a publicly exposed and accessible IP address. Local or Private IP address will not work. This is strictly needed for the Certbot to verify and generate the necessary acme_challenge files to authenticate and generate the certificates and private keys.If you are using cloudflare or similar service with proxy, disable the proxy for this domain as smtp traffic needs to reach to your origin server, and such proxy will hide your server’s public address with their own, resulting in the smtp traffic not reaching to your server.
During the authentication process for domain verification using the --standalone flag , Certbot spins up the temporary web server and binds itself to the port 80 (http). So, if any other services or reverse proxy are already binded and running on that port, Certbot will fail. You will have to set the webroot for the domain on that proxy to correctly serve the acme_challenge file for the Certbot auth to be successful.
Generate the certificates using the following command
In the code snippet, replace the domain smtp.example.com with your actual domain name and the email with your own email.
This will drop the certificates on the path
/etc/letsencrypt/live/smtp.example.com/fullchain.pem
/etc/letsencrypt/live/smtp.example.com/privkey.pem
Here, fullchain.pem is your certificate and the privkey.pem is your private key
Now use these keys on your smtp server depending upon how you have build your smtp server. Search for the documentation on how to use custom certificates.
Verification
Check the DNS propagation of the domain. It should return the public IP address of your server as you have set.
Check Implicit SSL (465) or your custom ports
It should show the ssl handshake output like :
Then type
EHLO testand it should return something like thisCheck STARTTLS (587) or your custom ports
It should also repeat the same behaviour as above.
Common pitfalls & troubleshooting
Wrong cert files: Always use correct fullchain.pem + privkey.pem files.
Port conflict: Ensure nothing else (e.g. Postfix) is binding 25/465/587 or any of your custom ports on the host.
Firewall/NAT: Double-check both your server’s firewall and any cloud-provider security group to enable the needed ports.
Docker mount permissions: If you are deploying the docker based smtp servers, Certs must be world-readable by the container; use
chmod 644 privkey.pemif needed.DNS: If
smtp.example.comstill points elsewhere, your client or the certbot will never reach your new server, which will fail generating the certificates and later on will not resolve to the smtp server. DNS propagation are generally quick, but sometimes can take upto 72 hours to reflect it globally. Wait before retrying.
Congratulations. Now your smtp server is secure and protected with SSL. Make sure to keep your private key private.
