PHP mail function not working on Centos server

70,634

Solution 1

After installing sendmail* and running the following commands:

[root@sendmail ~]# yum install sendmail*
[root@sendmail mail]# yum install dovecot
[root@sendmail mail]# cd /etc/mail/
[root@sendmail mail]# vi local-host-names
# local-host-names - include all aliases for your machine here.
example.com
[root@sendmail mail]# vi /etc/dovecot.conf
protocols = imap pop3 //uncomment
[root@sendmail mail]# m4 sendmail.mc > sendmail.cf
[root@sendmail mail]# make
[root@sendmail mail]# /etc/init.d/sendmail start
[root@sendmail mail]# /etc/init.d/saslauthd start
[root@sendmail mail]# /etc/init.d/dovecot start
[root@sendmail mail]# chkconfig sendmail on
[root@sendmail mail]# chkconfig dovecot on
[root@sendmail mail]# chkconfig saslauthd on

I still had the same issue. I checked my /var/log/maillog and saw an error:

My unqualified host name (domain) unknown; sleeping for retry

After more searching, I changed /etc/hosts from:

127.0.0.1     localhost localhost.localdomain domain
ip.ip.ip.ip  domain localhost 

to:

 127.0.0.1   localhost.localdomain localhost domain
 ip.ip.ip.ip  localhost domain  

and now the mail function is now working fine.

Solution 2

I know this has been answered but I had a similiar problem. In case anyone else....

/var/log/maillog showed me a Postfix permission issue.

sendmail: fatal: chdir /var/spool/postfix: Permission denied

Tracking down error I found solution to be SELinux policy on CentOS (I'm using version 6).

Quick answer: setsebool httpd_can_sendmail 1

You can use -P to make the change permanent; I just needed for password reset e-mail so not needed for my case.

Credit: http://www.spidersoft.com.au/2011/posftix-permission-denied-problem/?ModPagespeed=noscript

EDIT: I would have commented but I don't have enough reputation yet.

Solution 3

I had the same problem. I have a development server at home and prod server at external server house and incoming mails go to other server. PHP:s mail() works nicely in server house, but not at home.

I tested a bit and got it to work at home in the same manner as in server house. The difference between methods in server house and home is the configuration of sendmail. Server house I had only to install sendmail and it was fine, but at home I had to install also sendmail-cf and use it to add outgoing mail server address.

Let's assume you have Centos, Apache and PHP at home server and you want to send emails using PHP:s mail() function.

1) Set hostname on home server into two places: /etc/sysconfig/network and /proc/sys/kernel/hostname this way:

 # nano /etc/sysconfig/network
   NETWORKING=yes
   HOSTNAME=mydns157.dlinkddns.com

 # nano /proc/sys/kernel/hostname
   HOSTNAME=mydns157.dlinkddns.com

2) Install sendmail and sendmail-cf:

 # yum install sendmail sendmail-cf

3) Add the following row into /etc/mail/sendmail.mc, where you have your ISP:s outgoing mail server:

 define(`SMART_HOST',`mail.myisp.com')dnl

4) Update sendmail.cf:

 # /etc/mail/make

5) Restart sendmail and apache:

 # service sendmail restart
 # service httpd restart

6) Boot to update hostname:

 # reboot

That's it. Now the following works:

# php -r'mail("[email protected]", "Subject", "Body", null, "[email protected]");'

You can skip -f:

# php -r'mail("[email protected]", "Subject", "Body");'

in which case the sender's name become automatically user@hostname, eg. [email protected].


Some notes of hostname

The selection of hostname is critical. The default in Centos6 is localhost.localdomain, but mail() is not working with it if you skip your own sender address (eg. '[email protected]') when calling mail(). If you are sure, that you always call mail() using your real address as sender address, the hostname can be whatever, but if you have existing calls to mail() that lacks the sender address (I have hundreds of this like calls for testing purposes), then you must have a real domain as a hostname, because your server's hostname is used as a sender-address-domain in these cases. Real in the sense that domain must have at least DNS A-record (for some reason my ISP doesn't require NS-record for sender address, only A-record, but test and check with your ISP). The downside of using non-email-domain as a sender address is that replys and delivery notifications will go to bit's heaven, but if you drop sender address in your code, it usually means that you test and debug something and don't need reply functionality. The domain can be eg. the one you get from dynamic dns server eg. mydns157.dlinkddns.com, which can point to your home router (but not have to). You can get DNS record in PHP using dns_get_record("mydns157.dlinkddns.com"), which returns an array like this:

 [host] => mydns157.dlinkddns.com
 [type] => A
 [ip] => 92.152.214.137
 [class] => IN
 [ttl] => 7

If type in above DNS-record is NS, then the domain acts as an email domain, which is OK for hostname of own server, but the effect is a little different. If you set as hostname an existing email domain eg. myexistingemaildomain.com, and send a message to [email protected] eg for debugging purposes, sendmail thinks that the message has to be delivered to mail-folder of user me on this server. If me user doesn't exist, the sending fails and if the user exists, then the message goes to /var/mail/me. This can be what you want, but (like me) you may want that all messages are delivered outside instead of server folders.

Your hostname (in DNS record) doesn't need to point to your server's actual external IP to make mail() work in lack-of-sender-address cases, but there is no harm of it. The main thing is that hostname has a valid A-record and that the domain belongs to you. If the domain doesn't belong to you, then there may born a security hole. If you set as hostname some existing email domain eg. microsoft.com (for whatever reason) and send a message to someone without adding your own sender address when calling mail() (eg. '[email protected]'), the sender address will be automatically [email protected]. If you are logged as root, the sender address will be [email protected]. Replys and notifications of failed deliveries go then to [email protected] and this may not be your intention.

Solution 4

I just had this issue, two things.

My emails were going to spam, definitely check that. Probably because my server didn't have proper PTR and SPF records.

But also, I found it a lot easier to test sendmail with this:

sendmail -s '[email protected]'
Subject:Testing!
hey there, how ya doin?
CTRL+D

Solution 5

Always check your maillog in /var/log/maillog to know the cause of the problem. I had a similar issue once after having properly configured postfix. I got an error saying fatal: setrlimit: Permission denied. Workaround is check if the httpd can send mail is enabled or not by getsebool httpd_can_sendmail command. If httpd can send mail is off then enable it by the command: setsebool -P httpd_can_sendmail 1. Hope this helps.

Share:
70,634
Astha
Author by

Astha

Database and Server/BackEnd Engineer.

Updated on February 14, 2020

Comments

  • Astha
    Astha over 4 years

    I am using centos Server and have to send the mail to the user so i copied running code of mine from one server and used it in here, but it is not sending mails.

    Code is :

                    $to = $email; //writing mail to the user
                    $subject = "Hii";
                    $message = "<table>
                    <tr><td> Hello ".$email.",</td></tr>
                    <tr><td> Some Text </td></tr>
                    <tr><td> Some Text </td></tr>
                    <tr><td> Some Text </td></tr>
                    <tr><td> Some Text </td></tr>
                    </table>" ;
                    $from = "[email protected]";
                    // To send HTML mail, the Content-type header must be set
                        $headers  = 'MIME-Version: 1.0' . "\r\n";
                        $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
                    // Additional headers
                    $headers .= 'From: Team <[email protected]>' . "\r\n";
    
                    if(mail($to,$subject,$message,$headers))
                    {
                        echo "0";// mail sent Successfully.
                    }
                    else
                    {
                        echo "1";
                    }
    

    It always print 1. Same code running fine on other project. Please guide me what i can do to enable it here too? Any help will be highly appreciated!

  • emc
    emc over 11 years
    could be /etc/dovecot/dovecot.conf?
  • holms
    holms almost 11 years
    postfix does this out of the box
  • Martin Carstens
    Martin Carstens almost 8 years
    I used these instructions to set up sendmail for CentOS in a Docker container. I did however only have to to do yum install sendmail to use mail(). Configuring the hosts file as above proved critical in order to make the mail function send email in a timely fashion. Thank you!
  • t q
    t q over 6 years
    im getting setsebool: SELinux is disabled
  • t q
    t q over 6 years
    from service sendmail restart im getting an error Starting sendmail: 554 5.0.0 No local mailer defined 554 5.0.0 QueueDirectory (Q) option must be set
  • t q
    t q over 6 years
    worked on mail all day but errors never went away, this fixed my problem in 30 minutes!
  • preOtep
    preOtep almost 6 years
    Seems like SELinux isn't your issue then. Do you need still help ?
  • Shashank Pujari
    Shashank Pujari over 3 years
    in my case it was disabled