Make any suitable lookup table dynamic by adding a sufficiently dynamic lookup method, such as SQLite. If postfix itself delivers the mail (no dovecot etc), the alias
table seems appropriate. I will demonstrate for local
mail (analogous configuration possible for virtual
).
You may keep your existing (e.g. hash:
) lookup(s) and just add the new method:
alias_maps = hash:/etc/aliases sqlite:/etc/postfix/date-dependant-aliases.cf
You might need to install support for the new lookup type. I chose SQLite
, because I do not need to setup a database if my query does not use one.
# /etc/postfix/date-dependant-aliases.cf
dbpath = /dev/null
expansion_limit = 1
query = WITH T (prio, forward_addr, condition) AS ( VALUES (1, 'mark@mydomain.example', '%s' >= ('john' || substr(strftime('%%Y%%m', 'now'),3))), (2, 'devnull', 1=1)) SELECT forward_addr FROM T WHERE '%s' LIKE 'john____' AND condition ORDER BY prio ASC LIMIT 1;
Explanation of the query (note local
delivery agent inserts lowercase key for %s
, other %
need quoting):
WITH T (prio, forward_addr, condition) -- sub-query
AS ( VALUES -- with these 2 rows:
(1, 'mark@mydomain.example', -- 1: real address,
'%s' >= ('john' || substr(strftime('%%Y%%m', 'now'),3))), -- if >= current months alias
-- SQLite doesnt have 2-digit dates in strftime
(2, 'devnull', 1=1)) -- 2: discard, always
SELECT forward_addr FROM T -- postfix only needs the target
WHERE '%s' LIKE 'john____' -- require matching template
-- no REGEXP support; just match 4 arbitrary chararacters
AND condition ORDER BY prio ASC LIMIT 1; -- select best match from sub-query
You should verify the query suits your needs using postmap
:
postmap -q john$(date +'%y%m' -d '+1 year') sqlite:/etc/postfix/date-dependant-aliases.cf
mark@mydomain.example
postmap -q john$(date +'%y%m') sqlite:/etc/postfix/date-dependant-aliases.cf
mark@mydomain.example
postmap -q john$(date +'%y%m' -d '-31 days') sqlite:/etc/postfix/date-dependant-aliases.cf
devnull
postmap -q john1801 sqlite:/etc/postfix/date-dependant-aliases.cf
devnull
Note the propagate_unmatched_extensions
parameter (see man 5 postconf
and man 5 aliases
), which changes behavior in case of address extensions (+foo) not previously matched.