Making PHP Mail Work on Ubuntu Through Postfix

While writing a small mail application in PHP i noticed i couldn’t send mail from my local machine. Even with telnet i couldn’t send out emails. I quickly found out that postfix and sendmail on the same system is not a good idea. Seems it was a left over from some testing i did. So after wiping sendmail and postfix from the system. And reinstalling only postfix i got an error when starting Postfix

postfix: fatal: /etc/postfix/postfix-script: No such file or directory

So let’s try and completely remove the postfix package and purge all files.

$ sudo dpkg –remove postfix $ sudo dpkg –purge postfix

And a clean install of postfix:

$ sudo apt-get -V install postfix

Now i can telnet in and try to send some mail. And this seemed to work. The mail got delivered.

  • $ telnet localhost 25
  • Trying 127.0.0.1…
  • Connected to localhost.
  • Escape character is ‘^]’.
  • 220 0x0 ESMTP Postfix (Ubuntu)
  • helo test.nl
  • 250 0x0
  • mail from: test@test.nl
  • 250 2.1.0 Ok
  • rcpt to: some@working.address
  • 250 2.1.5 Ok
  • data
  • 354 End data with
  • testing
  • .
  • 250 2.0.0 Ok: queued as ED97311C412F

So now let’s make sure it also works from PHP. I tested it through a CLI script and through apache2. With the most basic mail script you can imagine.

mail('some@working.address', 'test', 'test message');

The mail however gets bounced.

  • Jan 7 22:31:48 0x0 postfix/pickup[10249]: 035BF11C4133: uid=1 from=
  • Jan 7 22:31:48 0x0 postfix/cleanup[11726]: 035BF11C4133: message-id=<20090107213148.035BF11C4133@0x0>
  • Jan 7 22:31:48 0x0 postfix/qmgr[10250]: 035BF11C4133: from=daemon@internal.name, size=303, nrcpt=1 (queue active)
  • Jan 7 22:31:48 0x0 postfix/smtp[11728]: 035BF11C4133: to=some@working.address, relay=working.mail.server[xx.xxx.xx.xx]:25, delay=0.68, delays=0.02/0/0.48/0.18, dsn=5.0.0, status=bounced (host working.mail.server[xx.xxx.xx.xx] said: 553 sorry, your envelope sender domain must exist (#5.7.1) (in reply to MAIL FROM command))
  • Jan 7 22:31:48 0x0 postfix/cleanup[11726]: C5C2911C4134: message-id=<20090107213148.C5C2911C4134@0x0>
  • Jan 7 22:31:48 0x0 postfix/qmgr[10250]: C5C2911C4134: from=<>, size=2064, nrcpt=1 (queue active)
  • Jan 7 22:31:48 0x0 postfix/bounce[11729]: 035BF11C4133: sender non-delivery notification: C5C2911C4134
  • Jan 7 22:31:48 0x0 postfix/qmgr[10250]: 035BF11C4133: removed
  • Jan 7 22:31:49 0x0 postfix/smtp[11728]: C5C2911C4134: to=daemon@internal.name, relay=working.mail.server[xx.xxx.xx.xx]:25, delay=0.75, delays=0.01/0/0.41/0.34, dsn=2.0.0, status=sent (250 ok 1231363909 qp 10204)
  • Jan 7 22:31:49 0x0 postfix/qmgr[10250]: C5C2911C4134: removed

From looking at the log files i can tell it bounced because the from address is set to daemon@internal.name. And internal.name is not known by my mail server. Let’s try that again. But this time specifically set the FROM header.

$headers .= 'To: Name <some@working.addressl>' . "\n";
$headers .= 'From: test <some@working.address>' . "\n";
mail('some@working.address', 'test', 'test message', $headers);

The result is the same. The FROM header didn’t change at all. So although it’s possible to set the from header. The message is always send by a system user.. So after doing some research on Google about this problem it seems possible to pass an extra parameter to the mail() function. This parameter can contain a string which will be passed to the postfix binary as an extra parameter. So adding -fsome@orking.address makes the problem go away.

  • Jan 7 22:36:58 0x0 postfix/pickup[10249]: 687CA11C4133: uid=1 from=some@working.address
  • Jan 7 22:36:58 0x0 postfix/cleanup[11847]: 687CA11C4133: message-id=<20090107213658.687CA11C4133@0x0>
  • Jan 7 22:36:58 0x0 postfix/qmgr[10250]: 687CA11C4133: from=some@working.address, size=276, nrcpt=1 (queue active)
  • Jan 7 22:36:59 0x0 postfix/smtp[11849]: 687CA11C4133: to=some@working.address, relay=working.mail.server[xx.xxx.xx.xx]:25, delay=1.4, delays=0.02/0/0.59/0.76, dsn=2.0.0, status=sent (250 ok 1231364219 qp 10582)
  • Jan 7 22:36:59 0x0 postfix/qmgr[10250]: 687CA11C4133: removed

But this would mean that i always have to pass the extra parameter. And if i use a third party class or function. i may not be able to do so without hacking the code. So although it solves the problem it’s not the final solution. After i bit of browsing i found out that changing the myorigin parameter in /etc/postfix/main.cf to a known mail server. I could start the send out mail. So i changed it to the domain my mail server runs under.

myorigin = mail.server

And now sending mail from PHP works.

comments powered by Disqus