PHP mail: What does -f do? - php

While troubleshooting a contact form with an e-mail host they told me to use '-f' in the from address of the php mail function. What does the "-f" flag do and why would that be a fix for allowing an e-mail to be delivered? I read some of the documentation but I'm not quite clear on it.
Example code:
mail($emailAddress, $mailSubject, $mailBody, $headers, '-f ' . $mailFrom);
PS: without the "-f" it works just fine for the big e-mail hosts (hotmail, gmail, etc, but for whatever reason not for the smaller host I'm working with)
Thanks

-f is a parameter to the mailer (usually sendmail). From the docs:
The additional_parameters parameter can be used to pass additional
flags as command line options to the program configured to be used
when sending mail, as defined by the sendmail_path configuration
setting. For example, this can be used to set the envelope sender
address when using sendmail with the -f sendmail option.
Here is the man page for sendmail, you can see what the -f option does:
-fname Sets the name of the ``from'' person (i.e., the sender of the
mail). -f can only be used by ``trusted'' users (normally
root, daemon, and network) or if the person you are trying to
become is the same as the person you are.

The -f option is to set the bounce mail address. Sending a message without one can negatively influence the spam-score that is being calculated over the message. Messages with low scores sometimes get filtered out for certain hosts.
You can use https://www.mail-tester.com/ to test the score of your message. You can expirement with or without the -f flag and see the score change.

It is a flag to mark the following text ($mailFrom) to be used as "from" address of the mail.
Have a look at: http://www.php.net/manual/en/function.mail.php

Related

Send e-mail from php using mail function [duplicate]

This question already has answers here:
How to configure XAMPP to send mail from localhost?
(11 answers)
Closed 2 years ago.
I want to send e-mail from a php file (Windows 10, localhost, XAMPP).
I followed this tutorial: Link
My php.ini file looks like this:
[mail function]
; For Win32 only.
SMTP = smtp.secureserver.net
; For Win32 only.
sendmail_from = some.email#gmail.com
My php file contains these:
$to = "another.email#gmail.com";
$subject = "Subject";
$mesaj = "Message";
$headers = "From:some.email#gmail.com\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/html; charset=iso-8859-1\r\n";
mail($to, $subject, $message, $headers);
When running, this warning appears:
Warning: mail(): Failed to connect to mailserver at "localhost" port 25, verify your "SMTP" and "smtp_port" setting in php.ini or use ini_set() in C:\xampp\htdocs\store\email_sender.php on line 61 No e-mail sent.
I saw similar questions (Link_1, Link_2, Link_3).
But I don't understand what I have to do. I have read that I need to install a SMTP server. What server should I install?
I have also followed this example (sending e-mail from mail function php), but the warning is still there and no e-mail is sent.
EDIT:
I have modified the information provided into the php.ini file:
[mail function]
SMTP=smtp.gmail.com
smtp_port=587
smtp_port=465
sendmail_from = some.mail#gmail.com
sendmail_path = "\"C:\xampp\sendmail\sendmail.exe\" -t"
I have also modified the information provided into the sendmail.ini file:
smtp_server=smtp.gmail.com
smtp_port=587
smtp_ssl=auto
error_logfile=error.log
;debug_logfile=debug.log
auth_username=some.mail#gmail.com
auth_password=somepassword
force_sender=some.mail#gmail.com
I have to mention that, in Gmail, the 2-step verification is disabled and the access to less secure apps is enabled. I have also stopped and started the Apache server.
All of the help links that you included in your question are correct. What I hear you saying, is that you don't fully comprehend what those links are telling you to do. Let me see if I can help you understand what is necessary to accomplish what you are trying to do.
When you send an email message from any program that you create, whether you're writing code in PHP, C++, Java ... makes no difference, the underlying libraries from your programming language do fully understand how to send an email. But you can only send an email using an email server that is actively working on the Internet, and one with which you have an account that has permission to send an email.
If email servers just let anyone send email through them, you can imagine how much worse spam would be on this planet.
Installing an SMTP server on your local machine won't solve your problem either, because you would need to have a subdomain that you control (whateverwhatever.com) and you would need to create MX records in a publically visible DNS server. You could buy a domain name with GoDaddy, then create your MX records and point them to your IP address, etc. but that's a lot of work.
What I suggest you do, is if you have a GMAIL account, you can use a Gmail server to send your email through, but you will need to configure your PHP code (either using ini_set() commands or in your php.ini file under the [mail function] heading with the information that the Gmail servers require.
Here are the fairly common pieces of information that most SMTP servers require, which you must define in your code or the php.ini file:
SMTP Server address (smtp.gmail.com)
Your Gmail account name
Your Gmail account password
The port numbers that the Gmail server requires
And there may be other pieces of info that it needs to see before it allows you to send the email.
Take a look at this page which explains how to use your own Gmail account to send an email for free. Also, do some Google searches using phrases like 'how to send SMTP through Gmail using my personal account' ... the information is out there.
Once you have learned what the Gmail servers require in order to send SMTP email, you simply input all of those required pieces of information into your PHP code or in the php.ini file. And there is plenty of documentation out there on how to do that.
Further discussion:
A little more clarification on what you're actually doing: ... you need to understand that your PHP program that you are writing is - for lack of a better term - en ad-hoc email client. You are use to sending email either with Outlook, or a web interface or some other email client, and you just write the email, put in the address of the person that you are sending to and you just click send and it goes ... but now, you're writing software to do the portion of the email sending that happens after you click send from an email program ... the part of the email process that you never have to think about ... you are now needing to create with your code. So your code needs to know where to place that email message, and email servers will not accept an email message from any place without proper credentials.
So you're basically writing with PHP code, a very light version of an email client that needs to be taught how to send an email... which is all the stuff that happens after you click SEND when you send an email to your mom.... you have never needed to know what happens to your email after you click send until now ... because you're hard coding the process literally in your PHP code.
I hope that helps you understand what's happening here a little better than you did.

Strange case with php mail function and addition parameter “-f”

I using php and CodeIgniter to send email but after change the server have following strange problem.
Each mail are sent to recipient and to sender.
After long debug of this problem I came to the following case.
mail("example#exmaple.com",$title,$body,$headers);
Work as expect send email only to "example#exmaple.com".
But
mail("example#exmaple.com",$title,$body,$headers, "-f example#domain.com ");
Send email and on both mail "example#exmaple.com" and "example#domain.com"
The problem is I do not know why she sends both emails.
I want to send only to "example#exmaple.com"
Here's what it says about this parameter php.net
The additional_parameters parameter can be used to pass additional flags as command line options to the program configured to be used when sending mail, as defined by the sendmail_path configuration setting. For example, this can be used to set the envelope sender address when using sendmail with the -f sendmail option.
Obviously this parameter needs me but it is only for authentication and should not be sent to the e-mail "example#domain.com",

Return-Path header rewritten by postfix

I'm sending mails from PHP using postfix at ubuntu:
mail($to, $subject, $body, "Return-Path: <test#mail.com>");
Trying to set Return-Path header but it seems that postfix rewrites it to user#serverdomain
Found in postfix documentation message_drop_headers variable that by default has value bcc, content-length, resent-bcc, return-path
Tried to change it's value in postfix/main.cf but it gives warning on start:
/usr/sbin/postconf: warning: /etc/postfix/main.cf: unused parameter: message_drop_headers=bcc content-length resent-bcc
What could be the reason? How can I configure postfix not to rewrite Return-Path header?
Setting the Return-Path: header on outbound email is pointless because it will be replaced by the recipient's MTA. If you want to control what gets written there, set the envelope sender (traditionally, sendmail -f address#example.com)
In some more detail, when you send a message, there are two layers: An envelope, which specifies the actual recipients, and the message itself, which often contains headers with the same information ... but sometimes it doesn't, and sometimes those headers lie, blatantly.
When that message is delivered to a recipient, the receiving MTA (Sendmail or Postfix or Exchange or what have you) will copy the envelope sender information into the Return-Path: header, adding one if it's missing, and usually simply overwriting it if it already existed.
So it doesn't really matter how you configure Return-Path: on your outgoing server; in order to properly control this, you would need to control the receiving behavior on every server which delivers the message to a recipient.
As a trivial example, subscribe to a public mailing list, observe how the headers often say something like:
From: Popular mailing list <popular-list#example.com>
To: Popular mailing list <popular-list#example.com>
And yet it arrived in your inbox. How did that happen? Why, by way of the envelope recipient information. The list software basically adds a Bcc: to every subscriber, but also convinces the server to ignore the actual To: address in the headers. This is surprising until you realize that the headers actually don't matter, and only the envelope addresses actually control where the message is eventually delivered.
Briefly, the envelope is specified by the SMTP MAIL FROM: and RCPT TO: verbs which are defined in RFC5321 (originally 822) and the actual message (including all the headers) are communicatd in the SMTP DATA section which is really just pure data as far as SMTP is concerned at this point. Their specification is RFC5322 (née 822) and once a message is actually delivered, the receiving server will actually add some headers of its own, but the From: and To: headers are still just basically ignored.
The solution is to declare a smtp_generic_maps table in Postfix main.cf and list local user and corresponding email in it.
For example :
www-data test#mail.com
Look at https://www.postfix.org/generic.5.html for more infos.
Of course use only a real domain you manage and with at least a SPF record allowing sending mails from this server.

phpmailer complications for spam filters "-f"

My clients hosting service isn't accepting emails sent from the website that doesn't have "-f" at the start of the FROM address. This related to a recent outgoing SPAM filter they added.
Official response is:
“senders envelope of data” is missing certain elements
I use phpmailer, everything was working fine until now using SMTP authentication.
But now with phpmailer, this DOESN'T work
$mail->From = 'me#test.com';
Also doesn't work
$mail->From = '-f me#test.com';
Its invalid obviousdly, not a good looking email address.
I CAN get mail to actually send like this:
mail('me#test.com', 'the subject', 'the message', null, '-f me#test.com');
But that isn't phpmailer, this is the garden variety php function. So im trying to make PHPmailer add "-f " to the FROM automatically somehow.
Should I be adjusting the class files to somehow get around that? Stuck!
You've got your transports mixed up. -f in the mail() function is an additional parameter passed to the underlying sendmail binary that sets the envelope sender of the message (and officially it should not have a space after it, like -fme#test.com). However, it does not apply when you are sending via SMTP because you get control over that parameter with the Sender property. You should do this:
$mail->Sender = 'me#test.com';
If you send using SMTP it will use that as the envelope sender (as the content of the SMTP MAIL FROM command), and if you send via isMail() or isSendmail() transports, it will set the sender via the -f property.
Also make sure you're using the latest PHPMailer from GitHub.

PHP mail issue with www-data

I am trying to invoke sendmail via PHP's mail function by the following code:
$to = 'blah#email.state.edu';
$subject = 'test';
$message = 'test';
$headers = 'From: mail#smartrek.blah.me' . "\r\n" .
'Reply-To: mail#smartrek.blah.me' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
mail($to, $subject, $message, $headers);
However in my mail.log I am getting a message that the from is not the address I specified in the header:
<www-data#Name>: Sender address rejected: Domain not found
Why is this?? I am running PHP's fast-cgi on ubuntu
Why doesn't sendmail use the header that I have specified via the PHP code?
It looks like www-data#Name is your envelope "from" address. The envelope "from" address is different from the address that appears in your "From:" header of the email. It is what sendmail uses in its "MAIL FROM/RCPT TO" exchange with the receiving mail server.The main reason it is called an "envelope" address is that appears outside of the message header and body, in the raw SMTP exchange between mail servers.
The default envelope "from" address on unix depends on what sendmail implementation you are using. But typically it will be set to the username of the running process followed by "#" and the hostname of the machine. In a typical configuration this will look something like username#example.com.
If your emails are being rejected by receiving mail servers, or if you need to change what address bounce emails are sent to, you can change the envelope "from" address to solve your problems.
To change the envelope "from" address on unix, you specify an "-r" option to your sendmail binary. You can do this globally in php.ini by adding the "-r" option to the "sendmail_path" command line. You can also do it programmatically from within PHP by passing -r mail#smartrek.blah.me as the additional parameter argument to the mail() function (the 5th argument). If you specify an address in both places, the sendmail binary will be called with two "-r" options, which may have undefined behavior depending on your sendmail implementation. With the Postfix MTA, later "-r" options silently override earlier options, making it possible to set a global default and still get sensible behavior when you try to override it locally.
EDIT
About optional flags that can be passed to sendmail: -f will set the From address, -r will override the default Return-path that sendmail generates (typically the From address gets used). If you want your bounce-backs to go to a different address than the from address, try using both flags at once: -f mail#smartrek.blah.me -r bounced-mail#smartrek.blah.me
my php.ini
[mail function]
; For Win32 only.
; http://php.net/smtp
SMTP = localhost
; http://php.net/smtp-port
smtp_port = 25
; For Win32 only.
; http://php.net/sendmail-from
;sendmail_from = me#example.com
; For Unix only. You may supply arguments as well (default: "sendmail -t -i").
; http://php.net/sendmail-path
;sendmail_path =
; Force the addition of the specified parameters to be passed as extra parameters
; to the sendmail binary. These parameters will always replace the value of
; the 5th parameter to mail(), even in safe mode.
;mail.force_extra_parameters =
; Add X-PHP-Originating-Script: that will include uid of the script followed by the filename
mail.add_x_header = On
; Log all mail() calls including the full path of the script, line #, to address and headers
;mail.log =
Although this is an old question, I'm adding this answer in case it is of help to someone:
I had the same problem with the From: header being re-written to www-data#host... I eventually tracked it down to the ssmtp bridge service that was piping mail from our web server into our mailserver. I added the line FromLineOverride=YES in the file /etc/ssmtp/ssmtp.conf and the problem disappeared.
In my case, I've got a hosted server so I needed to edit this file :
/etc/ssmtp/ssmtp.conf
Then uncomment this line :
FromLineOverride=YES
Once done, personals headers are working.
I was having similar problem with www-data when all my mails were sent and received with this header:
From: www-data <www-data#example.com>
I used the -f info#example.com flag as 5th argument with the PHP email() function (as mentioned in accepted answer), but i was still receiving my emails as:
From: www-data <info#example.com>
So i added one more flag -f info#example.com -F info to set the full name of the email and finally i was getting emails as i wanted:
From: info <info#example.com>
I'm posting this answer because nobody mentions it here and i got a little stuck on it.
This worked for me:
$mail->Sendmail = $mail->Sendmail.' -f '.$mail_errorsto;
I had this issue using exim4 with smarthost. The mails were sent with
Return-path: <www-data#servername>
which was rejected by the ISP. I needed to change it to at least www-data#example.com (assuming 'example.com' is the servers public domain name). I could achieve that by changing /etc/mailname from
servername
to
example.com
This has already worked for me, having www-data#example.com as Return-path.
However - If you want to completely change the email address, you can configure it in /etc/email-addresses as
www-data: notifications#example.com
After that the emails have been sent by default with
Return-path: <notifications#example.com>

Categories