Postfix – virtual domains

Postfix – virtual domains

This article concentrates on the installation and configuration of Postfix. The emphasis is on the
FreeBSD environment although the basics should apply to most operating systems. Virtual domains
are touched upon briefly, but Postfix – virtual domains
contains more information about the three different types of virtual domains and is recommended
reading for anyone contemplating implementation.

Postfix is an MTA designed to be
a replacement for sendmail as well as being fast, secure, and easy to configure.
Why was it designed to replace sendmail? Easy. sendmail is a very widely used MTA with a quite complex configuration.
It also handles most of the mail on the Internet not to mention the many private networks around the world.

I have been running Postfix on some of my mail servers since August 2001. At least, that’s when I think I first installed
Postfix on this web server, which also doubles as a mail server. I’ve been happy with it mostly because I’ve been able
to easily configure my virtual domains (i.e. handle mail for multiple domains) and block mail from certain sources.
Postfix is now my MTA of choice.

In this article, I will outline how to install Postfix and how to configure it to accept mail from more then one
domain. I’m using virtual_mapping for my virtual domains. There are other ways to do virtual domains which are far
more suitable for large scale operations. Search the newsgroup mailing.postfix.users for the phrase
“Some notes on relay, local and virtual domains”.


It will be useful to read and understand the Postfix Anatomy.
That will help you to understand how virtual address mapping, aliases, etc relate to the various Postfix components.
Postfix has many different parts, each with a very distinct function. By keeping the programs smaller
and with very distinct separation of tasks, it it both easier to code and to secure the system.

And don’t forget the Postfix FAQ.


I install just about everything using the ports tree.

cd /usr/ports/mail/postfix
make install

Right away you will be presented with the following choices. I wanted only
PCRE because of my header checks. If you don’t
understand or need any of the optional components shown below, you can safely
omit it without worry.

*--------------------- Postfix configuration options ---------------------*
|                                                                         |
| Please select desired options:                                          |
| *---------------------------------------------------------------------* |
| | [X] PCRE      Perl Compatible Regular Expressions                   | |
| | [ ] SASL      Cyrus SASL (Simple Authentication and Security Layer) | |
| | [ ] DB3       Berkeley DB3 (required if SASL also built with DB3)   | |
| | [ ] MySQL     MySQL map lookups                                     | |
| | [ ] PgSQL     PostgreSQL map lookups                                | |
| | [ ] OpenLDAP  OpenLDAP map lookups                                  | |
| | [ ] Test      SMTP/LMTP test server and generator                   | |
| | [ ] TLS       Secure Sockets Layer and Transport Layer Security     | |
| | [ ] IPv6      IPv6 support (not KAME official)                      | |
| |                                                                     | |
| |                                                                     | |
| |                                                                     | |
| |                                                                     | |
| |                                                                     | |
| |                                                                     | |
| |                                                                     | |
| *---------------------------------------------------------------------* |
|                         [  OK  ]       Cancel                           |

I was asked this question during the install:

Added group "postfix".
Added group "maildrop".
Added user "postfix".
You need user "postfix" added to group "mail".
Would you like me to add it [y]? y

As you can see, I said yes. I suggest you do the same. Then I was asked:

Would you like to activate Postfix in /etc/mail/mailer.conf [n]? y

For more information on mailer.conf, please read man 5 mailer.conf.

On my P233 box, it took about 10 or 15 minutes to compile the code.

During the install, you will see a couple of messages which you need to pay attention to (NOTE:
The following is from Postfix 2.2.4,1) under FreeBSD 4.*:

If you have postfix configured in your /etc/mail/mailer.conf (answered yes to
the previous question) and would like to enable postfix to start at boot time,
please set these variables in your /etc/rc.conf file:


This will disable Sendmail completely.

The above was an install under 4.11. For a recent install of 6.0, the port
told me to use use these settings instead:

# for postfix and not sendmail

For FreeBSD 7.0:


In both FreeBSD 4.* and 6.*, the following applied. You may wish to disable some Sendmail-specific daily maintenance
routines in your /etc/periodic.conf file:


I made those changes to my system as indicated above. I had to create /etc/periodic.conf.
The first set of changes ensure your system operates Postfix and not sendmail. The second set of changes avoids this
error in your daily run output message (these are emailed to you automatically by the system).

Mail in submit queue:
mailq: illegal option -- A
mailq: fatal: usage: mailq [options]


Postfix has a very well laid out configuration page. I urge you to read
before proceeding. Understanding the rest of this article involves reading that URL first.

The primary configuration file for Postfix is /usr/local/etc/postfix/ Unless otherwise
mentioned, all settings are made in that file. There are many examples in that directory. My count was 36 sample-* files.
The comments in make frequent reference to the example files.

Names used in this article

For the purposes of this article, we’ll assume the hostname of the computer is
(named after my cat). For those of you writing documentation for others,
you should know that is reserved for use in documentation.

How to not mess up when making changes

When making configuration changes, I suggest using the SOFT BOUNCE feature of Postfix. Please refer
to for more information. It’s the first setting in there. This will
allow you to make mistakes without rejecting all incoming mail….

What domain to use in outbound mail

I didn’t make any changes here. I left things as the default. You may use to experiment with that.

This is covered in What domain to use in outbound mail.

What domains to receive mail for

For my example, gus is a stand-alone box. It does not handle mail for anything other than itself.
Therefore, the default setting is sufficient.

myorigin = $mydomain

This is covered in What domains to receive mail for.


Aliases are documented under Postfix Configuration – Address Manipulation.
The default setting is:

alias_maps = hash:/etc/aliases

On FreeBSD systems, the file is actually /etc/mail/aliases. Therefore you should change this setting
to this:

alias_maps = hash:/etc/mail/aliases

After modifying an alias file, you should create the corresponding database file by issuing the following command:

/usr/local/sbin/postalias /etc/mail/aliases

That should be enough

With the above changes, I had enough to be able to send and receive mail on the box. But there’s more. I want to
create virtual domains and allow the box to handle mail for that too.

What domains to receive mail for

The official documentation for this section is What domains to receive mail for.

In this example, I will add two virtual domains to this box:


I changed the default mydestination setting to this value (all on one line!):

mydestination = $myhostname, localhost.$mydomain, /usr/local/etc/postfix/mydestination

In the file /usr/local/etc/postfix/mydestination, I added the following entries

Then I restarted Postfix so it would reread the configuration file:

/usr/local/sbin/postfix reload

I was then able to send test messages to both and This was OK for my
setup, but what if those are two different people? What you need then is virtual address mapping.

Virtual address mapping

The official documentation for this feature is Virtual address mapping.

Virtual address mapping will allow you to map an address in a virtual domain to a real address.
For example, let’s assume there are two people named Dan on this box. One has a login of
dan and the other has a login dtm. What we want is for the address translations to occur:

virtual addressreal address

To implement this in Postfix, we would add the following entry to the configuration file:

virtual_maps = hash:/usr/local/etc/postfix/virtual_maps

Then add this to the file /usr/local/etc/postfix/virtual_maps:         DOMAIN     dan         DOMAIN     dtm

It is very important to know that these destination addresses are
actually @$mydomain, which in
this case is If you actually wish to deliver to local users and not
users in the given domain, then append @localhost to the names. For example:     dan@localhost     dtm@localhost

Similarly, you can also forward the message to people in other domains:         DOMAIN         DOMAIN

Anything can be used in place of DOMAIN; it is
ignored. But using DOMAIN will emphasis to
the reader that the line signifies the start of the domain. It
also required for a Postfix-style virtual domain, which is what we
are using here. See man 5 virtual
for more information.

In this case, Postfix will accept the incoming mail and relay it to the mail servers for and

After creating your mapping file, you need to create the database file from which Postfix will look up the mappings:

/usr/local/sbin/postmap /usr/local/etc/postfix/virtual_maps

Then restart Postfix:

/usr/local/sbin/postfix reload

Virtual address mapping – yes, there’s more!

In the above example, we put all of our virtual mappings into one file. If you have several domains,
or many different virtual hosts, it might be useful to use multiple files. That’s entirely optional.

For what it’s worth, I actually put my mappings and aliases into another directory: /usr/local/etc/postfix-config/.
For example, contains aliases, and contains virtual address mappings.

What clients to relay mail for

The official documentation for this is What clients to relay mail for.

By default, Postfix will relay mail for clients in authorized networks and in authorized domains.

The authorized networks setting is controlled by the mynetworks directive.
The default is to authorize all clients in the IP subnetworks that the local machine is attached to. I just
found this out the hard way. I just checked the mail server I run at home. It handles most of my outgoing
mail and some incoming mail. I discovered it was an open relay for it’s /24 on the public side. Don’t worry,
I just changed that.

WARNING! If your mail server is directly connected to a public network
(e.g. the Internet), make sure you set mynetworks appropriately. If you do not,
then by default, it will relay for all of that subnet. That means anyone, and I mean anyone, will be able
to abuse your mail server.

Here is my setting for mynetworks:

mynetworks =

This means that anyone on my local subnet ( and on the machine itself ( can send outgoing
mail through this host.

I discovered this problem with the following command:

/usr/local/sbin/postconf | grep mynetworks

The authorized domains setting is controlled by the relay_domains. The default
setting automatically trusts hosts within the domains listed in the
mydestination directive.

Notice when running mergemaster during system upgrade (added on 14 November 2002)

If you are upgrading your system using make world, then remember to be careful
when it comes to upgrade /etc/mail/mailer.conf. If you aren’t, then chances are when
your system reboots into the upgrading OS, you’ll be running Sendmail, not
Postfix. Yes, I feel victim to this, just yesterday when I was upgrading from 4.6-STABLE
to 4.7-STABLE. Luckily, if it can be called lucky, it was only my mail server here at home…

In case it is useful, here is my existing /etc/mail/mailer.conf:

# Execute the Postfix sendmail program, named /usr/local/sbin/sendmail
sendmail        /usr/local/sbin/sendmail
send-mail       /usr/local/sbin/sendmail
mailq           /usr/local/sbin/sendmail
newaliases      /usr/local/sbin/sendmail

Are you using logcheck/security?

If you are, you might want to add these entries to /usr/local/etc/logcheck.ignore:

postfix/cleanup.*: .*: message-id=<.*>
postfix/local.*: to=.*
postfix/pickup.*: .*: uid=0 from=<root>
postfix/qmgr.*: from=<.*>, size=.*, nrcpt=1 (queue active)
postfix/qmgr.*\(queue active\)
postfix/smtp.*: to=.*
postfix/smtp.*: connect to .*: Connection refused.*
postfix/smtp.*: connect to .*: Operation timed out.*
postfix/smtp.*: .*: to=<.*>, relay=.*[.*], .*

postfix/smtpd.*: disconnect from .*[.*]
postfix/smtpd.*: .*: client=.*[.*]
postfix/smtpd.*: connect from .*[.*]

For more information on logcheck:

What’s an MTA?

What’s an MTA? Many people would guess either Mail Transfer Agent or Mail Transport Agent. It can also mean
Message Transfer Agent. Here are a few different definitions:

However, when dealing with SMTP,
an MTA is a mail transport agent.

2 thoughts on “Postfix – virtual domains”

  1. Excellent article.

    Postfix config is simple compared to that other MTA, but there is a lack of simple guides to anything other than the basic settings.

    I was looking for help on a gateway mailserver, and thought I should be using virtual or canonical to relay mail to internal mail hosts, but it is not clear in the help.



  2. A couple of things came to light recently with my own upgrade to 8.0-Release from 7.2-Release using the csup source and rebuild method.

    1. – The startup in rc.conf has changed. It is now a postfix_enable="YES" with the four other sendmail_enable all set to "NO". As per the pkg-message. This is new and discovered after rebooting and Postfix didn’t start.

    2. – Periodic uses the system sendmail binary to send its emails. Placing the WITHOUT_SENDMAIL= true in src.conf will cause sendmail to not be built. It will still work up until you do a ‘make delete-old-libs’, then won’t be found. While a quick temporary work around is easily arranged in libmap.conf, the proper fix is to rebuild sendmail for the new *.so.8 libs.

    This hadn’t bit me before as I’d neglected the ‘make delete-old-libs’ step, but this time wanted to "do it right". So the better path for next time may be to remove the entry from src.conf, let the new sendmail be built, and then do the portupgrade -f postfix last. This will make periodic happy.


Leave a Comment

Scroll to Top