# Postfix Configuration - Address Manipulation

Up one level | Basic Configuration | UCE Controls | Rate Controls | Resource Controls | Address Manipulation

## Introduction

Although the initial Postfix release has no address rewriting language, it can do quite a bit of address manipulation via table lookup. While a message flows through the Postfix system, its addresses are mangled in the order described in this document.

Unless indicated otherwise, all parameters described here are in the main.cf file. If you change parameters of a running Postfix system, don't forget to issue a postfix reload command.

All mail:

- Rewrite addresses to standard form

- Canonical address mapping

- Address masquerading

- Virtual address mapping

- Relocated users table

- Mail transport switch

Local delivery:

- Alias database

- Per-user .forward files

- Non-existent users

## Rewrite addresses to standard form

Before the cleanup daemon runs an address through any lookup table, it first rewrites the address to the standard user@fully.qualified.domain form, by sending the address to the trivial-rewrite daemon. The purpose of rewriting to standard form is to reduce the number of entries needed in lookup tables. The Postfix trivial-rewrite program implements the following hard-coded address manipulations:

Rewrite @hosta,@hostb:user@site to user@site
  The source route feature has been deprecated. Postfix has no ability to handle such addresses, other than to strip off the source route.

Rewrite site!user to user@site
  This feature is controlled by the boolean swap_bangpath parameter (default: yes). The purpose is to rewrite UUCP-style addresses to domain style. This is useful only when you receive mail via UUCP, but it probably does not hurt otherwise.

Rewrite user%domain to user@domain
  This feature is controlled by the boolean allow_percent_hack parameter (default: yes). Typically, this is used in order to deal with monstrosities such as user%domain@otherdomain.

Rewrite user to user@$myorigin
  This feature is controlled by the boolean append_at_myorigin parameter (default: yes). The purpose is to get consistent treatment of user on every machine in $myorigin.

  You probably should never turn off this feature, because a lot of Postfix components expect that all addresses have the form user@domain.

  If your machine is not the main machine for $myorigin and you wish to have some users delivered locally without going via that main machine, make an entry in the virtual table that redirects user@$myorigin to user@$myhostname.

Rewrite user@host to user@host.$mydomain
  This feature is controlled by the boolean append_dot_mydomain parameter (default: yes). The purpose is to get consistent treatment of different forms of the same hostname.

  Some will argue that rewriting host to host.$mydomain is bad. That is why it can be turned off. Others like the convenience of having the local domain appended automatically.

Rewrite user@site. to user@site (without the trailing dot).

## Canonical address mapping

Before the cleanup daemon stores inbound mail into the incoming queue, it uses the canonical table to rewrite all addresses in message envelopes and in message headers, local or remote. The mapping is useful to replace login names by Firstname.Lastname style addresses, or to clean up invalid domains in mail addresses produced by legacy mail systems.

Canonical mapping is disabled by default. To enable, edit the canonical_maps parameter in the main.cf file and specify one or more lookup tables, separated by whitespace or commas. For example:

  canonical_maps = hash:/usr/local/etc/postfix/canonical

In addition to the canonical maps which are applied to both sender and recipient addresses, you can specify canonical maps that are applied only to sender addresses or to recipient addresses. For example:

  sender_canonical_maps = hash:/usr/local/etc/postfix/sender_canonical

  recipient_canonical_maps = hash:/usr/local/etc/postfix/recipient_canonical

The sender and recipient canonical maps are applied before the common canonical maps.

Sender-specific rewriting is useful when you want to rewrite ugly sender addresses to pretty ones, and still want to be able to send mail to the those ugly address without creating a mailer loop.

## Address masquerading

Address masquerading is a method to hide all hosts inside a domain behind their mail gateway, and to make it appear as if the mail comes from the gateway itself, instead of from individual machines.

Address masquerading is disabled by default. To enable, edit the masquerade_domains parameter in the main.cf file and specify one or more domain names separated by whitespace or commas. For example:

  masquerade_domains = $mydomain

In this example, addresses of the form user@host.$mydomain would be rewritten to user@$mydomain.

The masquerade_exceptions configuration parameter specifies what user names should not be subjected to address masquerading. Specify one or more user names separated by whitespace or commas. For example,

  masquerade_exceptions = root

By default, Postfix makes no exceptions.

Subtle point: by default, address masquerading is applied only to message headers and to envelope sender addresses, but not to envelope recipients. This allows you to use address masquerading on a mail gateway machine, while still being able to forward mail from outside to users on individual machines.

In order to subject envelope recipient addresses to masquerading, too, specify (only available with Postfix versions after 20010802):

  masquerade_classes = envelope_sender, envelope_recipient, header_sender, header_recipient

If you do this, Postfix will no longer be able to send mail to individual machines.

## Virtual address mapping

After applying the canonical and masquerade mappings, the cleanup daemon uses the virtual table to redirect mail for all recipients, local or remote. The mapping affects only envelope recipients; it has no effect on message headers or envelope senders. Virtual lookups are useful to redirect mail for virtual domains to real user mailboxes, and to redirect mail for domains that no longer exist. Virtual lookups can also be used to transform Firstname.Lastname back into UNIX login names, although it seems that local aliases are a more appropriate vehicle.

Virtual mapping is disabled by default. To enable, edit the virtual_maps parameter in the main.cf file and specify one or more lookup tables, separated by whitespace or commas. For example:

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

Addresses found in virtual maps are subjected to another iteration of virtual mapping, but are not subjected to canonical mapping, in order to avoid loops.

## Relocated users table

Next, the queue manager runs each recipient name through the relocated database. This table provides information on how to reach users that no longer have an account, or what to do with mail for entire domains that no longer exist. When mail is sent to an address that is listed in this table, the message is bounced with an informative message.

Lookups of relocated users are disabled by default. To enable, edit the relocated_maps parameter in the main.cf file and specify one or more lookup tables, separated by whitespace or commas. For example:

  relocated_maps = hash:/usr/local/etc/postfix/relocated

## Mail transport switch

Once the queue manager has established the destination of a message, the optional transport table controls how the message will be delivered (this table is used by the address rewriting and resolving daemon). By default, everything is sent via the smtp transport. The transport table can be used to send mail to specific sites via UUCP, or to send mail to a really broken mail system that can handle only one SMTP connection at a time (yes, such systems exist and people used to pay real money for them).

Transport table lookups are disabled by default. To enable, edit the transport_maps parameter in the main.cf file and specify one or more lookup tables, separated by whitespace or commas. For example:

  transport_maps = hash:/usr/local/etc/postfix/transport

## Alias database

When mail is to be delivered locally, the local delivery agent runs each local recipient name through the aliases database. The mapping does not affect addresses in message headers. Local aliases are typically used to implement distribution lists, or to direct mail for standard aliases such as postmaster to real people. The table can also be used to map Firstname.Lastname addresses to login names.

Alias lookups are enabled by default. The default configuration depends on the system environment, but it is typically one of the following:

  alias_maps = hash:/etc/aliases
  alias_maps = dbm:/etc/aliases, nis:mail.aliases

The path to the alias database file is controlled via the alias_database configuration parameter. The value is system dependent. Usually it is one of the following:

  alias_database = hash:/etc/aliases (4.4BSD, LINUX)
  alias_database = dbm:/etc/aliases (4.3BSD, SYSV<4)
  alias_database = dbm:/etc/mail/aliases (SYSV4)

For security reasons, deliveries to command and file destinations are performed with the rights of the alias database owner. A default userid, default_privs, is used for deliveries to commands/files in root-owned aliases.

## Per-user .forward files

Users can control their own mail delivery by specifying destinations in a file called .forward in their home directories. The syntax of these files is the same as with system aliases, except that the lookup key and colon are not present.

## Non-existent users

When the local delivery agent finds that a message recipient does not exist, the message is normally bounced to the sender ("user unknown"). Sometimes it is desirable to forward mail for non-existing recipients to another machine. For this purpose you can specify an alternative destination with the luser_relay configuration parameter.

Alternatively, mail for non-existent recipients can be delegated to an entirely different message transport, as specified with the fallback_transport configuration parameter. For details, see the local delivery agent.

luser_relay can specify one address. It is subjected to $name expansions. The most useful examples are:

$user@other.host
  The bare username, without address extension, is prepended to @other.host. For example, mail for username+foo is sent to username@other.host.

$mailbox@other.host
  The entire original recipient localpart, including address extension, is prepended to @other.host. For example, mail for username+foo is sent to username+foo@other.host.

sysadmin+$user
  The bare username, without address extension, is appended to sysadmin. For example, mail for username+foo is sent to sysadmin+username.
sysadmin+$mailbox
  The entire original recipient localpart, including address extension, is appended to sysadmin. For example, mail for username+foo is sent to sysadmin+username+foo.

Up one level | Basic Configuration | UCE Controls | Rate Controls | Resource Controls | Address Manipulation