How can I change Return-Path: www-data@localhost.localdomain?

January 16, 2017 771 views
Email PHP Ubuntu 16.04

I have a huge issue with emails being blacklisted, due to the fact that their return-path is set to www-data@localhost.localdomain, so is there anyone who knows how to change that email to use my domain name?

This is one of the errors that I can see in my email headers:

*Received-Spf: neutral (google.com: 1.1.1.1 is neither permitted nor denied by best guess record for domain of www-data@localhost.localdomain) client-ip=1.1.1.1; *

Everything is setup correctly in my PHP function for sending an email, where the sender and reply emails are using the correct domain name, but not the return-path email?

$output .= 'From: '.$this->headers['from'].' <'.$this->headers['sender'].'>'."\r\n";
$output .= 'Reply-To: '.$this->headers['from'].' <'.$this->headers['sender'].'>'."\r\n";
$output .= 'Return-Path: '.$this->headers['from'].' <'.$this->headers['sender'].'>'."\r\n";

I use an Ubuntu 16.04 installation with WordPress and I've activated the Postfix package, which is used to send email via a contact form and a simple PHP mail() function.

3 Answers

@richardpersson

How was Postfix setup?

PHP relies heavily on how you've configured sendmail. You can set From, Reply-To, and Return-Path, but unless your mail server is properly configured, it'll still show as being sent by whatever user you are logged in as.

For example, on a Droplet I have deployed right now, the only configuration I've setup for sendmail is what was provided when I ran sudo apt-get -y install postfix, nothing more. As a result, when mail is sent using mail(), I see that the message was actually sent by

root@dev.localdomain

The reason dev.localdomain shows is because a hostname has yet to be set for the Droplet, which you need to do. This can be done by using the hostname command and then adding whatever you wish to use as a hostname as an option.

For example, running:

hostname dev.mydomain.com

Sets my hostname and changes the sent by header I see when viewing the mail to:

root@dev.mydomain.com

That being said, when it comes to running a mail server, there's actually a lot more involvement than just installing and configuring Postfix to send mail. If you want e-mail to stay out of the SPAM box, you need to be setup to use SPF, DKIM, and potentially even DMARC (which can be setup with Postfix, but it's a bit time consuming to do so).

You also need to have proper reverse DNS setup. That can only be setup by setting the name of your Droplet to the hostname you set using the command above.

When you created the Droplet, you remember the input box at the end? That's where you can set the name of your droplet to match that of your hostname. You can optionally login to the DigitalOcean CP, click on the name of the droplet you want to modify, and then click on the droplet name and you'll see an inline-edit input pop up. You can use that to change your droplets' name after deployment.

Why does the name matter? DigitalOcean automatically creates your reverse DNS (i.e. PTR) records for you when you deploy a droplet. If the droplet name and the hostname of your droplet do not match, it won't be considered valid when a lookup is performed.

All that being said, if you're using WordPress and don't want to go through the hassle of all the above, the best thing to do would be to use an external e-mail service such as Mailgun or SendGrid, both of which offer plugins to integrate with their services.

Using an external mail service removes the need for you to rely on properly setting up and configuring a working mail server on your end.

Just to clear things out, I do not want to host any emails at DigitalOcean, I have an external resource for that, so I don't want any MX records set up for emails.

I only want my visitors to contact me via my website and a form that uses PHP with a simple mail() function, which clearly submit content and sends an email.

The issue I have is that those emails ends up in the spam folder, because of the Return-Path: www-data@localhost.localdomain.

It seems to be very unclear on how to set this up properly, especially if I would like to use an normal email as the Return-Path: inquiry@company.com, which then would be the same as the sender email?

It looks like my PTR is correct:

1.1.1.1.in-addr.arpa domain name pointer mydomain.com.

I've added two SPF records:

TXT 
mydomain.com
v=DMARC1; p=none    
3600
TXT 
mydomain.com
v=spf1 +a +ip4:1.1.1.1 ~all
3600

My /etc/hosts file contains the following:

127.0.0.1 localhost.localdomain localhost
127.0.0.1 localhost.localdomain localhost mydomain

My /etc/postfix/main.cf file contains the following:

smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
myhostname = mydomain.com
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = $myhostname, mydomain.com, localhost, localhost.localdomain, localhost
relayhost = 
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = loopback-only
inet_protocols = all

I'm sadly not a server administrator and some technical terms is totally alien for me, so I would appreciate a clear and simple explanation.

So what is incorrect here, or what else need to be changed?

  • @richardpersson

    Unless you've installed and setup the software required to use SPF, DKIM, and DMARC, the DNS entries won't do anything for you -- essentially, they're not valid and may potentially result in your Droplet's IP being blacklisted.

    The ultimate goal here is staying out of the Junk/Spam box, correct? You can go about this a few ways -- handle sending the mail externally or configure your Droplet as working mail server.

    Why? -- Because to get your mail through, it needs to be authenticated.

    SPF is essentially an e-mail validation system and it's designed to prevent spoofing. DKIM is, in simple terms, a way to associate your domain name with mail sent from it. It signs e-mail with a digital signature, which is added to the header of the e-mail.

    PHP's mail() function doesn't care if a domain has proper SPF, DKIM, or DMARC entries set up. Simply pass what it requires and it'll send. The receiving mail server, however, does care. Why? Because using PHP's mail() function essentially allows you to pose as anybody. I could wrap it around a function and use your domain and any address I believe is valid and mail-bomb away. Without these solutions, those e-mails would be valid and make their way through. Because of these solutions, they don't.

    Example of Potential Abuse

    Let's say I knew your domain and created an array of 10,000+ potential e-mail addresses (easily done using auto-generators) and then create a function such as the one below.

    <?php
    /**
     * Assume that the $emails array is filled with 10,000+ potential e-mails that
     * are potentially associated with your domain. Assume that the $headers array
     * is filled with headers I'm spoofing to get mail through.
     */
    $emails  = [];
    $headers = [];
    
    function mailBomb( array $data, array $headers )
    {
        $mailHeaders = '';
    
        foreach ( $headers as $header )
        {
            $mailHeaders .= $header . "\r\n";
        }
    
        foreach ( $emails as $email )
        {
            mail(
                $email,
                "Important Message from YourCompany L.L.C",
                "...insert spammy message here...",
                $mailHeaders
            );
        }
    }
    
    mailBomb( $emails, $headers );
    

    NOTE: This is just a very basic example. It'll work, but if someone really wanted to abuse it, something far more complex could be used.

    We could even extend that to sleep every XX messages to prevent detection. We could also add an array of subjects and for every XX messages, change the subject line. This prevents you from easily blacklisting.

    So you're thinking of simply blacklisting what shows under the Sent by header? Nope. Without SPF or DKIM entries in your DNS telling providers that your real mail servers are elsewhere, I can name that sever anything I want, including your domain, so if you want to blacklist it, you'd have to blacklist your domain, which means you wouldn't be able to receive mail from any e-mail address on your domain.

    See why these entries matter? Without them, this kind of thing can happen and it did before they existed. I've ran 4 web hosting businesses over the last 15 years -- I've dealt with it way too many times prior to these solutions existing.

    Back To Your Options

    Sending mail externally is going to be the best option and if you're already using an external service, use it. You can use existing PHP libraries such as SwiftMail and phpMailer to connect to most anything that allows it. Once connected, you use that library to send the mail.

    http://swiftmailer.org

    https://github.com/Synchro/PHPMailer

    That said, you need to make sure you have valid SPF and DKIM setup for that external service as well, or you may land in the same boat. You'd need to check with that provider and see how they require you to configure / set things up.

Have another answer? Share your knowledge.