Отправлять почту со своего выделенного VPS сервера
Пользуясь выделенным сервером (VPS) для хостинга своего сайта часто возникает проблема с отправкой почты: поднимать свой полноценный сервер слишком трудоёмко, и даже следуя всем инструкциям результат не гарантирован. Хорошее решение проблемы - использовать сторонний сервер.
Варианта тут три:
- Отправлять почту через sendmail или встроенные средства языка PHP без всякой авторизации. Обычно такие способы настроены по умолчанию во всех современных движках сайтов (Joomla, WordPress). Проблема лишь только одна: ваши письма всегда будут попадать в спам. Потому, что без авторизации на почтовом сервере к письму не добавляется информация о подлинности, и у принимающего сервера нет уверенности, что письмо отправил действительно хозяин почтового ящика. Оно попадает в спам.
- Использовать чужой почтовый сервер со своим доменным именем. Например почта у вас будет Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в вашем браузере должен быть включен Javascript., а почтовый сервер будет mail.ru. Настроить всё можно за час, а конечные пользователи не заметят разницы
- Если вам не обязательно отправлять почту со своего доменного имени, а вполне устроит @gmail.com или @mail.ru, то проще всего настроить отправку почты с авторизацией по SMTP
Joomla: настройка отправки почты через SMTP
Примерные настройки показаны на скриншоте:
Важно удостовериться, что поле "Имя пользователя" и "Email сайта" совпадают.
Ошибка в перечисленных адресах отправителей
Если вы видите эту ошибку, причин может быть несколько:
- Неправильный логин/пароль от почты
- поле "Имя пользователя" и "Email сайта" не совпадают. Иными словами, авторизируясь как vasya@ вы пытаетесь отправить почту от имени petya@.
- Неправильные настройки vps-сервера. Об этом отдельно
Неправильные настройки VPS сервера при отправке почты
Как проверить
Можно написать простой скрипт на питоне:
to = Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в вашем браузере должен быть включен Javascript.'
gmail_user = Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в вашем браузере должен быть включен Javascript.'
gmail_pwd = 'mypass'
print "smtp.."
smtpserver = smtplib.SMTP("smtp.gmail.com",587)
#smtpserver = smtplib.SMTP("64.233.162.108",587)
print "ehlo..."
smtpserver.ehlo()
print "starting tsl..."
smtpserver.starttls()
print "ehlo2..."
smtpserver.ehlo() # extra characters to permit edit
print "logining..."
smtpserver.login(gmail_user, gmail_pwd)
header = 'To:' + to + '\n' + 'From: ' + gmail_user + '\n' + 'Subject:Hello \n'
print header
msg = header + '\n this Hello from lubov 5 try \n\n'
print "sending"
smtpserver.sendmail(gmail_user, to, msg)
print 'done!'
smtpserver.quit()
Видите в скрипте закомментированную строчку с IP вместо имени почтового сервера?
Попробуйте по ip, если не заработает по имени.
Запускаем через:
time python ./script.py
При этом команда time выведет время исполнения скрипта.
Причина 1. Не открыт исходящий порт для IMAP соединений
Если у вас VPS сервер, то скорее всего у вас настроен файрвол (если нет, то скорее же его поставьте).
В настройках iptables нужно открыть 25 порт для исходящих соединений. На разных дистрибутивах это делается немного по-разному, поэтому конкретные команды писать не буду.
Также нужно не забывать что если у вас настроена сеть по Ipv6, то нужно также настроить правила для ip6tables.
Причина 2. Хостер не пропускает почтовые соединения по IPv6
У меня в итоге оказалась именно эта проблема. Хостер DigitalOcean не пропускает соединения к почтовым серверам по ipv6.
Вышеприведённый скрипт коннектился и отправлял почту, но это занимало больше 2х минут. Если же к серверу обращаться по IPv4, то почта отправлялась за пару секунд.
Не отправляется почта по ipv6. Решение для Joomla 2.5
Решение состоит в том, чтобы принудительно подключаться к почтовому серверу по ipv4.
Идём в www/libraries/phpmailer/phpmailer.php
Ищем там функцию SmtpConnect, и внутри неё ищем код:
if (preg_match('/^(.+):([0-9]+)$/', $hosts[$index], $hostinfo)) {
$host = $hostinfo[1];
$port = $hostinfo[2];
} else {
$host = $hosts[$index];
$port = $this->Port;
}
И вставляем строчку:
$host = gethostbyname($host);
Должно получиться
if (preg_match('/^(.+):([0-9]+)$/', $hosts[$index], $hostinfo)) {
$host = $hostinfo[1];
$port = $hostinfo[2];
} else {
$host = $hosts[$index];
$host = gethostbyname($host);
$port = $this->Port;
}
Смысл в том, чтобы принудительно получать IPv4 хоста, и обращаться уже по IP-адресу.
Решение не очень элегантное, т.к. приходится исправлять код Joomla, и при очередном обновлении это исправление вполне может слететь.
Не отправляется почта по ipv6. Решение для Joomla 3.7
Всё аналогично Joomla 2.5, только нужный нам файл находится по адресу: www/libraries/vendor/phpmailer/phpmailer/class.phpmailer.php
Ищем там функцию smtpConnect, внутри неё ищем первое упоминание $host:
$host = $hostinfo[3];
$port = $this->Port;
$tport = (integer)$hostinfo[4];
И вставляем строчку:
$host = gethostbyname($host);
Должно получиться
$host = $hostinfo[3];
$host = gethostbyname($host);
$port = $this->Port;
$tport = (integer)$hostinfo[4];
Да... решение временное и будет слетать при каждом обновлении Joomla... но другого пока нет.