TRANSPORT(5)
π TRANSPORT(5) π
okay bestie, welcome to TRANSPORT(5) from the File Formats Manual β this is the whole vibe on the Postfix transport table format and honestly? it's giving infrastructure chaos in the best way. let's go π¦
β¨ NAME β¨
transport β Postfix transport table format. that's it, that's the name, she's simple but she runs the whole delivery game π
πΈ SYNOPSIS πΈ
postmap /etc/postfix/transport
postmap -q "string" /etc/postfix/transport
postmap -q - /etc/postfix/transport <inputfile
π DESCRIPTION π
the optional transport(5) table maps email addresses β message delivery transports + next-hop destinations. the delivery transports themselves (local, smtp, whatever) live in the master.cf file, and the next-hop destinations are usually hosts or domain names. the table gets searched by the trivial-rewrite(8) daemon. no cap π
this mapping overrides the default transport:nexthop selection that's built into Postfix. here's the whole roster:
local_transport (default: local:$myhostname)
- this is the default for final delivery to domains listed with
mydestination, and for[ipaddress]destinations that match$inet_interfacesor$proxy_interfaces. - in order of decreasing precedence, the nexthop destination is taken from
transport_maps,local_transport, or from the recipient domain.
virtual_transport (default: virtual:)
- this is the default for final delivery to domains listed with
virtual_mailbox_domains. - in order of decreasing precedence, the nexthop destination is taken from
transport_maps,virtual_transport, or from the recipient domain.
relay_transport (default: relay:)
- this is the default for remote delivery to domains listed with
relay_domains. - in order of decreasing precedence, the nexthop destination is taken from
transport_maps,relay_transport,sender_dependent_relayhost_maps,relayhost, or from the recipient domain.
default_transport (default: smtp:)
- this is the default for remote delivery to other destinations.
- in order of decreasing precedence, the nexthop destination is taken from
transport_maps,sender_dependent_default_transport_maps,default_transport,sender_dependent_relayhost_maps,relayhost, or from the recipient domain.
normally the transport(5) table is just a text file that feeds into the postmap(1) command so it can build an indexed file for fast lookups. slay for efficiency β‘
run the command postmap /etc/postfix/transport to rebuild a default-type indexed file every time you change the text file β or run postmap type:/etc/postfix/transport if you wanna specify an explicit type, your call bestie.
the default indexed file type is configured with the default_database_type parameter. depending on your platform this may be one of lmdb:, cdb:, hash:, or dbm: (β οΈ without the trailing ':').
when the table comes from other means like NIS, LDAP or SQL, the same lookups happen as for ordinary indexed files. managing those databases is outside the scope of Postfix β not our problem, not our circus πͺ
alternatively the table can be given as a regular-expression map where patterns are given as regular expressions, or lookups can be directed to a TCP-based server. in those cases the lookups are done in a slightly different way, described below under "REGULAR EXPRESSION TABLES" or "TCP-BASED TABLES" π«Ά
π€ CASE FOLDING π€
the search string gets folded to lowercase before the database lookup. but β as of Postfix 2.3 β the search string is not case folded with database types such as regexp: or pcre: whose lookup fields can match both upper and lower case. lowercase girls only, except when they're not π
π TABLE FORMAT π
the input format for the postmap(1) command goes like this:
pattern resultβ whenpatternmatches the recipient address or domain, use the correspondingresult.- blank lines and comments β empty lines and whitespace-only lines are ignored, and so are lines whose first non-whitespace character is a
'#'. - multi-line text β a logical line starts with non-whitespace text. a line that starts with whitespace continues a logical line.
the pattern specifies an email address, a domain name, or a domain name hierarchy, as described in the section "TABLE SEARCH ORDER".
the result is of the form transport:nexthop and specifies how or where to deliver mail β full breakdown in "RESULT FORMAT" π
π TABLE SEARCH ORDER π
when you're doing lookups from indexed files like DB or DBM, or from networked tables like NIS, LDAP or SQL, patterns are tried in the order listed below (first match wins, bestie, it's a race):
user+extension@domain transport:nexthopβ deliver mail foruser+extension@domainthroughtransporttonexthop.user@domain transport:nexthopβ deliver mail foruser@domainthroughtransporttonexthop.domain transport:nexthopβ deliver mail fordomainthroughtransporttonexthop..domain transport:nexthopβ deliver mail for any subdomain ofdomainthroughtransporttonexthop. β οΈ this applies only when the stringtransport_mapsis not listed in theparent_domain_matches_subdomainsconfiguration setting. otherwise, a domain name matches itself and its subdomains.* transport:nexthopβ the special pattern*represents any address (i.e. it functions as the wild-card pattern, and it's unique to Postfix transport tables π¦).
Note 1: the null recipient address is looked up as$empty_address_recipient@$myhostname(default:mailer-daemon@hostname).
Note 2:user@domainoruser+extension@domainlookup is available in Postfix 2.0 and later.
π RESULT FORMAT π
the lookup result is of the form transport:nexthop. the transport field specifies a mail delivery transport such as smtp or local, and the nexthop field specifies where and how to deliver mail. iconic duo honestly π
the transport field specifies the name of a mail delivery transport β that's the first name of a mail delivery service entry in the Postfix master.cf file.
the nexthop field usually specifies one recipient domain or hostname. in the case of the Postfix SMTP/LMTP client, the nexthop field may contain a list of nexthop destinations separated by comma or whitespace (Postfix 3.5 and later).
the syntax of a nexthop destination is transport dependent. with SMTP, specify a service on a non-default port as host:service, and disable MX (mail exchanger) DNS lookups with [host] or [host]:port. β¨ the [] form is required when you specify an IP address instead of a hostname.
- a null transport and null nexthop field means "do not change": use the delivery transport and nexthop information that would be used when the entire transport table did not exist.
- a non-null transport field with a null nexthop field resets the nexthop information to the recipient domain.
- a null transport field with non-null nexthop field does not modify the transport information.
π EXAMPLES π
wanna deliver internal mail directly while shoving everything else at a mail relay? specify a null entry for internal destinations (do not change the delivery transport or the nexthop information) and a wildcard for all other destinations:
my.domain :
.my.domain :
* smtp:outbound-relay.my.domain
wanna send mail for example.com and its subdomains via the uucp transport to the UUCP host named example? bet:
example.com uucp:example
.example.com uucp:example
when no nexthop destination is specified, Postfix uses (from low to high precedence): the recipient domain, the nexthop specified with relayhost, with sender_dependent_relayhost_maps (for remote deliveries only), with the transport for the address domain class (see DESCRIPTION above), or with sender_dependent_default_transport_maps (for remote deliveries only). for example, the following directs mail for user@example.com via the slow transport to a mail exchanger for example.com β and the slow transport could be configured to run at most one delivery process at a time:
example.com slow:
when no transport is specified, Postfix uses the transport that matches the address domain class (see DESCRIPTION above), or the transport specified with sender_dependent_default_transport_maps (for remote deliveries only). the following sends all mail for example.com and its subdomains to host gateway.example.com:
example.com :[gateway.example.com]
.example.com :[gateway.example.com]
in the above example, the [] suppress MX lookups. this prevents mail routing loops when your machine is the primary MX host for example.com π (chaos prevention, we love to see it)
in the case of delivery via SMTP or LMTP, you may specify host:service instead of just a host:
example.com smtp:bar.example:2025
this directs mail for user@example.com to host bar.example port 2025. instead of a numerical port a symbolic name may be used. specify [] around the hostname if MX lookups must be disabled.
deliveries via SMTP or LMTP support multiple destinations (Postfix >= 3.5):
example.com smtp:bar.example, foo.example
this tries to deliver to bar.example before trying to deliver to foo.example β bar gets first dibs, foo is the backup bestie.
the error mailer can be used to bounce mail:
.example.com error:mail for *.example.com is not deliverable
this causes all mail for user@anything.example.com to be bounced. not me dropping the hammer π
π§ REGULAR EXPRESSION TABLES π§
this section describes how the table lookups change when the table is given in the form of regular expressions. for a description of regular expression lookup table syntax, see regexp_table(5) or pcre_table(5).
each pattern is a regular expression that is applied to the entire address being looked up. so some.domain.hierarchy is not looked up via its parent domains, and user+foo@domain is not looked up as user@domain. no sneaky parent lookups here π
patterns are applied in the order as specified in the table, until a pattern is found that matches the search string.
β οΈ the trivial-rewrite(8) server disallows regular expression substitution of $1 etc. in regular expression lookup tables, because that could open a security hole (Postfix version 2.3 and later). dangerous behavior, we do not stan π«
π₯οΈ TCP-BASED TABLES π₯οΈ
this section describes how the table lookups change when lookups are directed to a TCP-based server. for a description of the TCP client/server lookup protocol, see tcp_table(5). β οΈ this feature is not available up to and including Postfix version 2.4.
each lookup operation uses the entire recipient address once. so some.domain.hierarchy is not looked up via its parent domains, and user+foo@domain is not looked up as user@domain.
results are the same as with indexed file lookups. periodt π
βοΈ CONFIGURATION PARAMETERS βοΈ
Okay bestie, these are the main.cf parameters that actually matter for this whole thing. The tea below is just a summary though β for the full picture, examples and all, go read postconf(5). π
empty_address_recipient(MAILER-DAEMON) β this one is literally who gets the mail that was sent to the null address. Yeah. Mail to nowhere still needs a somebody. π«₯πparent_domain_matches_subdomains(seepostconf -doutput) β a whole list of Postfix features where the patternexample.comALSO matches subdomains ofexample.com, instead of you having to be extra and spell out.example.com. So it's the "I don't wanna type the dot" list. Periodt. πtransport_maps(empty) β optional lookup tables that map a recipient address β(message delivery transport, next-hop destination). This is THE one, the main character of this whole manpage. π
π SEE ALSO π
Go read these next, iykyk:
trivial-rewrite(8)β rewrite and resolve addressesmaster(5)β master.cf file formatpostconf(5)β configuration parameterspostmap(1)β Postfix lookup table manager
π README FILES π
Wanna find these? Run postconf readme_directory or postconf html_directory and they'll tell you where this info lives. πΊοΈβ¨
ADDRESS_REWRITING_READMEβ address rewriting guideDATABASE_READMEβ Postfix lookup table overviewFILTER_READMEβ external content filter
π LICENSE π
The Secure Mailer license must be distributed with this software. Fr fr, don't be shady about it. π
π AUTHOR(S) π
The legend himself, in two chapters:
Wietse Venema
IBM T.J. Watson Research
P.O. Box 704
Yorktown Heights, NY 10598, USA
and
Wietse Venema
Google, Inc.
111 8th Avenue
New York, NY 10011, USA
and that's the whole page babes π this is from the TRANSPORT(5) manual, matching the version your system's got installed with the date stamped on it β if the date up top doesn't match what you're running, go read the local copy, mwah π¦β¨
π¦ where this page comes from
- alpine 3.24: postfix-doc 3.11.7-r0 Β· IPL-1.0 EPL-2.0
- arch rolling: postfix 3.11.7-1 Β· EPL-2.0 OR IPL-1.0 AND BSD-4-Clause-UC
- nixos 26.05: postfix 3.11.7
- nixpkgs unstable: postfix 3.11.7
- ubuntu stonking: postfix 3.11.7-1ubuntu2
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms