Files
florian.wilde 7238e7a937 feat(domains): Pruefung von DNS, Zuordnung und Zertifikat
Eine reine DNS-Pruefung sagt nichts darueber aus, ob der Webserver die
Domain auch dem richtigen Verzeichnis zuordnet - genau das ist der
haeufigste Fehler. Die Pruefung ruft die Domain deshalb von aussen auf
einen signierten Endpunkt auf. Kommt der Aufruf mit gueltigem Token an,
ist die ganze Kette bewiesen, denn nur diese Installation kann ein
solches Token erzeugen.

Erkannt und benannt werden: fehlender DNS-Eintrag, Domain-Weiterleitung
des Registrars, falsches Verzeichnis, ungueltiges Zertifikat.

Link-lokale Adressen werden nicht abgerufen - dort liegen bei Cloud-
Anbietern die Metadaten-Dienste.
2026-08-03 18:11:40 +02:00

51 lines
1.4 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Support;
/**
* Kurzlebiges, signiertes Token fuer die Domain-Pruefung.
*
* Die Pruefung ruft die zu testende Domain von aussen auf. Der dafuer
* noetige Endpunkt muss ohne Login erreichbar sein - deshalb ist er nur
* mit einem gueltigen Token ansprechbar und antwortet sonst mit 404.
*
* Das Token ist zustandslos (HMAC ueber den Zeitstempel), es muss also
* nichts zwischengespeichert werden. Kommt der Aufruf mit einem
* gueltigen Token an, ist damit zugleich bewiesen, dass er bei DIESER
* Installation gelandet ist - nur sie kennt das Geheimnis.
*/
final class CheckToken
{
/** Gueltigkeitsdauer in Sekunden. */
public const LIFETIME = 180;
public static function create(string $secret, ?int $now = null): string
{
$timestamp = (string) ($now ?? time());
return $timestamp . '.' . hash_hmac('sha256', $timestamp, $secret);
}
public static function isValid(string $token, string $secret, ?int $now = null): bool
{
$parts = explode('.', $token, 2);
if (count($parts) !== 2) {
return false;
}
[$timestamp, $signature] = $parts;
if ($timestamp === '' || !ctype_digit($timestamp)) {
return false;
}
if (abs(($now ?? time()) - (int) $timestamp) > self::LIFETIME) {
return false;
}
return hash_equals(hash_hmac('sha256', $timestamp, $secret), $signature);
}
}