Using Postfix for Secure SMTP Gateways

Improve your site's e-mail hygiene and make life difficult for spammers and hackers.
The Quickness and Dirtiness Explained

As cool as that was, it may not have been enough to get postfix to do what needs to be done for your network. And even if it was, it behooves you to dig a little deeper: ignorance nearly always leads to bad security. Let's take a closer look at what we just did, and then move on to even niftier postfix tricks.

First, why did so little information need to be entered in The only thing we added to it was our fully qualified domain name. In fact, depending on how your machine is configured, it may not have even been necessary to supply that!

This is because postfix uses system calls such as gethostname to glean as much information as possible directly from your kernel. If given the fully qualified domain name of your host, it's smart enough to know that everything past the first “.” is your name-domain, and it sets the variable mydomain accordingly.

You may need to add additional names to mydestination if your server has more than one FQDN (that is, multiple “A” records in your domain's DNS). For example, if your SMTP gateway doubles as your public FTP server, and thus has the name “ftp” associated with it in addition to its normal host name, your mydestination declaration might look something like this:

mydestination = $myhostname, localhost.$mydomain, ftp://www.$mydomain, $mydomain

It's important that any name by which your server can be legitimately referred to is contained in this line.

There were two other interesting things we did in the “quick and dirty” procedure. One was to start postfix with the command postfix start. Just as BIND uses ndc to control the various processes that comprise BIND, the postfix command can be used to manage postfix. Like BIND, postfix is actually a suite of commands, dæmons and scripts rather than a single monolithic program.

The most common invocations of the postfix command are postfix start, postfix stop and postfix reload. Start and stop are obvious; reload causes postfix to reload its configuration files without stopping and restarting. Another handy one is postfix flush, which forces postfix to immediately attempt to send all queued messages. This is particularly useful after changing a setting that you think may have been causing problems—in the event that your change worked, all messages delayed by the problem go out immediately. They'd go out regardless, but not as quickly.

The other thing we did was to add a line to /etc/aliases to divert root's e-mail to an unprivileged account. This is good healthy paranoia: we don't want to have to log in as the superuser for mundane activities such as viewing system reports, which are sometimes e-mailed to root. Be careful, however: if your unprivileged account uses a “.forward” file to forward your mail to some other system, you may wind up sending administrative messages over public bandwidth in clear text!

Aliases Revealed

As alluded to in the quick and dirty procedure, aliases are also useful for mapping e-mail addresses for users who don't actually have accounts on the SMTP gateway. This practice has two main benefits. First, most users prefer meaningful e-mail names and short host /domain names, e.g., “” rather than “”. Second, you probably don't want your users connecting to and storing mail on a publicly accessible server. Again, common sense tells us that any server the unwashed masses can commune with must be kept at arm's length. The greater the separation between public servers and private servers, the better. (And don't forget, POPmail passwords are transmitted in clear text!)

Still another use of aliases is the maintenance of mailing lists. An alias can point to not only an address or comma-separated list of addresses, but also to a mailing list. This is achieved with the :include:tag—without this, postfix will append mail to the file specified rather than using the file to obtain recipients. (This is a feature, not a bug; it's useful sometimes to write certain types of messages to a text file rather than to a mailbox.)

Here's part of an example alias file that contains all of these types of mappings:

postmaster:     root
mailer-daemon:  root
hostmaster:     root
root:           bdewinter
mailguys:       bdewinter,mick.bauer
clients:        :include:/etc/postfix/clientlist.txt
spam-reports:   /home/bdewinter/spambucket.txt

One warning: if an alias points to a different mail server, that server must belong to a domain for which the SMTP gateway is configured to relay mail (i.e., either that server's FQDN or its domain must be listed in the mydestination declaration in

Don't forget to run either newaliases or, hipper still, postalias /etc/aliases anytime you edit aliases. The postalias command is hipper because it can accept any correctly formatted alias file as its input. Both commands compress the alias file into a database file that can be searched repeatedly and rapidly each time a destination address is parsed; neither postfix nor sendmail directly use the text version of aliases.

If you have a large number of users and/or internal mail servers, alias-file updates lend themselves to automation, especially via Secure Shell (ssh) and Secure Copy (scp). Using scp with null-passphrase RSA (or DSS/El Gamal) keys, your internal mail servers can periodically copy their local alias files to the SMTP gateway, which can then merge them into a new /etc/aliases followed by postalias /etc/aliases. (Unfortunately, telling you exactly how to use scp/ssh is beyond the scope of this article.) This practice is especially useful in large organizations where different people control different mail servers: day-to-day e-mail account administration can be kept decentralized.



Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

how to local smtp

Anonymous's picture

Hello and thank you for the guide.

I changed inet_interfaces = localhost but it didnt worked.
I can receive but i can not send eimail
I quote the cf in order to have a look.

# See /usr/share/postfix/ for a commented, more complete version

# Debian specific: Specifying a file name will cause the first
# line of that file to be used as the name. The Debian default
# is /etc/mailname.
#myorigin = /etc/mailname

smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
biff = no

# appending .domain is the MUA's job.
append_dot_mydomain = no

# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h

readme_directory = no

# TLS parameters
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.

myhostname = localhost
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = $myhostname, localhost.$mydomain, $mydomain
relayhost =
mynetworks = [::ffff:]/104 [::1]/128,

mailbox_command = procmail -a "$EXTENSION"
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = localhost
default_transport = error
relay_transport = error
inet_protocols = ipv4

Did i missed something?

Sending from localhost only

Robsteranium's picture

Apparently setting the following in will ensure that only localhost can send emails:

inet_interfaces = localhost