Securing SMTP Server with SSL

Learn how to secure your SMTP server with SSL, ensuring safe email transmission by following this comprehensive guide.
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.
So, lets secure our smtp servers:
First, enable all your smtp ports through the firewall. Below is the example to enable it in ufw
ufw allow 25,465,587/tcp ufw reload
Install Certbot and related dependencies. We are using snap here. You can use any package managers you want, to install these.
snap install core; snap refresh core; snap install --classic certbot
Now point your domain like
smtp.example.com
to 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.sudo certbot certonly \ --standalone \ -d smtp.example.com \ --agree-tos \ --no-eff-email \ --email your_email@example.com
This will drop the certificates on the path
/etc/letsencrypt/live/smtp.example.com/fullchain.pem
/etc/letsencrypt/live/smtp.example.com/privkey.pem
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.
dig +short smtp.example.com
Check Implicit SSL (465) or your custom ports
openssl s_client -connect smtp.example.com:465 -servername smtp.example.com \ -crlf -quiet
It should show the ssl handshake output like :
Connecting to {your_ip_address} depth=2 C=US, O=Internet Security Research Group, CN=ISRG Root X1 verify return:1 depth=1 C=US, O=Let's Encrypt, CN=E5 verify return:1 depth=0 CN=smtp.example.com verify return:1 220 feec0839934b ESMTP
Then type
EHLO test
and it should return something like this250-feec0839934b Nice to meet you, [your ip address] 250-PIPELINING 250-8BITMIME 250-SMTPUTF8 250-AUTH LOGIN PLAIN 250 SIZE 10485760
Check STARTTLS (587) or your custom ports
openssl s_client -starttls smtp -connect smtp.example.com:587 -servername smtp.example.com \ -crlf -quiet
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.pem
if needed.DNS: If
smtp.example.com
still 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.
Happy Coding !
Subscribe to my newsletter
Read articles from Shree directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
