ssl-monitor/check_ssl.php
2026-01-11 17:25:10 +01:00

67 lines
1.6 KiB
PHP

<?php
set_time_limit(0);
$db = new PDO("sqlite:/var/www/data/ssl.db");
$db->exec("
CREATE TABLE IF NOT EXISTS certs (
domain TEXT PRIMARY KEY,
expires INTEGER,
checked_at INTEGER,
error TEXT
)");
$domains = file("/var/www/domains.txt", FILE_IGNORE_NEW_LINES);
function check_ssl($domain) {
$ctx = stream_context_create([
"socket" => ["bindto" => "0.0.0.0:0"],
"ssl" => [
"capture_peer_cert" => true,
"verify_peer" => false,
"verify_peer_name" => false,
"SNI_enabled" => true,
"peer_name" => $domain
]
]);
$client = @stream_socket_client(
"ssl://$domain:443",
$errno,
$errstr,
5,
STREAM_CLIENT_CONNECT,
$ctx
);
if (!$client) return [null, $errstr];
$params = stream_context_get_params($client);
if (!isset($params["options"]["ssl"]["peer_certificate"])) {
return [null, "No certificate"];
}
$cert = openssl_x509_parse($params["options"]["ssl"]["peer_certificate"]);
return [$cert["validTo_time_t"] ?? null, null];
}
foreach ($domains as $domain) {
[$expiry, $error] = check_ssl($domain);
$stmt = $db->prepare("
INSERT INTO certs(domain, expires, checked_at, error)
VALUES(:d,:e,:c,:er)
ON CONFLICT(domain) DO UPDATE SET
expires=:e, checked_at=:c, error=:er
");
$stmt->execute([
":d" => $domain,
":e" => $expiry,
":c" => time(),
":er" => $error
]);
usleep(200000); // anti-rate-limit (0.2s)
}
echo "SSL check completed\n";