Полный тест SMTP

Полный тест SMTP

Скрипт проверяет настройки PHP mail(), DNS-записи домена, доступность SMTP-портов и отправку письма через прямой socket. Домен и email-адреса вынесены в переменные — достаточно поменять их в одном месте.

Внимание

Скрипт предназначен только для отладки. Он раскрывает конфигурацию сервера и позволяет инициировать отправку писем. После проверки обязательно удалите файл с сервера.


Что проверяется

  1. INI-настройки PHP — SMTP, smtp_port, sendmail_from, sendmail_path.
  2. DNS-записи домена — MX и TXT (в том числе SPF/DKIM/DMARC).
  3. Доступность портов — 25, 465, 587 для SMTP-хоста и localhost.
  4. Отправка письма — прямой socket-тест SMTP-сессии.

Что делать со скриптом: пошаговая инструкция

Шаг 1. Сохранить файл на сервере

Создайте файл, например smtp-test.php, в корне сайта или в отдельной директории:

/public_html/smtp-test.php

Убедитесь, что у файла есть права на чтение веб-сервером (обычно 644).

Шаг 2. Настроить переменные под свой домен

Откройте файл и отредактируйте блок в самом начале:

$domain    = 'example-test.ru';
$fromEmail = 'sender@' . $domain;
$smtpHosts = ['smtp.example-test.ru', 'localhost'];
$toEmail   = 'recipient@example-test.ru';
$testEmail = 'test-user@example-test.ru';
  • $domain — домен, для которого проверяются MX/TXT-записи и который подставляется в EHLO.
  • $fromEmail — адрес отправителя. Если домен уже указан в $domain, менять его отдельно не нужно.
  • $smtpHosts — список хостов, у которых проверяются порты 25/465/587. Обычно это smtp.<ваш-домен> и localhost.
  • $toEmail и $testEmail — адреса, куда будет отправлено тестовое письмо.

Если тестируете реальный домен, укажите настоящие значения. Если хотите просто прогнать скрипт «вхолостую» — оставьте тестовые.

Шаг 3. Запустить через браузер

Откройте в браузере:

https://ваш-сайт.ru/smtp-test.php

Скрипт выведет четыре раздела с результатами. Ошибки PHP включены (error_reporting(E_ALL)), поэтому при проблемах вы увидите предупреждения и уведомления прямо на странице.

Шаг 4. Прочитать результаты

1. PHP mail() настройки

Показывает текущие INI-значения:

  • SMTP — адрес SMTP-сервера (на Linux обычно пусто, на Windows — localhost).
  • smtp_port — порт (по умолчанию 25).
  • sendmail_from — адрес отправителя по умолчанию.
  • sendmail_path — путь к sendmail/msmtp, если используется.

Если sendmail_path пустой и SMTP пустой — PHP-функция mail() скорее всего не работает. Это нормально для хостингов, где почта отправляется через внешний SMTP.

2. DNS-записи домена

Выводятся MX и TXT-записи:

  • MX — какие серверы принимают почту для домена.
  • TXT — SPF, DKIM, DMARC-записи. Проверьте, что SPF содержит нужные IP/хосты, а DMARC не в режиме p=reject без настроенного DKIM.

Если MX-записей нет — домен не сможет принимать почту. Если TXT пустые — письма будут попадать в спам.

3. Проверка портов

Для каждого хоста из $smtpHosts проверяются порты:

  • 25 — классический SMTP (часто блокируется хостерами).
  • 465 — SMTP over SSL.
  • 587 — SMTP с STARTTLS (рекомендуется для отправки).

Если все порты закрыты — сервер не сможет подключиться к SMTP. Обратитесь к хостеру или используйте внешний сервис (Yandex, Mailgun, SendGrid).

4. Тест отправки

Функция testSMTPDirect() открывает socket к localhost:25, выполняет минимальную SMTP-сессию (EHLO → MAIL FROM → RCPT TO → DATA → QUIT) и возвращает ответ сервера.

  • Если в ответе 250 OK — локальный SMTP работает.
  • Если Connection refused — SMTP на localhost не запущен.
  • Если Relay access denied — сервер не принимает письма от вашего домена.

Шаг 5. Что делать с результатами

Проблема Решение
sendmail_path пуст, mail() не работает Установите msmtp или sendmail, либо используйте SMTP-библиотеку (PHPMailer, Symfony Mailer)
MX-записи отсутствуют Настройте MX у регистратора домена
Нет SPF/DKIM/DMARC Добавьте TXT-записи у DNS-провайдера
Порты 25/465/587 закрыты Попросите хостера открыть порт или используйте внешний SMTP
Relay access denied Настройте аутентификацию в SMTP или разрешите релей для localhost
Письма уходят в спам Проверьте SPF, DKIM, DMARC, reverse DNS (PTR)

Шаг 6. Удалить файл

После отладки обязательно удалите smtp-test.php с сервера:

rm /public_html/smtp-test.php

Или замените его содержимое на пустой <?php // disabled ?>.


Код

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);

$domain    = 'example-test.ru';
$fromEmail = 'sender@' . $domain;
$smtpHosts = ['smtp.example-test.ru', 'localhost'];
$toEmail   = 'recipient@example-test.ru';
$testEmail = 'test-user@example-test.ru';

echo "<h2>Полный тест SMTP для домена: {{ '{{' }}$domain{{ '}}' }}</h2>";

// 1. INI
echo "<h3>1. PHP mail() настройки:</h3>";
echo "SMTP = " . ini_get('SMTP') . "<br>";
echo "smtp_port = " . ini_get('smtp_port') . "<br>";
echo "sendmail_from = " . ini_get('sendmail_from') . "<br>";
echo "sendmail_path = " . ini_get('sendmail_path') . "<br>";

// 2. DNS
echo "<h3>2. DNS записи для {{ '{{' }}$domain{{ '}}' }}:</h3>";
$records = dns_get_record($domain, DNS_ALL);
foreach ($records as $record) {
    if ($record['type'] == 'MX' || $record['type'] == 'TXT') {
        print_r($record);
        echo "<br>";
    }
}

// 3. Порты
echo "<h3>3. Проверка портов:</h3>";
$ports = [25, 465, 587];
foreach ($smtpHosts as $host) {
    echo "<b>$host:</b><br>";
    foreach ($ports as $port) {
        $fp = @fsockopen($host, $port, $errno, $errstr, 5);
        echo $fp
            ? "Порт $port: ОТКРЫТ<br>"
            : "Порт $port: ЗАКРЫТ ($errstr)<br>";
        if ($fp) fclose($fp);
    }
    echo "<br>";
}

// 4. Отправка через socket
echo "<h3>4. Тест отправки:</h3>";

function testSMTPDirect($host, $port, $from, $to, $domain) {
    $socket = fsockopen($host, $port, $errno, $errstr, 30);
    if (!$socket) return "Ошибка подключения: $errstr";

    fgets($socket, 4096);
    fputs($socket, "EHLO {{ '{{' }}$domain{{ '}}' }}\r\n");
    fgets($socket, 4096);

    fputs($socket, "MAIL FROM: <$from>\r\n");
    fgets($socket, 4096);

    fputs($socket, "RCPT TO: <$to>\r\n");
    fgets($socket, 4096);

    fputs($socket, "DATA\r\n");
    fgets($socket, 4096);

    fputs($socket, "Subject: Test\r\n");
    fputs($socket, "From: $from\r\n");
    fputs($socket, "To: $to\r\n\r\n");
    fputs($socket, "Test message\r\n.\r\n");
    $response = fgets($socket, 4096);

    fputs($socket, "QUIT\r\n");
    fclose($socket);
    return $response;
}

echo "Результат socket отправки: " .
    testSMTPDirect('localhost', 25, $fromEmail, $testEmail, $domain);

Настройка

Замените значения переменных на нужные:

$domain    = 'your-domain.ru';
$fromEmail = 'sender@' . $domain;
$smtpHosts = ['smtp.your-domain.ru', 'localhost'];
$toEmail   = 'recipient@your-domain.ru';
$testEmail = 'test-user@your-domain.ru';

Все производные значения ($fromEmail, EHLO, DNS-запрос) подставятся автоматически.