SSL Part 2: PHP mail function
SSL Part 2: Home | Lock Down | No IP | hMailServer | Config hMailServer | PHP mail function | Generate CSR | CAcert | CAcert Signing Process
PHP mail function problem
With your e-mail server working I suppose one of the first things to try is PHP’s mail function. A very simple looking function with the power to make you rip your hair out when you discover it does not work.
The truth is it does work, in reality it’s a lack of understanding, which this page attempts to address. When I used this function for the first it failed imagine my surprise when I discovered it required a mail server. Even after acquiring a mail server it persistently refused to work.
Most problems are solvable however first you need to understand what the failure mechanism is. The following examples use our mail-sever as describe on the previous two pages to investigate PHP’s mail function and server interaction.
Basic PHP mail function
All examples use a variant of the following script running on Uniform Server 3.5-Apolo. I assume you have set-up your email client with a “postmaster” account ( see previous page)
The script clearly works, mailed was delivered to our recipient “postmaster” perhaps what is a little surprising is where the mail came from email@example.com!
That e-mail address does not exist, either in our script or e-mail server. A recipient wanting to reply clearly would have a problem.
The address is automatically added by PHP. Address used is that set in the php.ini file located in folder *\Uniform Server\udrive\usr\local\php.
Line 617: sendmail_from = firstname.lastname@example.org
Suppose you want all your PHP e-mail scripts to reply to a single address changing the php.ini file to that address would achieve the result required. To see this in action change the line in php.ini to sendmail_from = email@example.com run the above script again. This is a small change to illustrate a point and not a practical solution.
Note: The above is extremely important you need to think of the combined script and php.ini as a mini-smtp server. It will only relay (deliver) mail to the local server (Line 614: smtp_port = 25) and to a single account defined by (Line 617) sendmail_from = firstname.lastname@example.org.
Basic PHP mail function - Problem
The above demonstrates our script and mail server are working. This next test I am sure you will be familiar with or at least the resulting error message. Change the script, replace to email address with your real e-mail address (as provided by your ISP)
Error 550 means that this mail server does not allow relaying! The address (implied) on line 10 is your real e-mail address!
Test: Using the postmaster account you set-up in your client. send yourself an email (to your ISP email account).
The test demonstrates you can relay email through your email server, to your ISP and receive mail. Clearly the above error message is not referring to your real address.
Remember the importance of test 1! Its referring to that address from the mini-smtp server. The problem is our local mail server sees this as an external server.
The answer to the problem is on this page Internet IP ranges section 10 it defines what is allowed to relay through the server. I have reproduced the image below:
A quick and disastrous solution is to check the bottom box and allow external-to-external relaying.
This would be instant death for any e-mail server, not only would you be blacklisted but you open your server for every one to use where they can relay all unsavory stuff and spam.
The solution is interesting all four selectable options have one thing in common accounts!
Does our mini-server email@example.com have an account on our hMailServer of course not we never set one-up.
Do we have a domain localhost.com well we never set that up either.
You can set-up an account for firstname.lastname@example.org in any domain however it is preferable to create a new domain just in case you delete the one it resides in killing off all your PHP scripts.
Creating a new domain and account see below:
Create new domain:
Create new account:
For the catch-all address to become active it requires an account.
Note: The password is required only to create the account it is never used by scripts.
Repeat the original test:
|Run script:||Type into your browser http://localhost/mail_test_2.php|
|Result:||Mail accepted for delivery Indicates mail was sent (Script is working!)|
|Mail Client:||Wait for the mail to be delivered. After a reasonable time refresh your e-mail client.|
|Subject: Mail Test 2|
Both hMailServer and PHP has been set-up correctly however that strange from address (email@example.com) needs resolving. You have two options depending on your requirements.
1) Common address
If all your scripts expect all recipients to reply to a single address you can change php.ini and hMailServer to reflect that address.
2) Generic address
Solution one is specific and inflexibly however you have a server that is capable of relaying any standard e-mail. The real solution lies in PHP’s mail function and the use of its fourth parameter covered in the next section.
Basic PHP mail function - Reply address
PHP's basic mail function allows you to specify a fourth parameter. This parameter is primarily used for inserting MIME types however it also allows you to specify a “from address”.
I hope you found the above digression of interest; PHP’s basic mail function always seems to give new users grief. I faced the same problem because of a basic lack of understanding; thinking in terms of a mini-smtp server helps to visualise the problem. You may be interested in alternative solutions there are two covered on this page.
Enough of this lets continue with our quest for a signed certificate.