Piping email to PHP

Discussion in 'Installation/Configuration' started by rinu, Feb 6, 2017.

  1. rinu

    rinu New Member

    I've been trying for ages to get a simple pipe to work but no luck so far. It's been several days of trying.
    What I had on my old server (now deleted) was a simple custom rule on an email account. It said
    Code:
    to "|/usr/bin/php /path/to/my/script.php"
    It worked perfectly before but I can't figure it out on the new server. That is Maildrop syntax, which Sieve does not support at all. The default in ISPConfig however is Sieve. I tried to change to Maildrop by changing "virtual_transport" to "maildrop" in /etc/postfix/main.cf. Which results in something like "maildrop[11480]: Temporary authentication failure." in /var/log/mail.log.
    I have to switch the config back to "dovecot" after testing to make my incoming email work again.

    I even tried the Sieve pipe plugin but unfortunately it's a dead end. Will not compile on Ubuntu 16.04.
     
  2. Jesse Norell

    Jesse Norell Well-Known Member Staff Member Howtoforge Staff

    As you found out, sieve does not support executing external commands without a proprietary extension. For dovecot you have 'execute', 'filter', and 'pipe' - if pipe didn't work for you, look at the other two. If none of those work, you'll have to call the program in another way outside of sieve (eg. postfix aliases support a pipe like that so maybe copy the message to an alias, or you could setup a postfix transport to run your command and call it that way).
     
  3. rinu

    rinu New Member

    I think I tried both the alias and a new transport but neither of them worked. It's probably just me being stupid and missing a line of config somewhere but I tried following several tutorials/guides and got nowhere. If you're familiar with either method, could you please try explaining how they work? At this point I'm willing to try anything that works.
     
  4. Jesse Norell

    Jesse Norell Well-Known Member Staff Member Howtoforge Staff

    The alias route is quite simple, just put something like this in /etc/aliases:
    Code:
    myscript: '| /path/to/my/script.php'
    Then forward your mail (eg. via your sieve script) to myscript@localhost or [email protected] (some hostname that hits the local transport).

    The transport route takes just a bit more configuration, first create a transport in master.cf:
    Code:
    myscript     unix  -       n       n       -       1       pipe
      flags=FR  size=1048576 user=nobody:nogroup argv=/path/to/my/script
    
    Then set some email address, or even an entire domain if you wish, to deliver via that transport. You can configure a domain that way via 'Email Routing' in ispconfig; I don't know if you can do an individual email address (the field is labelled 'Domain' , I haven't tried an addr), but that can be done by adding 'texthash:/etc/postfix/transports' to the existing transport_maps (in main.cf), then creating /etc/postfix/transports with:
    Code:
    [email protected]    myscript:
    
    And again you'll have to forward your mail to [email protected], eg. via sieve.

    (The above is all untest so may contain errors, but that's the gist of it.)
     
  5. rinu

    rinu New Member

    Tried to get the alias thing working but not happening. Took forever to bypass ispconfig, had to write directly to the mailbox's sieve file to have @loalhost and this is what I get:
    Feb 8 22:15:11 myhost postfix/smtp[20028]: B6BD81B019AA: to=<myscript@localhost>, relay=none, delay=0.03, delays=0.01/0.01/0/0, dsn=5.4.6, status=bounced (mail for localhost loops back to myself)
     
  6. Jesse Norell

    Jesse Norell Well-Known Member Staff Member Howtoforge Staff

    well, I did disclaim that it was untested. :)

    Turns out you need to use double quote in the aliases file, and make sure you run 'newaliases' for changes to take effect.

    Code:
    # cat >/tmp/myscript.sh <<EOF
    /bin/dd of=/tmp/output.txt oflag=append conv=notrunc
    EOF
    # chmod +x /tmp/myscript.sh
    # echo 'myscript: "|/tmp/myscript.sh"' >> /etc/aliases
    # newaliases
    # echo test1 | mail myscript@localhost
    # echo test2 | mail myscript@`hostname -f`
    
    # wc -l /tmp/output.txt 
    40 /tmp/output.txt
    # tail -1 /tmp/output.txt
    test2
    
     
  7. rinu

    rinu New Member

    In my previous tests I had already written the alias to /etc/aliases, with double quotes, also had already ran `newaliases`.
    With localhost I still get a bounce with "(mail for localhost loops back to myself)".
    With my actual hostname I get a bounce with "(user unknown)".

    Could the issue here be that I have my hostname set up in ISPConfig? I have several mailboxes with that same domain.
    When I used a subdomain like mail.mydomain, I got the same old "loops back to myself" error.

    What I also attempted was creating a random new domain name, redirecting it to localhost in /etc/hosts and sending mail there. However this gave me DNS errors for some reason.
     
  8. rinu

    rinu New Member

    So I added mydomain to virtual_alias_domains and $alias_maps to virtual_alias_maps. So now it's like
    Code:
    virtual_alias_domains = mydomain
    virtual_alias_maps = $alias_maps, hash:/var/lib/mailman/data/virtual-mailman, proxy:mysql:/etc/postfix/mysql-virtual_forwardings.cf, proxy:mysql:/etc/postfix/mysql-virtual_email2email.cf
    Which resulted in
    Feb 9 09:55:33 mydomain postfix/error[4449]: E55971B04116: to=<|/usr/bin/php /path/to/myscript.php@mydomain>, orig_to=<myscript@mydomain>, relay=none, delay=0.02, delays=0.01/0/0/0.01, dsn=5.1.1, status=bounced (User unknown in virtual alias table)
     
  9. Jesse Norell

    Jesse Norell Well-Known Member Staff Member Howtoforge Staff

    Yep, that would be it - so postfix no longer uses the 'local' transport, which is what reads/expands /etc/aliases. But you might be able to specify that in Email Routing in ispconfig, just add a route for this specific email address as the 'Domain' (I just tested, and an email address is allowed there), with Type 'custom' and Destination of 'local:'. I haven't tested it, but that might get you back to the 'local' transport for just that one email address.
     
  10. rinu

    rinu New Member

    That worked perfectly! Thank you so much!
     
  11. brisk

    brisk Member

    Hi, Jesse/Rinu:

    I need to setup pipe as well. Can you please explain a bit more? Especially the transport part. thanks
     
  12. Jesse Norell

    Jesse Norell Well-Known Member Staff Member Howtoforge Staff

    The post above shows how to define a transport named 'myscript' in /etc/postfix/master.cf which will pass mail to the /path/to/my/script script when used; then the address [email protected] is set to use that transport map, so any mail sent to that address will run the script to "deliver" that mail (though the script can do whatever you want/need it to with the mail).
     
  13. brisk

    brisk Member

    Thanks! this is the confusing part, the script is specified in the aliases file, why again in transport?
     
  14. Jesse Norell

    Jesse Norell Well-Known Member Staff Member Howtoforge Staff

    That is 2 separate ways to accomplish the same end (passing email to a php script); if you have aliases working to your liking, you don't need to setup transports, and vice-versa. The transports route is a little more configurable though, which can be very useful (see http://www.postfix.org/pipe.8.html).
     
    Last edited: Sep 6, 2017
    brisk likes this.
  15. brisk

    brisk Member

    Thank you!!! it is working!!!! So I used alias:

    This is what I did just for reference:

    1. Edit /etc/aliases file to add this:
    Code:
    specialuser: "|/var/www/clients/client1/api/pipe.php"
    2. Add a system user:
    Code:
    useradd -r specialuser
    3. In ISPConfig, add a forward, forward [email protected] to specialuser@localhost

    4. Run command newaliases

    DONE!
     

Share This Page