Konfiguracja PHP do wysyłki maili przez SMTP

Od dłuższego czasu zastanawiam się jak sensownie rozwiązać powyższy problem.

Czemu nie mogę wysyłać maili normalnie?
Na domenach skonfigurowane jest SPF, DKIM i DMARC, przez co wysyłając maile z pominięciem MTA nie są one podpisywane przez DKIM co powoduje DMARC = fail.

Zastosowanie bibliotek PHP typu SwiftMailer.
Najprostsze rozwiązanie, ale nie wszędzie można łatwo wprowadzić i dodatkowo każdy ze skryptów/cmsów trzeba odpowiednio dostosować i skonfigurować. Do tego dochodzi konfiguracja tego pod każdą domenę. Potrzebuję rozwiązania które będzie bardziej abstrakcyjne i nie będzie wymagało ingerencji w skrypty.

Obecnie mam to prawie skonfigurowane, tylko…
wysyłając maile przez phpowe mail() dostają one nagłówek smtp.mailfrom: systeuser@s1.server.cpl. Domena s1.server.cpl ma tylko skonfigurowany spf i teraz nie jestem pewny cze powinienem te maile podpisywać kluczem dla poszczególnych domen ponieważ każdy użytkownik to jedna domena, czy może wygenerować dkim dla s1.server.cpl, a może nawet dla smtp.server.cpl i nim podpisywać maile wysyłane przez php.

s1.server.cpl - jest to adres serwera webowego
smtp.server.cpl - adres serwera smtp oba działają na tym samym ip/vps

dlatego mogę skonfigurować MTA tak by pozwalał z localhosta wysyłać maile bez uwierzytelnienia.

Dlaczego biblioteka php do wysyłki maili przez SMTP jest zła?
Ponieważ chcę mieć możliwość wysyłania z serwera WWW maili o różnych zmiennych i nieistniejących adresach email - takich na które nie da się odpowiadać. Nie chce mi się dla każdej domeny tworzyć nawet głupich maili noreply bo to strata czasu, dodatkowo jeśli domena wykorzystuje dwa adresy email do wysyłki maili to dodatkowo utrudnia to konfigurację po stronie skryptu.


Nie wiem teraz w którą stronę iść, czy wymusić w OpenDKIM podpisywanie maili z systeuser@s1.server.cpl kluczem odpowiedniej domeny lub dla domeny s1.server.cpl (bo nie wiem którego klucza powinienem w takim przypadku użyć). Czy może konfigurować PHP tak by nie było informacji o tym że mail wysyłany z konta systeuser@s1.server.cpl.

W pierwszym przypadku nie wiem czy w ogóle nie powinna być to konfiguracja taka, że maile podpisuje kluczem dla domeny s1.server.cpl, a dodatkowo w wlasciwadomena.cpl załączam w jej strefie informacje o wykorzystaniu klucza z zewnętrznej domeny.

PS. Oczywiście są opcje konfiguracyjne php takie jak:

SMTP
smtp_port
sendmail_from

Lecz są one przeznaczone tylko dla Windowsa :smiley:, a ja mam na serwerze linuxa.

I ostatnia rzecz, maile idą przez postfixa, ale nie są podpisywane i nie wiem jak je (jakim kluczem) powinienem je podpisywać. Liczę na czyjąś pomoc bo nie chcę tego sprawdzać metodą prób i błędów bo będzie to trwało kilka dni …

Masz to na localhost lub w tej samej podsieci?

Tak napisałem o tym.

Opis jest tak szczegółowy, że widocznie przeoczyłem.

Jeśli masz to na localhost, to sprawa prosta, w postfix 127.0.0.1 puszczasz pewnie i tak bez sasl. SPF powinien być po sasl_authenticated, bo sprawdzasz SPF nadawcy z zewnątrz, gdyż Twoi klienci są zaufani. SPF ma za zadanie filtrować spamerów. Z DKIM jest o tyle upierdliwe, że klucz generujesz dla każdej domeny.

Problem jest z wysyłką przez postfix czy u odbiorców zewnętrznych?

Na osobnych maszynach postfix można skonfigurować jako klienta smtp, tzw. null mailer lub polecam ssmtp, który lepiej się sprawdzi.

Jak masz ustawiony SPF na DNSie? Żaden SPF nie sprawdza czy adres istnieje. SPF weryfikuje czy nadawca ma prawo wysyłać z domeny, z ktorej otrzymał maila. Tak więc jeśli wysyłasz maila z adresu noexist@server.cpl, a smtp ma smtp.server.cpl i spf mówi, że domena server.cpl ma prawo wysyłać przez smtp.server.cpl to żaden serwer ich nie odrzuci i prawdopodbnie nie trafi do spamu. Twój serwer sprawdza SPF nadawcy z innego serwera, Twój SPF sprawdzany jest przez odbiorcę. Jeśli coś lata w obrębie Twojego serwera (kilka domen) SPFa nie sprawdzasz, dlatego dajesz go po sasl authenticated.

DKIM też jest sprawdzany przez odbiorcę, nie przez Twój serwer. Jeśli Twoi klienci są zaufani (uwierzytelnienia saslem), nie sprawdzasz u siebie DKIM, nie ma takiej potrzeby, bo i po co. Tu też sprawdzasz tylko DKIM nadawcy z innego serwera, przy czym to jest upierdliwe, bo mało kto podpisuje maile DKIM, a 90% maili nie ma SPF lub jest on niepoprawnie skobfigurowany i często dostaję telefony, że “ważny” mail nie dotarł, bo serwer nam się “popsuł”.

1 polubienie

Dzięki za odpowiedź fajnie wszystko opisałeś, ale dalej się nie zrozumieliśmy. Prościej będzie jak załączę reporty i nagłówki maili.

DMARC dla przykładowej domeny w przypadku maili wysyłanych przez serwer WWW

<feedback>
  <report_metadata>
    <org_name>google.com</org_name>
    <email>noreply-dmarc-support@google.com</email>
    <extra_contact_info>https://support.google.com/a/answer/2466580</extra_contact_info>
    <report_id>8034515626504323772</report_id>
    <date_range>
      <begin>1533081600</begin>
      <end>1533167999</end>
    </date_range>
  </report_metadata>
  <policy_published>
    <domain>domena.cpl</domain>
    <adkim>r</adkim>
    <aspf>r</aspf>
    <p>quarantine</p>
    <sp>quarantine</sp>
    <pct>1</pct>
  </policy_published>
  <record>
    <row>
      <source_ip>server_ip_address</source_ip>
      <count>2</count>
      <policy_evaluated>
        <disposition>none</disposition>
        <dkim>fail</dkim>
        <spf>fail</spf>
        <reason>
          <type>sampled_out</type>
          <comment></comment>
        </reason>
      </policy_evaluated>
    </row>
    <identifiers>
      <header_from>domena.cpl</header_from>
    </identifiers>
    <auth_results>
      <spf>
        <domain>s1.server.cpl</domain>
        <result>pass</result>
      </spf>
    </auth_results>
  </record>
</feedback>

Przykładowa wiadomość email

Delivered-To: adresatemail@gmail.com
Received: by 2002:a2e:9bd9:0:0:0:0:0 with SMTP id w25-v6csp2241644ljj;
        Sun, 5 Aug 2018 02:08:01 -0700 (PDT)
X-Google-Smtp-Source: AAOMgpdqOYJYkAYGYlJOrsmazeNCIPXo/2y2LF1uduVLiZeae1Ob0oYa9OqHEUy53OHDhQxo0xYh
X-Received: by 2002:a1c:d942:: with SMTP id q63-v6mr9601414wmg.78.1533460081439;
        Sun, 05 Aug 2018 02:08:01 -0700 (PDT)
ARC-Seal: i=1; a=rsa-sha256; t=1533460081; cv=none;
        d=google.com; s=arc-20160816;
        b=qEwnMl8eW421FB3jlnyUPyC0XqAyrz/JMxVCSURBwuXQ060Y0lxu//jTrT0Yc1N3XJ
         mk8lsqBTstxx2Ge5cfxUOIHiBu4rhmkT79dRUS7BuOlbxHJzxUEg7VXqgegl6UQm66IE
         IqjTWDhiVIKnXhlHscVyxCcHukWCrz9XyoscIoyjN4WtM8eyP7O4FgXULGKTZUjUXIKF
         43y9+N4fTHf6RAQGZhl1K2pVPi3wT50GN3k5t8y91bGnXKTPrKQemVLHkt520RQ/bcY+
         z4Ia/w5ERvjQpeSrz+v+Qd9RrJdHk9z1Xtv148x1CXEadEtZok/Jqa5+r4CQnOS/gOkg
         Iv5A==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816;
        h=content-transfer-encoding:date:message-id:mime-version:sender
         :reply-to:from:subject:to:arc-authentication-results;
        bh=xGoXEPhjPqKnwPg3x9bRNea82bm/BtXLwKPErSmxtsE=;
        b=SYcku4WfEM3l2KIZpDIJ++wpn+Zh04BCbpWD9Co+aZ9OsK1+siHtlrE+vvy7memekr
         +bHWe+1x+U7Z6RgjrV55XbSrnUJaH2qoUhiillNyl28ub9KpgIs7fJ0UHdkkEXdijMQo
         PQ/rl+bGqAXwUAcjnEXNqMacYijdrtdcxxDlTPO9Tlx6ctqmgq6d+LIX9pKTF1RokKls
         NEa1rn8q3envqz1jzQMaSA/ioRYy5hy1JknQVhQgIcFrt5x5HX9w4aXSoP68TjGXkzwK
         KFOUI/fIQMh4Sjk1cmzW59+jSObHZcWhKu9Ko4dfpqjW1UjK9rtxY8dY+53MbPZg5rWK
         fjmQ==
ARC-Authentication-Results: i=1; mx.google.com;
       spf=pass (google.com: domain of systeuser@s1.server.cpl designates <server_ip> as permitted sender) smtp.mailfrom=systeuser@s1.server.cpl;
       dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=domain.cpl
Return-Path: <systeuser@s1.server.cpl>
Received: from smtp.server.cpl (smtp.server.cpl. [<server_ip>])
        by mx.google.com with ESMTPS id a132-v6si2616843wmh.219.2018.08.05.02.08.00
        for <adresatemail@gmail.com>
        (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
        Sun, 05 Aug 2018 02:08:01 -0700 (PDT)
Received-SPF: pass (google.com: domain of systeuser@s1.server.cpl designates <server_ip> as permitted sender) client-ip=<server_ip>;
Authentication-Results: mx.google.com;
       spf=pass (google.com: domain of systeuser@s1.server.cpl designates <server_ip> as permitted sender) smtp.mailfrom=systeuser@s1.server.cpl;
       dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=domain.cpl
Received: by smtp.server.cpl (Postfix, from userid 1004) id 49E0A24418; Sun,
  5 Aug 2018 10:58:22 +0200 (CEST)
To: <user_nickname> <adresatemail@gmail.com>
Subject: czesc22
X-PHP-Originating-Script: 1004:functions_messenger.php
From: <no-retry@domain.cpl>
Reply-To: adresatemail@gmail.com
Sender: <no-retry@domain.cpl>
MIME-Version: 1.0
Message-ID: <103ed62dafac62acabe3c5f9a897bc93@www.domain.cpl>
Date: Sun, 05 Aug 2018 10:58:22 +0200
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: phpBB3
X-MimeOLE: phpBB3
X-phpBB-Origin: phpbb://www.domain.cpl
X-AntiAbuse: Board servername - www.domain.cpl
X-AntiAbuse: User_id - 2
X-AntiAbuse: Username - <user_nickname>
X-AntiAbuse: User IP - <user_ip_address>

Witaj <user_nickname>,

Tę wiadomość wysłał(a) do Ciebie <user_nickname> przez Twoje konto na "domain.cpl -
serwery Counter-Strike". Jeśli jest to spam lub zawiera obraźliwe treści,
to wyślij informację o tym na ten adres e-mail:

no-retry@domain.cpl

Załącz cały e-mail (szczególnie nagłówki). Zauważ, że adres e-mail nadawcy
tej wiadomości został ustawiony na ten należący do <user_nickname>.

Treść wiadomości:
~~~~~~~~~~~~~~~~~

asdas

-- 
Dziękujemy, Ekipa

Teraz tak:

  • domain.cpl - jest to jedna przykładowa domena dla której chcę wszystko skonfigurować
  • s1.server.cpl - jest to domena serwera WWW, skonfigurowanego podobnie jak shared hosting, czyli na jednym ip tak naprawdę jest WWW/SMTP/IMAP/FTP/MariaDB
  • systeuser@s1.server.cpl - jest to nazwa użytkownika w systemie - “konto” hostingowe z uprawnieniami którego działa pool php, ma public_html i podpiętą pod niego domain.cpl
  • smtp.server.cpl - jest to nazwa oraz adres domenowy serwera SMTP, który jest na tej samej maszynie co s1

Konfiguracja domen:

  • domain.cpl - rekordy DNS: MX, SPF (mx, a, include: s1.server.cpl -all), DKIM oraz DMARC. Na SMTP: DKIM, które podpisuje maile w przypadku wysyłki ich z thunderbirda - tutaj 0 problemów wszystko działa idealnie dla wszystkich domen
  • s1.server.cpl - rekordy DNS: MX, SPF. Na SMTP brak dodatkowej konfiguracji.

Wygląda to tak, że w obecnej sytuacji wysyłając maile przez PHP gdzie serwer nazywa się s1.server.cpl maile wychodzą jakby spod jego domeny. SPF dla domeny zezwala na jego wysyłkę, ale przez brak podpisu DKIM nie przechodzą one DMARC.

Pytania - to czego nie wiem
Teraz nie wiem czy dodać DKIM dla s1.server.cpl czy skonfigurować DKIM tak by dla maili wysyłanych przez systeuser@s1.server.cpl podpisywał je kluczem domain.cpl.
A może istnieje jeszcze jedno wyjście - skonfigurowanie PHP tak by nie było śladu po s1.server.cpl i systeuser, co byłoby najlepszą opcją. Wiem, że uzyskałbym to przez wysyłkę maili przy pomocy SwiftMailer zamiast phpowego mail(), ale nie chcę musieć modyfikować wszystkich skryptów jakie przyjdzie mi zainstalować na serwerze.

@offtop
Generalnie wszystko działa maile nie lądują w spamie nawet na gmailu, ale nie chcę mieć kolejnego kiepsko skonfigurowanego serwera SMTP :confused:. Chcę udowodnić sobie, że da się to zrobić dobrze i maksymalnie bezpiecznie, do tego rozwiązać to tak by było całkowicie wygodnie.

Okazało się, że Postfix dla maili wysyłanych przez PHP w ogóle pomija wszystkie ustawione filtry.

Powodem takiej sytuacji był brak włączonych filtrów (w tym właśnie DKIM) dla wiadomości non smtpd, czyli wysyłanych np. przy pomocy komendy sendmail.
Wystarczyło dodać filtry w postfixe i wszystko działa. Komenda odpowiedzialna za filtry na wiadomościach wysyłanych przez między innymi komendę sendmail to: non_smtpd_milters. Odpowiednia konfiguracja tej opcji w main.cf Postfixa załatwiła sprawę.

Nie było potrzeby też dodawania dodatkowych klucz DKIM dla domeny s1.server.cpl, ani podpisywania kluczem domeny maili użytkownika systemowego.

1 polubienie