How to get sendmail to send mail?

July 17, 2018 929 views
Apache PHP CentOS

I've been happily beavering away on a Centos 7 droplet. I set up a LAMP stack and got few websites running in virtual hosts. I've now run into an annoying issue: the php mail() function isn't working.

As a test I installed Drupal 7 on one of the sites. At first the form was submitted instantly but nothing was sent. After installing sendmail the form hangs for a while and I'm getting this in /var/log/maillog:

Jul 16 22:58:29 myhostname sendmail[18792]: My unqualified host name (myhostname) unknown; sleeping for retry
Jul 16 22:59:29 myhostname sendmail[18792]: unable to qualify my own domain name (myhostname) -- using short name
Jul 16 22:59:29 myhostname sendmail[18792]: alias database /etc/aliases rebuilt by myusername
Jul 16 22:59:29 myhostname sendmail[18792]: /etc/aliases: 76 aliases, longest 10 bytes, 771 bytes total
Jul 16 23:02:21 myhostname sendmail[18838]: My unqualified host name (myhostname) unknown; sleeping for retry
Jul 16 23:03:21 myhostname sendmail[18838]: unable to qualify my own domain name (myhostname) -- using short name
Jul 16 23:03:23 myhostname sendmail[18838]: My unqualified host name (myhostname) unknown; sleeping for retry
Jul 16 23:04:23 myhostname sendmail[18838]: unable to qualify my own domain name (myhostname) -- using short name
Jul 16 23:04:23 myhostname sendmail[18838]: w6GM3LxY018838: Authentication-Warning: myhostname: apache set sender to recipient@example.com using -f
Jul 16 23:04:23 myhostname sendmail[18838]: w6GM3LxY018838: from=recipient@example.com, size=429, class=0, nrcpts=1, msgid=<201807162203.w6GM3LxY018838@myhostname>, relay=apache@localhost
Jul 16 23:04:23 myhostname sendmail[18838]: w6GM3LxY018838: to=recipient@example.com, ctladdr=recipient@example.com (48/48), delay=00:01:02, xdelay=00:00:00, mailer=relay, pri=30429, relay=[127.0.0.1] [127.0.0.1], dsn=4.0.0, stat=Deferred: Connection refused by [127.0.0.1]

I then added this to the /etc/httpd/sites-available/example.com.conf file:

<Directory /var/www/example.com/public_html>
    php_admin_value sendmail_path "/usr/sbin/sendmail -t -i -fwebsite@example.com"
</Directory>

That results in:

Jul 17 12:06:48 myhostname sendmail[20949]: My unqualified host name (myhostname) unknown; sleeping for retry
Jul 17 12:07:48 myhostname sendmail[20949]: unable to qualify my own domain name (myhostname) -- using short name
Jul 17 12:07:48 myhostname sendmail[20949]: My unqualified host name (myhostname) unknown; sleeping for retry
Jul 17 12:08:48 myhostname sendmail[20949]: unable to qualify my own domain name (myhostname) -- using short name
Jul 17 12:08:48 myhostname sendmail[20949]: w6HB7mFh020949: Authentication-Warning: myhostname: apache set sender to website@example.com using -f
Jul 17 12:08:50 myhostname sendmail[20949]: w6HB7mFh020949: from=website@example.com, size=476, class=0, nrcpts=1, msgid=<201807171107.w6HB7mFh020949@myhostname>, relay=apache@localhost
Jul 17 12:08:50 myhostname sendmail[20949]: w6HB7mFh020949: to=myvps@email.com, ctladdr=website@example.com (48/48), delay=00:01:02, xdelay=00:00:00, mailer=relay, pri=30476, relay=[127.0.0.1] [127.0.0.1], dsn=4.0.0, stat=Deferred: Connection refused by [127.0.0.1]

I suspect the issue is my /etc/hosts and/or /etc/mail/local-host-names file but I'm at a loss at this stage.

# cat /etc/hosts
# The following lines are desirable for IPv4 capable hosts
127.0.0.1 myhostname myhostname
127.0.0.1 localhost.localdomain localhost
127.0.0.1 localhost4.localdomain4 localhost4

# The following lines are desirable for IPv6 capable hosts
::1 myhostname myhostname
::1 localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
# cat /etc/mail/local-host-names
# local-host-names - include all aliases for your machine here.

Any guidance gratefully received!

2 Answers

Hello friend!

In this case if you replace example.com with something like gmail.com, does it end up producing the same log entry? The reason I ask is that I think what might be happening here is that example.com has no MX record, causing the email to go back to the sender (apache@localhost), which is then rejected as the server at localhost does not accept email.

Kind Regards,
Jarland

  • Thanks, you got me on the right track... The MX record was one of my issues. There were others as well - my droplet's host name was fully qualified, for instance. I've added a new answer to summarise how I got it to work.

I finally got this working. As I'm sure other people will be struggling with sending emails via PHP I'll explain what I did. In the below example the domain on my droplet is called server.example.com and my domain is mydomain.com. I'm sending emails from website@mydomain.com and the emails are relayed via a server called sending.server.com.

Your droplet needs a fully qualified host name
If the host name isn't fully qualified you'll get entries like these in /var/log/maillog:

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

To check the host name:

$ cat /etc/hostname
server.example.com

You're /etc/hosts file will then probably look something like this:

$ cat /etc/hosts
127.0.0.1 server.example.com server
127.0.0.1 localhost.localdomain localhost
127.0.0.1 localhost4.localdomain4 localhost4

Contrary to some guides I read you don't need to add anything to your /etc/hosts file. With the above you'll be able to send mail from any number of virtual hosts on your droplet.

You need to install sendmail
Obviously, sendmail isn't going send mail if it isn't installed.

# yum install sendmail

Again, contrary to some guides I've seen there's nothing to configure. That said, you will need to make sure that SELinux isn't preventing Apache from sending mail. If you see something like this in /var/log/maillog...

NOQUEUE: SYSERR(apache): /etc/mail/sendmail.cf: line 0: cannot open: Permission denied

... then you should check the value of SELinux's httpdcansendmail boolean:

# getsebool httpd_can_sendmail
httpd_can_sendmail --> on

If the output shows httpdcansendmail is off then you can run:

# setsebool -P httpd_can_sendmail on

Again, that all you need to do. No need to restart httpd or anything.

The email address you're sending from must exist
You need to make sure that the mailbox you're sending from exists on the server that's relaying your emails. If it doesn't you'll see errors like these in /var/log/maillog:

550-Verification failed for <website@mydomain.com> 550-No Such User Here 550 Sender verify failed (in reply to RCPT TO command)

You need a valid MX record
If at this stage you're seeing errors like this in /var/log/maillog...

rejected MAIL <website@mydomain.com>: Access denied - Invalid HELO name (See RFC2821 4.1.1.1)

... then you probably either don't have an MX record for the domain (here mydomain.com) or an invalid MX record.

$ dig mydomain.com MX +short
0 sending.server.com

Here, I'm sending emails for the domain example.com via a server called sending.server.com. The MX record therefore simply points to sending.server.com (with a priority of 0).

For good measure you should probably add an SPF record. That is a simple TXT record that stores the IP address of the sending server (that is, the server that is relaying the emails - not your droplet). In the below example 12.34.56.78 is the IP address of sending.server.com:

$ dig mydomain.com TXT +short
"v=spf1 +a +mx +ip4:12.34.56.78 ~all"

Hopefully this will help someone!

Have another answer? Share your knowledge.