Proper setup of the mail sending server for PHP scripts, setting up the mail () function

    In this topic, you will learn how to correctly configure outgoing mail server and in particular the mail () function in PHP. I myself am a terrible pedant. I love that everywhere everything was in place, I can’t stand hacking. Seeing once complete nonsense in the message headers from my server, I dealt with this drastically and unconditionally. By proper configuration, I mean one that satisfies the needs of spam filters of large mail systems, and just looked beautiful and meaningful.

    As you know, the SMTP protocol does not imply any means of protection against spam and user authentication, therefore, large and not very companies have come up with “fixes” of protocol security.
    If you are installing a dedicated server with a domain hosted on it, it is highly recommended that you complete these settings so that everything is as it should.

    I spent a lot of time studying this issue, sorting through each headline. I started with the basic settings from the packages, and from the packages I selected, I liked what I liked, and ended up with a thin feng shui, which I didn’t fully realize, because it was already quite sophisticated.

    The title title chose just that, since at the beginning of my journey I was looking for something like this. We will configure postfix, php, dns (ptr, spf), and more.

    This article will be interesting to people setting up dedicated servers, but no less interesting for ordinary programmers .

    Details under the cut

    Preamble


    Someone uses libs that replace the mail function (for example phpmailer), they can communicate with SMTP directly, or they can send to the local server. But it is better to use the standard built-in and configured PHP mail () function which will send mail to the local outgoing mail server, which in turn will deal with it itself. When using this function, the brakes are always the smallest, since the local mail agent quickly accepts or rejects mail, and if it does, it delivers it on its own.

    The article is not formatted in the best way. I apologize, time is running out, but I want to tell while I remembered, otherwise there will be no time.

    How to check our work?


    Testing with this method
    $result = mail('yourmail@domain.ru', 'subject', 'message');
    if($result)
    {
    	echo 'все путем';
    }
    else
    {
    	echo 'что-то не так';
    }
    


    We will read a lot of headings of letters. Viewing headers is very convenient in gmail, there is such a feature in 2 clicks, you will find it yourself.

    What goals do we need to achieve in the headlines?


    - These are the headers from gmail.com
    Please note that these are the headers with which the letter falls into the end-user box
    Delivered-To: YOURMAIL@DOMAIN.DOM
    Received: by 10.182.0.137 with SMTP id 9cs9033obe;
            Sat, 21 Jan 2012 13:25:09 -0800 (PST)
    Received: by 10.205.119.199 with SMTP id fv7mr1052469bkc.113.1327181107295;
            Sat, 21 Jan 2012 13:25:07 -0800 (PST)
    Return-Path: 
    Received: from wartur.ru (wartur.ru. [188.134.79.140])
            by mx.google.com with ESMTP id ua10si4066845bkb.110.2012.01.21.21.13.25.06.06;
            Sat, 21 Jan 2012 13:25:07 -0800 (PST)
    Received-SPF: pass (google.com: domain of no-reply@wartur.ru designates 188.134.79.140 as permitted sender) client-ip = 188.134.79.140;
    Authentication-Results: mx.google.com; spf = pass (google.com: domain of no-reply@wartur.ru designates 188.134.79.140 as permitted sender) smtp.mail=no-reply@wartur.ru
    Received: by wartur.ru (Postfix, from userid 1002)
    	id 9913B61D; Sun, 22 Jan 2012 01:24:55 +0400 (MSK)
    To: YOURMAIL@DOMAIN.DOM
    Subject: subject
    X-PHP-Originating-Script: 1002: index.php
    Message-Id: <20120121212455.9913B61D@wartur.ru>
    Date: Sun, 22 Jan 2012 01:24:55 +0400 (MSK)
    From: no-reply@wartur.ru
    

    - And also these headers from mail.ru
    Return-path: 
    Received-SPF: pass (mx64.mail.ru: domain of wartur.ru designates 188.134.79.140 as permitted sender) client-ip = 188.134.79.140; envelope-from=no-reply@wartur.ru; helo = wartur.ru;
    Received: from [188.134.79.140] (port = 64667 helo = wartur.ru)
    	by mx64.mail.ru with esmtp (envelope-from )
    	id 1RoiQJ-0005E9-6r
    	for wartur@list.ru; Sun, 22 Jan 2012 01:24:31 +0400
    X-Mru-BL: 0: 0: 0: 0
    X-Mru-PTR: wartur.ru
    X-Mru-NR: 1
    X-Mru-OF: Linux (ethernet / modem)
    X-Mru-RC: RU
    Received: by wartur.ru (Postfix, from userid 1002)
    	id 460BC9B7; Sun, 22 Jan 2012 01:24:20 +0400 (MSK)
    To: wartur@list.ru
    Subject: subject
    X-PHP-Originating-Script: 1002: index.php
    Message-Id: <20120121212420.460BC9B7@wartur.ru>
    Date: Sun, 22 Jan 2012 01:24:20 +0400 (MSK)
    From: no-reply@wartur.ru
    X-Spam: Not detected
    X-Mras: Ok
    X-Mru-Authenticated-Sender: uid: 1002@wartur.ru
    


    When you first start, you will see that you do not have such beautiful headlines. The receiving mail server will consider you some kind of chummek, and it will write about this in the header of the letter with a warning that just a little bit more and it will put you in the black list for sure. All information in the header is used by all server chains and the receiving agent in order to reject or accept the message, depending on the settings of the spam filter. The most dragon methods are black lists, while the soft ones identify the bad ones according to headings and complaints.

    I also notice that if you set the 4th parameter in the mail () function and put the From header there, the From: no-reply@wartur.ru header will also change, and if you do not set it, it will be automatically detected the same as the header Return-path:what you can see in my headlines.
    Such a scheme is very convenient: sending goes through a server with a modified From header, and receiving it on gmail (through domain services). It is desirable that the mail also belong to the same domain for which the server is configured, as well as some of the points listed below are fulfilled.

    Let's get started


    - The
    Lord’s advice , I like to put everything in packages, and I don’t advise beginners to do amateur performances, many packages already have automatic configuration scripts, the results of which need only to be slightly corrected and everything will be fine. In addition, from the repositories it is updated itself and generally less zapara just because it is less.

    - Setting up PHP
    We put as we want php, is it you somehow without me.

    Go to php settings, replace equivalently:
    sendmail_path = / usr / sbin / sendmail -t -i -fno-reply@wartur.ru
    


    By this we indicated the Return-Path header:

    By the way, 1: it will be such for all virtual domains of the server, to fix it and configure it for the current one, you need to pass the 5th parameter to the mail () function.
    $result = mail('YOURMAIL@DOMAIN.DOM', 'subject', 'message', 'From ...', '-fno-reply@yourdomine.ru');
    

    By the way 2: if you put the 5th parameter on a shared hosting, then you are also advised to configure your domain, as described below. I draw your attention to the fact that it is impossible to do an operation with PTR records, since 1 IP = Domain, or at least it is not recommended to do 2 of them, I don’t remember already.

    - Configuring MTA , it is also a local outgoing mail server.
    I sincerely recommend postfix to you, then we go to the /etc/postfix/main.cf settings
    for those who have already run into sendmail and realized how hard they are to cut out of the system, I advise the command:
    aptitude purge sendmail
    


    Next, we do it equivalently like this
    myhostname = wartur.ru
    #smtp_helo_name = k-wartur.wartur.ru
    mydestination = _ALL_, wartur.ru, k-wartur.wartur.ru, localhost.wartur.ru, localhost

    (k-wartur.wartur .ru is my server in the wartur.ru domain)

    - If I am not mistaken, this helped. When the delivery agent is presented to another server, HELO is transmitted. Change myhostname, the following header will change:
    Message-Id: <20120121212420.460BC9B7@wartur.ru>

    - smtp_helo_name by default is myhostname, we read the materiel

    - mydestination - if I’m not mistaken, this sets the domains from which MTA will receive mail for processing, if you have shared hosting (which I installed on the server at home), then without _ALL_ you will have problems sending mail from domains other than those indicated .

    Well, you see, the headings are already much more correct, aren't they, otherwise there was horror at first.

    - Showdown with mail services (mailers)
    And they consider us as an unkind source.
    Our server was able to correctly introduce itself helo, but only the mailers still do not trust us.
    An algorithm was invented for this, so that the domain owner using DNS (if he is of course literate like us) could indicate that such and such servers can be trusted, but not others.

    Instead of the horror that you should now have this:
    Received-SPF: pass (google.com: domain of no-reply@wartur.ru designates 188.134.79.140 as permitted sender) client-ip = 188.134.79.140;
    Received-SPF: pass (mx64.mail.ru: domain of wartur.ru designates 188.134.79.140 as permitted sender) client-ip = 188.134.79.140; envelope-from=no-reply@wartur.ru; helo = wartur.ru;
    


    We are already on the way to the truth. By the way, by default, the mailer considers everything as v = spf1 ~ all, which lowers the threshold for entering the blacklist, and you can also use your domain to send spam, and you yourself did not know that they would mark it as bad for future times.

    We go to the DNS and create a TXT record in your domain, in my case wartur.ru
    v = spf1 + mx + a: wartur.ru + a: k-wartur.wartur.ru + include: gmail.com -all

    v = spf1
    this means that the version of the spf1

    + mx algorithm
    You can trust mail if it is sent from mx servers, for example if mx.wartur.ru is a receive server, then if this server sends, then everything will be fine.

    + a: wartur.ru
    You can trust the server serving the wartur.ru domain

    I’ll also add, for example, pupkin.ru was located on my mail server.
    I gave Pupkin a drive to my outgoing mail server k-wartur.wartur.ru (the usual situation of shared hosting, it always costs locally, like a database, and that's all). Then he must configure + a: k-wartur.wartur.ru

    + include: gmail.com,
    import all the rules gmail.com, they also have such a TXT record for their servers. (I use google services for the domain)

    -all We
    indicate that the admin considers other places to be not their own, and this may be the nearest brothel in the gateway sending spam on my behalf
    (+ all which means that the whole world is my friends)

    Self-study materiel
    http : //ru.wikipedia.org/wiki/Sender_Policy_Framework

    - Showdowns with mail services, setting up reverse PTR. Mail service
    providers still ask for reverse PTR domain zones for an additional tick, I think this checkbox is one of the boldest , since it defines the server 100%, and if it behaves correctly, then anybody trusts it very much the letter will surely reach the addressee.
    X-Mru-PTR: wartur.ru, it’s also on google this is Received: from wartur.ru (wartur.ru. [188.134.79.140])

    Note:
    You will not be allowed to do this in shared hosting, they will have to this address Zamapin your server, some servername.badhosting.ru, on which you are located, and indeed only on your own server with its own IP it is possible to crank it up.

    Interesting: If you live at home, and I have one of the servers at home, in particular wartur.ru. What to do? sort of IP is dedicated, but the return address cannot be configured. I called above (to the provider) said they say I want the PTR zone anyway. I did it, very pleased.

    A few more words about headings (all mixed up)


    X-Mru-BL: 0: 0: 0: 0 forbid you to have anything other than zeros, these are blacklisted.
    X-Mru-OF: the interface from which it is sent, I still do not understand what it depends on.
    X-PHP-Originating-Script: - I would advise you to add, although if you really care about security and non-disclosure, then you can forbid it. This is done not far from the PHP settings that we did. Enabled by default.

    It is also possible and interesting to see what Yandex writes at the reception, it is very interesting.

    Additionally


    There are still some digital signatures.
    defined by the header, DKIM-Signature
    In appearance, I already had everything in order, but this header is not really needed. Usually it is needed by a very large-scale service like facebook or google where the distribution of notifications and mail is on a gigaton scale. If your service does not have millions of users, then do not think about it, although if you are a researcher - write how about it here and we will link the articles - so that everything seems completely finished, only I ask you to write much easier, as I've already seen it somewhere articles about it all. On my own I will add that I was too lazy to install another package, understand and something else.



    Unfortunately, there is no material, since I collected it bit by bit from everywhere 4 months ago, then I did not have time, and now I wrote from memory.

    Successful competent setup of your server. I tried to explain at least one of several aspects of the setup.

    UPD:
    Found an interesting proof on the topic: http://forum.ixbt.com/topic.cgi?id=7:26978

    It is also interesting to read:
    http://habrahabr.ru/blogs/sysadm/114852/

    UPD2: 2012.08. 02
    Cool article on the topic!
    http://habrahabr.ru/post/141534/

    UPD3: 2013.04.04
    Hoping for the consciousness / attentiveness of people, I set up a work address, so you saw the real picture and changed them. Not once did I receive messages with meaningless content in the mail, so I changed the address to YOURMAIL@DOMAIN.DOM

    Also popular now: