fix: corriger les checks Mailcow DNS et ignorer DKIM Mailcow

src/Service/MailcowService.php - getExpectedDnsRecords() reecrit:
- Suppression des checks SPF et DMARC (deja verifies par DnsCheckService)
- Suppression du check DKIM TXT (le DKIM est gere par AWS SES, pas Mailcow)
- Ajout du champ 'optional' (bool) dans chaque enregistrement attendu
  au lieu de deviner l'optionnalite par le nom
- Enregistrements verifies:
  - MX {domain} → mail.esy-web.dev (obligatoire)
  - CNAME autodiscover.{domain} → mail.esy-web.dev (obligatoire)
  - CNAME autoconfig.{domain} → mail.esy-web.dev (obligatoire)
  - SRV _autodiscover._tcp.{domain} (optionnel)
  - TXT _mta-sts.{domain} v=STSv1 (optionnel)
  - CNAME mta-sts.{domain} → mail.esy-web.dev (optionnel)

src/Command/CheckDnsCommand.php - checkMailcow():
- DKIM Mailcow marque comme OK avec detail "Ignore (DKIM via AWS SES)"
  car l'envoi des mails utilise le DKIM d'AWS SES, pas celui de Mailcow
- Suppression de la methode getDkimFromDns() devenue inutile
- Utilisation du champ 'optional' de getExpectedDnsRecords() au lieu
  de deviner par le nom de l'enregistrement

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Serreau Jovann
2026-04-02 21:47:38 +02:00
parent 3313d28ef3
commit 5d47db73d4
2 changed files with 19 additions and 46 deletions

View File

@@ -367,32 +367,15 @@ class CheckDnsCommand extends Command
$errors[] = "[$domain] Mailcow : desactive";
}
$dkimKey = $this->mailcow->getDkimKey($domain);
if (null !== $dkimKey && '' !== $dkimKey) {
$dnsDkim = $this->getDkimFromDns($domain);
$match = null !== $dnsDkim && str_contains($dnsDkim, substr($dkimKey, 0, 40));
$checks[] = DnsCheckService::check(
'Mailcow', 'DKIM', $match ? 'ok' : 'error',
$match ? 'Cles correspondent' : 'Cles differentes',
'Cle Mailcow: '.substr($dkimKey, 0, 30).'...',
null !== $dnsDkim ? substr($dnsDkim, 0, 30).'...' : 'Absent du DNS'
);
if ($match) {
$successes[] = "[$domain] Mailcow DKIM : correspond au DNS";
} else {
$errors[] = "[$domain] Mailcow DKIM : ne correspond pas au DNS";
}
} else {
$errors[] = "[$domain] Mailcow DKIM : pas de cle";
$checks[] = DnsCheckService::check('Mailcow', 'DKIM', 'error', 'Aucune cle', 'Cle DKIM configuree', 'Absente');
}
// DKIM Mailcow ignore - l'envoi utilise AWS SES DKIM
$checks[] = DnsCheckService::check('Mailcow', 'DKIM', 'ok', 'Ignore (DKIM via AWS SES)', 'AWS SES DKIM', 'N/A');
$successes[] = "[$domain] Mailcow DKIM : ignore (utilise AWS SES)";
// Verifier les enregistrements DNS attendus par Mailcow
$expectedRecords = $this->mailcow->getExpectedDnsRecords($domain);
foreach ($expectedRecords as $expected) {
$found = $this->checkDnsRecordExists($expected['type'], $expected['name'], $expected['content']);
$isOptional = str_contains($expected['name'], 'autodiscover') || str_contains($expected['name'], 'autoconfig') || 'SRV' === $expected['type'] || str_contains($expected['name'], '_mta-sts');
$isOptional = $expected['optional'];
$label = $expected['type'].' '.$expected['name'];
$checks[] = DnsCheckService::check(
@@ -415,21 +398,6 @@ class CheckDnsCommand extends Command
}
}
private function getDkimFromDns(string $domain): ?string
{
foreach (['dkim', 'default', 'mail', 'k1'] as $selector) {
$records = dns_get_record($selector.'._domainkey.'.$domain, \DNS_TXT) ?: [];
foreach ($records as $r) {
$txt = $r['txt'] ?? '';
if (str_contains($txt, 'v=DKIM1') || str_contains($txt, 'k=rsa')) {
return $txt;
}
}
}
return null;
}
private function checkDnsRecordExists(string $type, string $name, string $expectedContent): bool
{
return match ($type) {

View File

@@ -43,22 +43,27 @@ class MailcowService
/**
* Recuperer la configuration DNS attendue par Mailcow pour un domaine.
* Basee sur la documentation Mailcow: https://docs.mailcow.email/prerequisite/dns/
*
* @return list<array{type: string, name: string, content: string, priority?: int}>
* @return list<array{type: string, name: string, content: string, optional: bool}>
*/
public function getExpectedDnsRecords(string $domain): array
{
$hostname = parse_url($this->baseUrl, \PHP_URL_HOST) ?: 'mail.esy-web.dev';
return [
['type' => 'MX', 'name' => $domain, 'content' => $hostname, 'priority' => 10],
['type' => 'TXT', 'name' => $domain, 'content' => 'v=spf1 include:'.$hostname.' -all'],
['type' => 'TXT', 'name' => '_dmarc.'.$domain, 'content' => 'v=DMARC1'],
['type' => 'TXT', 'name' => 'dkim._domainkey.'.$domain, 'content' => 'v=DKIM1'],
['type' => 'CNAME', 'name' => 'autodiscover.'.$domain, 'content' => $hostname],
['type' => 'CNAME', 'name' => 'autoconfig.'.$domain, 'content' => $hostname],
['type' => 'SRV', 'name' => '_autodiscover._tcp.'.$domain, 'content' => $hostname],
['type' => 'TXT', 'name' => '_mta-sts.'.$domain, 'content' => 'v=STSv1'],
// MX obligatoire - reception des mails
['type' => 'MX', 'name' => $domain, 'content' => $hostname, 'optional' => false],
// CNAME autodiscover - configuration auto Outlook
['type' => 'CNAME', 'name' => 'autodiscover.'.$domain, 'content' => $hostname, 'optional' => false],
// CNAME autoconfig - configuration auto Thunderbird
['type' => 'CNAME', 'name' => 'autoconfig.'.$domain, 'content' => $hostname, 'optional' => false],
// SRV autodiscover - decouverte auto des services
['type' => 'SRV', 'name' => '_autodiscover._tcp.'.$domain, 'content' => $hostname, 'optional' => true],
// TXT _mta-sts - politique de securite du transport mail
['type' => 'TXT', 'name' => '_mta-sts.'.$domain, 'content' => 'v=STSv1', 'optional' => true],
// CNAME mta-sts - page de politique MTA-STS
['type' => 'CNAME', 'name' => 'mta-sts.'.$domain, 'content' => $hostname, 'optional' => true],
];
}