Ваша задача — заставить Invision Community (IPS4) корректно работать с SMTPS (TLS на порту 465, implicit TLS), а не только с SMTP+STARTTLS (обычно порт 587). Из того, что вы описали: - Вы успешно «пропатчили» механизм авторизации SMTP, заменив LOGIN на PLAIN — это решило вопрос аутентификации. - Теперь вы хотите перейти на SMTPS (implicit TLS) на порту 465. - При попытке отправки через SMTPS происходит зависание и таймаут. --- ### Почему возникает проблема? Большинство современных PHP-библиотек и реализаций SMTP-клиентов (включая стандартный stream_socket_client и частично PHPMailer, которые может использовать IPS4) по умолчанию поддерживают STARTTLS, но implicit TLS (где TLS начинается сразу при подключении) требует особой настройки соединения. Если пытаться подключаться к SMTPS на 465 порт без правильного указания SSL-контекста в stream_socket_client, то соединение либо не устанавливается, либо "зависает". --- ### Что проверить и как решить 1. Проверка способа соединения Убедитесь, что в IPS4 при использовании порта 465 действительно используется SSL/TLS-соединение с самого начала, а не plain TCP, и не пытается запускать STARTTLS. 2. Настройка параметров соединения В IPS4 (его классе SMTP отправки), скорее всего, используется stream_socket_client(). Для implicit SSL вам нужно использовать транспорт ssl:// или tls:// в URL подключения. Например: $transport = ($this->smtpPort == 465) ? 'ssl://' : 'tcp://';
$connection = stream_socket_client($transport . $this->smtpHost . ':' . $this->smtpPort, $errno, $errstr, $timeout);Часто ssl:// используется для implicit TLS (порт 465), а tcp:// — для обычного TCP (порт 587 с STARTTLS). 3. Патчинг IPS4 Возможно, в исходном коде IPS4 в классе SMTP нет поддержки ssl:// транспорта, или она автоматически не выбирается по порту. Попробуйте поискать и изменить логику открытия соединения так, чтобы для порта 465 использовать ssl://. Обычно в IPS4 путь к классу — IPS\Email\Outgoing\Smtp или похожий. 4. Пример патча для подключения: Найдите метод, который открывает сокет, может называться _openSocket() или что-то подобное. Добавьте условие: $transport = 'tcp://';
if ( $this->smtpPort == 465 )
{
$transport = 'ssl://';
}
$this->_socket = stream_socket_client(
$transport . $this->smtpHost . ':' . $this->smtpPort,
$errno,
$errstr,
$timeout
);5. Выключите STARTTLS При использовании SMTPS на 465 не нужно запускать команду STARTTLS — TLS уже активен. Проверьте, что IPS4 не пытается выполнить STARTTLS после подключения, иначе возникнет конфликт. 6. Проверка настроек почтового сервера Убедитесь, что ваш SMTP сервер корректно слушает 465 порт с implicit TLS. 7. Логирование и отладка Включите расширенное логирование SMTP соединения в IPS4, чтобы увидеть, на каком этапе происходит зависание. 8. Альтернативы Если IPS4 не поддерживает implicit TLS из коробки, можно: - Использовать порт 587 с STARTTLS (если это возможно). - Проксировать SMTP через stunnel на сервере, переводя plain 587 в 465 SSL. - Использовать внешний SMTP-клиент/шлюз. --- ### Краткое резюме - SMTPS (порт 465) требует подключения с ssl:// transport в PHP. - Нужно исправить код создания сокета, чтобы для порта 465 использовать ssl://. - Убедиться, что не запускается STARTTLS, когда используешь implicit TLS. - Проверьте, что аутентификацию и отправку сообщений IPS4 выполняет после установления TLS. - Логируйте SMTP-сессию для диагностики. --- Если хотите, могу помочь более конкретно с кодом, если вы предоставите исходный код класса, где открывается SMTP-соединение у вас в IPS4. Ваш GPT-5 Спасибо за предоставленный код класса SMTP. Теперь гораздо яснее, как идёт подключение и какая логика используется. --- ### Ваша задача — заставить Invision Community корректно работать с implicit TLS (SMTPS на порту 465). --- ## Анализ текущей реализации подключения В методе connect() есть эта строка: $connection = @fsockopen( ( ( $this->smtpProtocol == 'ssl' ) ? 'ssl://' : '' ) . $this->smtpHost, $this->smtpPort, $errno, $errstr );То есть протокол ssl:// добавляется к хосту только, если $this->smtpProtocol == 'ssl'. Это позволяет открывать implicit TLS соединение, которое как раз используется на порту 465. Если $this->smtpProtocol == 'tls', то соединение открывается как plain TCP, и затем вызывается команда STARTTLS. Всё выглядит правильно, но: - Вы должны убедиться, что в конфигурации IPS4 при использовании порта 465 указано $smtpProtocol = 'ssl'. - Если у вас $smtpProtocol == 'tls' на 465 порту — соединение зависнет, так как сервер ожидает TLS с самого начала, а клиент пытается сделать plain connection. --- ## Рекомендации и исправления 1. **Проверьте значение $smtpProtocol в вашей конфигурации.** Для implicit TLS (порт 465) оно должно быть точно 'ssl', а не 'tls'! 2. **Убедитесь, что вы не запускаете STARTTLS при $smtpProtocol == 'ssl'.** В вашем методе connect() есть такой код: if( $this->smtpProtocol == 'tls' )
{
// starttls и активация шифрования
} Следовательно при 'ssl' этот блок пропускается, что правильно. 3. **Ваш патч с AUTH PLAIN** Ваш код авторизации должен выглядеть примерно так, чтобы включать поддержку PLAIN, например заменить этот участок: /* Authenticate */
if ( $this->smtpUser )
{
// вместо AUTH LOGIN, сделать:
$responseCode = $this->_sendCommand( 'AUTH PLAIN', 334 );
$responseCode = $this->_sendCommand( base64_encode("\0" . $this->smtpUser . "\0" . $this->smtpPass), 235 );
}4. **Добавьте логирование** Метод getLog() есть, так что вызовите его после неудачных попыток, чтобы получить подробный лог SMTP сессии. Это поможет отловить, на каком этапе подвисает. 5. **Пример конфигурации для port 465** В конфиге форума/почты должно быть так: - SMTP host: ваш сервер - SMTP port: 465 - SMTP protocol: ssl - SMTP user/pass: ваши данные --- ## Можно протестировать -- пример быстрого скрипта для проверки соединения (outside IPS4) <?php
$host = 'ssl://smtp.yourserver.com';
$port = 465;
$user = 'username';
$pass = 'password';
$fp = fsockopen($host, $port, $errno, $errstr, 10);
if (!$fp) {
die("Ошибка подключения: $errstr ($errno)\n");
}
echo fgets($fp, 515); // ждем готовности сервера
fputs($fp, "EHLO yourdomain.com\r\n");
echo fgets($fp, 515);
fputs($fp, "AUTH PLAIN " . base64_encode("\0$user\0$pass") . "\r\n");
echo fgets($fp, 515);
// Далее команда MAIL, RCPT и DATA ... Если тестовый скрипт работает, а IPS4 нет — проблема в настройках (smtpProtocol) или нюансах работы класса. --- ## Резюме - В IPS4 для implicit TLS на 465 порт должно быть $smtpProtocol = 'ssl' - В этом случае fsockopen() использует ssl:// префикс, TLS устанавливается сразу - STARTTLS в этом случае не вызывается - Используйте AUTH PLAIN вместо AUTH LOGIN для аутентификации - Проверьте лог сессии для диагностики проблем - Убедитесь, что порт 465 на сервере корректно работает с implicit TLS --- Если будете испытывать проблемы — пришлите лог из $smtp->getLog() после неудачной попытки. Помогу проанализировать дальше.