Posted in Code, Linux/Unix on 15th October 2010, 10:17 pm by Stuart
The other day a colleague was testing some code which relied on sending mail to a local mailserver and it was failing when the mailserver couldn’t be found. Needing to install postfix seemed overkill so I decided to look into what could be done to make a fake smtp service.
All that was required was something to pretend to be a real SMTP service as we didn’t need to view the messages at all.
Here’s the snippet I came up with using the smtpd module in Python:
#!/usr/bin/env python """A noddy fake smtp server.""" import smtpd import asyncore class FakeSMTPServer(smtpd.SMTPServer): """A Fake smtp server""" def __init__(*args, **kwargs): print "Running fake smtp server on port 25" smtpd.SMTPServer.__init__(*args, **kwargs) def process_message(*args, **kwargs): pass if __name__ == "__main__": smtp_server = FakeSMTPServer(('localhost', 25), None) try: asyncore.loop() except KeyboardInterrupt: smtp_server.close()
To use this, save the above as fake_stmp.py and:
chmod +x fake_smtp.py sudo ./fake_smtp.py
NOTE: Running this requires sudo to bind to port 25 as binding any port < 1024 requires superuser privileges.
Clearly you could easily adapt that to do something more useful if you want to see what's in the messages sent, either by writing messages to a file or printing them to stdout.
If printing them to stdout is what you need then there's also smtpd.DebuggingServer which is a subclass of SMTPServer which prints messages out to stdout. Using that is even easier and can be done with the following one liner:
sudo python -m smtpd -n -c DebuggingServer localhost:25
Again we use sudo in this case because we’re using port 25 if you don’t want that you can use a port higher than 1024.
To test this out we can use telnet like so:
$ telnet localhost 25 Trying 127.0.0.1... Connected to localhost.localdomain. Escape character is '^]'. 220 localhost6.localdomain6 Python SMTP proxy version 0.2 HELO localhost 250 localhost6.localdomain6 MAIL FROM: email@example.com 250 Ok RCPT TO: firstname.lastname@example.org 250 Ok DATA 354 End data with
. subject: Hello to: email@example.com This is my message . 250 Ok QUIT 221 Bye Connection closed by foreign host.
Over on the terminal running the debugging server you should see the following:
$ sudo python -m smtpd -n -c DebuggingServer localhost:25 [sudo] password for moo: ---------- MESSAGE FOLLOWS ---------- subject: Hello to: firstname.lastname@example.org This is my message ------------ END MESSAGE ------------