When using a self-hosted mail server like Mailcow, you'll often encounter SMTP certificate issues. In most other applications, this is fairly easy to resolve by simply enabling the “Ignore SSL verification” switch.
However, Flarum lacks this functionality, and setting Encryption to empty does not resolve the issue. Additionally, you cannot modify this behavior via extend.php, as the SMTP Driver constructs its own transport and is not managed by global settings.
Even when using plaintext port 25 with no encryption settings specified, Flarum's SMTP driver will still construct a transport that utilizes STARTTLS/TLS when available, triggering certificate validation issues.
Currently, the only solution is to modify the SMTPDriver.php file and manually pass in the stream parameter. This is extremely cumbersome, and any changes made to this file will be lost after an upgrade.
<?php
/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/
namespace Flarum\Mail;
use Flarum\Settings\SettingsRepositoryInterface;
use Illuminate\Contracts\Validation\Factory;
use Illuminate\Support\MessageBag;
use Swift_SmtpTransport;
use Swift_Transport;
class SmtpDriver implements DriverInterface
{
use ValidatesMailSettings;
public function availableSettings(): array
{
return [
'mail_host' => '', // a hostname, IPv4 address or IPv6 wrapped in []
'mail_port' => '', // a number, defaults to 25
'mail_encryption' => '', // "tls" or "ssl"
'mail_username' => '',
'mail_password' => '',
];
}
public function validate(SettingsRepositoryInterface $settings, Factory $validator): MessageBag
{
return $validator->make($settings->all(), [
'mail_host' => ['required', $this->noWhitespace()],
'mail_port' => ['nullable', 'integer', $this->noWhitespace()],
'mail_encryption' => 'nullable|in:tls,ssl,TLS,SSL',
'mail_username' => ['nullable', 'string', $this->noWhitespace()],
'mail_password' => ['nullable', 'string', $this->noWhitespace()],
])->errors();
}
public function canSend(): bool
{
return true;
}
public function buildTransport(SettingsRepositoryInterface $settings): Swift_Transport
{
$transport = new Swift_SmtpTransport(
$settings->get('mail_host'),
$settings->get('mail_port'),
$settings->get('mail_encryption') // <-- This actually DIDN'T WORK if you want disable encryption, it ALWAYS use STARTTLS or something like that when available (even encryption is null)!
);
$transport->setUsername($settings->get('mail_username'));
$transport->setPassword($settings->get('mail_password'));
$transport->setStreamOptions([ // Hack start
'ssl' => [
'allow_self_signed' => true,
'verify_peer' => false,
'verify_peer_name' => false,
],
]); // Hack end
return $transport;
}
}
This proposal suggests that Flarum requires a mechanism to address such scenarios, which could be implemented either through a new toggle in the admin panel or by disabling SSL verification in config.php.