5

I'd like to implement self-destructing e-mail address rules on my Postfix mail server. The idea is to have public address like this:

john0220@mydomain.com

where 0220 in the address means "February 2020". If Postfix receives e-mail for this address before 3/1/2020 it will be delivered to some non-public e-mail (e.g. mark@mydomain.com) but after this date the e-mail is discarded (/dev/null).

Such system would allow me to have infinite number of temporary addresses.

Postfix allows regular expressions to match recipient address but how to do that conditional rewriting based on time?

kenlukas
  • 3,101
  • 2
  • 16
  • 26
bizwiz
  • 153
  • 2
  • 1
    I'm interested if that that can be done native in Postfix. In the past I have used the `recipient_delimiter +` sub-addressing separator which allows you to use any sub-address `label` after your local username `username+label@example.com` and the power of `procmail` (or other mail filters such as [sieve](https://wiki.dovecot.org/Pigeonhole/Sieve/Examples) ) to accept, discard and store "unique" email addresses in separate folders without having to set up specific aliases before hand. – HBruijn Oct 07 '19 at 11:05

1 Answers1

4

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.

anx
  • 8,963
  • 5
  • 24
  • 48
  • Your reply inspired me to try different "sufficiently dynamic lookup method": tcp map as described here http://www.postfix.org/tcp_table.5.html. But I've run into some security constrains (error: tcp:localhost:4444 map is not allowed for security sensitive data) – bizwiz Oct 09 '19 at 06:51