‘Piping’ with POSTFIX for Virtual Users

postfix icon

Piping emails using Postfix MTA for virtual users:

I was asked by my manager to configure ‘piping’ using postfix for virtual users. Now, when I say virtual users, it means:

1. User should not be present on the system physically.

2. User should not have a physical mailbox to store mails in.

3. User does not have any database account neither any database to store any mails on.

Most of the tutorials that I have come across through Google search refer to virtual domains and not virtual users. Here we will configure both, that is, virtual domains as well as virtual users who can actually receive emails from outer world and PIPE those emails to a program/script. The only caveat is if the email is lost somewhere while delivering, it will be lost forever, as there is no mailbox associated with them to, well, store those emails. Imagine that your email server is down for couple of hours and you are working your ass off to fix it, but during those hours, if any email is originated from any source for this virtual user, it will be eventually lost, why? You guessed it right! No mailbox to store it for later delivery.

This type of scenario is useful when you do not want to store the emails onto the server itself but want to pipe it to some program such as the help desk. For those, who do not know what help desk is, head over to: “www.kayako.com” for a basic insight. The setup is pretty straight forward and after having a look, you might say to yourself, “Hey! I know that already”. In that case, good for you, let me educate others who do not know ūüėČ


Create 3 virtual domains as follows:

1. testing1.virtual.internal

2. testing2.virtual.internal

3. testing3.virtual.internal

Add virtual email addresses (not the real ones, meaning no mailbox associated with them) such that emails for:

1. support@testing1.virtual.internal

2. support@testing2.virtual.internal

3. support@testing3.virtual.internal

should go to there different test sites (and in turn fed to the scripts which will process them after receiving the mails)

So, we have scenario here that whenever we send email to “support@testing1.virtual.internal“, it should go to the testing1 domain (testing1.virtual.internal); similarly, when we send email to “support@testing2.virtual.internal“, it should go to the testing2 domain (testing2.virtual.internal) and so forth.

Piping setup:

1. Edit the postfix configuration file, /etc/postfix/main.cf, and append the following to the last:

virtual_mailbox_domains = /usr/share/nginx/html/virtual/vdomains
virtual_alias_maps = hash:/etc/postfix/virtual

2. Edit “/usr/share/nginx/html/virtual/vdomains” and add your virtual domains in this file, one virtual domain per line:

# virtual domains for postfix

NOTE: You can add the virtual domain to any file but make sure that it is mentioned in the configuration file (main.cf) under: virtual_mailbox_domains.

3. Edit “/etc/postfix/virtual” file to add the virtual email addresses. Now the trick is that virtual aliases do not work with piping, but local aliases do. So, we will first link virtual aliases to local dummy account and then link those dummy accounts to the script to which we want to fed our incoming emails to.

# Virtual email address                 dummy user which will be used in aliases file
support@testing1.virtual.internal       support-testing1
support@testing2.virtual.internal       support-testing2
support@testing3.virtual.internal       support-testing3

NOTE: Run “postmap /etc/postfix/virtual” every time you edit the above file (/etc/postfix/virtual). It may be addition of another virtual account, deletion of account, etc.

4. Edit “/etc/aliases” file so that we can link our dummy users (local aliases) to the piped program/script.

support-testing1:       "|/usr/share/nginx/html/virtual/testing1/console/index.php"
support-testing2:       "|/usr/share/nginx/html/virtual/testing2/console/index.php"
support-testing3:       "|/usr/share/nginx/html/virtual/testing3/console/index.php"

Do not forget to change the permissions on your piped program/script, they should be 755.

Restart ‘postfix’ and you will have a setup where if any email is received on one of the accounts above, that email will directly be fed into the script for further processing and it will not be stored on the server.

Pretty neat stuff;) Ain’t it!

3 thoughts on “‘Piping’ with POSTFIX for Virtual Users

  1. Thanks for this guide! It helped me to finally get the piping done with my virtual accounts. Main difference is that I use MySQL for the virtual parts. VAlias to exec@localhost then “exec: |/some/script/here”.

    Another option I explored was to use the pipe() route in master.cf, and actually got that working now as well. But, it seems that the alias method is actually better as it passed on a larger header, and sets more environment variables. Maybe there’s more to add in the pipe, or has some performance advantage… but right now I can’t see it.

  2. One edit: After adding entries to the /etc/aliases file, you must run the newaliases command for the /etc/aliases.db to be updated

Leave a Reply

Your email address will not be published. Required fields are marked *