GENERIC(5)
π NAME π
okay so bestie, welcome to generic β it's the Postfix generic table format page, and yes it came out of the File Formats Manual section, we love a format legend π
β¨ SYNOPSIS β¨
the whole vibe in three little commands, no notes:
postmap /etc/postfix/generic
postmap -q "string" /etc/postfix/generic
postmap -q - /etc/postfix/generic <inputfile
periodt π
πΈ DESCRIPTION πΈ
okay so the generic(5) table is optional, and what it does is specify an address mapping that kicks in when mail is delivered. it's literally the mirror image of canonical(5) mapping, which does its thing when mail is received. two sisters, opposite directions, both iconic π¦
typically you'd pull out the generic(5) table on a system that does not have a valid Internet domain name and that uses something like localdomain.local instead. so then the smtp(8) client uses the generic(5) table to turn local mail addresses into valid Internet mail addresses whenever mail has to be sent across the Internet. there's a whole EXAMPLE section at the end of this doc, go look, it eats π₯
so the generic(5) mapping hits both:
- message header addresses (aka the addresses that appear inside messages), and
- message envelope addresses (aka for example the addresses used in SMTP protocol commands)
both. every time. main character behavior tbh π
normally the generic(5) table is given as a text file, and that file serves as input to postmap(1) so it can create an indexed file for fast lookup. speed queen β‘
run this to rebuild a default-type indexed file after you change the text file:
postmap /etc/postfix/generic
or run this if you want to specify an explicit type:
postmap type:/etc/postfix/generic
the default indexed file type gets configured with the default_database_type parameter. depending on the platform, that could be one of lmdb:, cdb:, hash:, or dbm: β note: 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, so that's a you problem bestie, no cap π
OR, alternatively β and this is the fun part β the table can be provided 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 happen in a slightly different way, described below under "REGULAR EXPRESSION TABLES" or "TCP-BASED TABLES". keep scrolling β¨
π CASE FOLDING π
the search string gets folded to lowercase before the database lookup. simple as that.
BUT β as of Postfix 2.3, the search string is not case folded when you're using database types such as regexp: or pcre:, because those lookup fields can match both upper and lower case. so those ones are just built different π
π TABLE FORMAT π
here's the input format for the postmap(1) command, bestie:
pattern resultβ when the pattern matches a mail address, replace it with the corresponding result. match made in heaven fr fr π- blank lines and comments β empty lines and whitespace-only lines get ignored, and so do lines whose first non-whitespace character is a
#. silent. unbothered. irrelevant π - multi-line text β a logical line starts with non-whitespace text. a line that starts with whitespace continues a logical line. it's giving paragraph energy π¦
π TABLE SEARCH ORDER π
when the lookups come from indexed files like DB or DBM, or from networked tables like NIS, LDAP or SQL, every user@domain query produces a whole sequence of query patterns, listed below.
each query pattern gets sent to each specified lookup table before the next query pattern is even tried, and this goes on until a match is found. patient, thorough, organized β the way a real one operates β¨
user@domain addressβ replaceuser@domainbyaddress. this form has the highest precedence, she's first in line πuser addressβ replaceuser@sitebyaddresswhensiteis equal to$myorigin, whensiteis listed in$mydestination, or when it's listed in$inet_interfacesor$proxy_interfaces. so many conditions, so much range π@domain addressβ replace other addresses indomainbyaddress. this form has the lowest precedence. someone has to be last, bestie π
πͺ RESULT ADDRESS REWRITING πͺ
the lookup result is subject to address rewriting, and here's the tea:
- when the result has the form
@otherdomain, the result becomes the same user inotherdomain. glow-up preserved, identity intact π«Ά - when
append_at_myorigin=yes, append"@$myorigin"to addresses without"@domain" - when
append_dot_mydomain=yes, append".$mydomain"to addresses without".domain"
π ADDRESS EXTENSION π
when a mail address localpart contains the optional recipient delimiter β like user+foo@domain β the lookup order becomes this exact sequence:
user+foo@domain, user@domain, user+foo, user, and @domain
and the propagate_unmatched_extensions parameter controls whether an unmatched address extension (+foo) gets propagated to the result of the table lookup. iykyk πΈ
π§ REGULAR EXPRESSION TABLES π§
this section explains how the table lookups change when the table is given in the form of regular expressions. want the full regular expression lookup table syntax? check regexp_table(5) or pcre_table(5), they've got you π
each pattern is a regular expression that gets applied to the entire address being looked up. so that means user@domain mail addresses are not broken up into their user and @domain constituent parts, and user+foo is not broken up into user and foo. they stay whole. integral. unbothered π¦
patterns are applied in the order specified in the table, until a pattern is found that matches the search string. first match wins, no tiebreakers needed π
results are the same as with indexed file lookups, plus one extra feature that's genuinely so good: parenthesized substrings from the pattern can be interpolated as $1, $2 and so on. iconic β¨
π₯οΈ TCP-BASED TABLES π₯οΈ
this section explains how the table lookups change when lookups get directed to a TCP-based server. for the whole description of the TCP client/server lookup protocol, go read tcp_table(5). this feature is available in Postfix 2.5 and later π
every lookup operation uses the entire address once. so again, user@domain mail addresses are not broken up into their user and @domain constituent parts, and user+foo is not broken up into user and foo. same rule, same energy π
results are the same as with indexed file lookups. periodt π
π EXAMPLE π
here's a generic mapping with an indexed file in the wild. when mail gets sent to a remote host via SMTP, this replaces his@localdomain.local by his ISP mail address, replaces her@localdomain.local by her ISP mail address, and replaces other local addresses by his ISP account with an address extension of +local. (this example assumes the ISP supports "+" style address extensions β no cap, check first π«Ά)
/etc/postfix/main.cf:
smtp_generic_maps = hash:/etc/postfix/generic
/etc/postfix/generic:
his@localdomain.local hisaccount@hisisp.example
her@localdomain.local heraccount@herisp.example
@localdomain.local hisaccount+local@hisisp.example
run this command every single time the table changes, bestie, don't skip it:
postmap /etc/postfix/generic
and instead of hash, some systems use dbm database files. want to find out what tables your system supports? run:
postconf -m
πβ¨
π BUGS π
okay so this is the one sad part: the table format does not understand quoting conventions. that's it. that's the whole bug. no quotes for you π
βοΈ CONFIGURATION PARAMETERS βοΈ
these main.cf parameters are especially relevant, bestie. the text below is only a parameter summary β go read postconf(5) for more details, examples included π
smtp_generic_maps(empty) β optional lookup tables that perform address rewriting in the Postfix SMTP client, typically to transform a locally valid address into a globally valid address when sending mail across the Internet. literally the star of the show πpropagate_unmatched_extensions(canonical, virtual) β what address lookup tables copy an address extension from the lookup key to the lookup result π«Ά
other parameters of interest β yes there's more, we're not done:
inet_interfaces(all) β the local network interface addresses that this mail system receives mail on πproxy_interfaces(empty) β the remote network interface addresses that this mail system receives mail on by way of a proxy or network address translation unit π°οΈmydestination($myhostname, localhost.$mydomain, localhost) β the list of domains that are delivered via the$local_transportmail delivery transport π¬myorigin($myhostname) β the domain name that locally-posted mail appears to come from, and that locally posted mail is delivered to πowner_request_special(yes) β enable special treatment forowner-listnameentries in thealiases(5)file, and don't splitowner-listnameandlistname-requestaddress localparts when therecipient_delimiteris set to"-"π
π SEE ALSO π
postmap(1), Postfix lookup table managerpostconf(5), configuration parameterssmtp(8), Postfix SMTP client
the holy trinity honestly π
π README FILES π
use "postconf readme_directory" or "postconf html_directory" to locate this information β
ADDRESS_REWRITING_README, address rewriting guideDATABASE_README, Postfix lookup table overviewSTANDARD_CONFIGURATION_README, configuration examples
required reading, bestie, do your homework πβ¨
π LICENSE π
the Secure Mailer license must be distributed with this software. legal girlies stay winning π
π°οΈ HISTORY π°οΈ
a genericstable feature appears in the Sendmail MTA. so yes, this concept has lore π
and this feature is available in Postfix 2.2 and later. old but gold π
π AUTHOR(S) π
- Wietse Venema IBM T.J. Watson Research P.O. Box 704 Yorktown Heights, NY 10598, USA
- Wietse Venema Google, Inc. 111 8th Avenue New York, NY 10011, USA
two addresses, one legend π«Ά
and that's the whole page bestie!! this was generic(5) from the File Formats Manual β thank you for coming to my ted talk, see u in the next lookup, 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