How To Make Sure Postfix Never Sends Actual Emails From Your Development Machine
If you’re building any kind of application or service, you want to make absolutely sure that you don’t accidentally send out emails to real email addresses while you’re developing or testing. There’s no excuse for doing so, and it makes you look bad.
The problem is: you need to “send” emails and check to make sure they look right, and it would be even better if it “just worked” (while still making sure you don’t make a mistake).
OS X comes installed with Postfix, which is an SMTP mail server. By default, it does have the capability to send emails to external addresses. Using Postfix is great, because it can be used by everything with minimal configuration.
Once we disable Postfix from being able to send emails to external addresses, we can use an application like MockSMTP to preview the email and rest easy that we aren’t spamming people or hurting our reputation.
Checking if it’s possible for email to be sent from our development machine
In order to ensure we are unable to send emails out to external clients, we have to make sure that none of the default SMTP ports are open on our development machine.
Any of the following are considered “default” SMTP ports:
- 25
- 2525
- 587
- 465
- 2526
Use the following command to see if any of these ports are open (meaning that email could be sent to the outside world, which is a very bad thing):
sudo lsof -i -P | grep -E ':2525|:2526|:25|:587|:465'
If there are any results, we need to reconfigure our SMTP servers to deny access to the external network.
Disabling Postfix from accessing external networks
Thankfully, it’s very easy to prevent Postfix from accessing external networks. All that is involved is commenting out a few lines in the configuration file.
The configuration file we are looking for is master.cf
. It’s usually stored in the following location:
/private/etc/postfix/master.cf
Open this file and look for any lines that containing inet
. For example:
smtp inet n - n - 1 postscreen
submission inet n - n - - smtpd
Comment these lines out with a #
:
#smtp inet n - n - 1 postscreen
#submission inet n - n - - smtpd
These entries are what allow postfix to access the external network:
inet The service listens on a TCP/IP socket and is accessible via the network. source
Commenting out these lines will only allow UNIX or local-domain ports to be used by Postfix. MockSMTP should still work, and you won’t run the risk of sending out emails to actual customers.
After you are finished, run the following command in the terminal:
sudo postfix reload
Other things to look out for
There are a few other things you’ll want to check before you can rest easy:
- You might have another SMTP Server installed on your development machine, so you’ll want to double check what you have installed and running as a background service.
- If you’re using an external service to handle emails in your application (such as Postmark), you’ll want to make sure that you have separate development and production configurations and that both are configured correctly. You’ll also want to check that you don’t override those configurations anywhere in your project.
Testing
After you’ve finished making sure your development machine’s SMTP server can’t send out real emails, you can use the following command to make sure MockSMTP is working (make sure it’s open first!):
date | mail -s testing YOUR_EMAIL_ADDRESS
UPDATE: Configuring your Rails app
Unfortunately, this process breaks devilering emails from a Rails app. My best guess for this is that Rails uses the TC/IP ports, and not the UNIX or local ports. Thankfully, the MockSMTP site include a code snippet you can use.
This goes in config/environments/development.rb
:
config.action_mailer.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
:address => "localhost",
:port => 1025,
:domain => "www.yourdomain.com"
}