I'm trying to set up an SMTPS server on port 465 using Python and the aiosmtpd library. While I can connect to the server locally using openssl s_client, external mail servers (like Gmail) are unable to connect, reporting a "Connection refused" error.
Here's my current code:
import asyncio
import ssl
from aiosmtpd.controller import Controller
from aiosmtpd.handlers import Debugging
async def main():
ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ssl_context.load_cert_chain(
certfile='./certs/fullchain.pem',
keyfile='./certs/privkey.pem'
)
controller = Controller(
handler=Debugging(),
hostname='0.0.0.0',
port=465,
ssl_context=ssl_context
)
controller.start()
print("SMTPS server started on port 465...")
try:
await asyncio.sleep(3600)
finally:
controller.stop()
if __name__ == "__main__":
asyncio.run(main())
Though it works fine when I disable TLS encryption and change port number to 25.
I've verified that:
openssl s_client -connect my_domain.example.com:465
.I know that there is also SMTP with STARTTLS protocol on port 587, but in my specific use case I need exactly SMTPS on port 465.
Additional information:
Python version: 3.12.3. OS: Ubuntu 24 server
Any help or guidance would be greatly appreciated. Thank you
... external mail servers (like Gmail) are unable to connect, reporting a "Connection refused" error. ... Though it works fine when I disable TLS encryption and change port number to 25.
External email servers always connect to port 25. Specifically they do a DNS MX lookup and then connect to port 25 on the given server. And since you don't have a server on port 25 this will result in "Connection refused". There is no way to specify a different port they should use.
In other words: you can do nothing in your code to make it work, simply because the connecting mail server will not try to use your server on port 465. Port 465 and 587 are instead for user agents (MUA), not for mail servers (MTA).
Also, port 25 actually supports TLS - using STARTTLS the same way as done with port 587.