mirror of
https://git.hexahost.dev/smueller/HexaHost-Frontend.git
synced 2026-06-02 08:08:43 +00:00
Update file inclusion paths in multiple PHP files: Adjusted paths to use the new backend directory structure, ensuring consistent access to functions and configuration files across the application.
This commit is contained in:
365
backend/api/whois-lookup.php
Normal file
365
backend/api/whois-lookup.php
Normal file
@@ -0,0 +1,365 @@
|
||||
<?php
|
||||
/**
|
||||
* HexaDNS - WHOIS Lookup API
|
||||
*
|
||||
* Ruft WHOIS-Informationen für eine Domain ab
|
||||
*
|
||||
* Verwendung: GET /api/whois-lookup.php?domain=example.com
|
||||
*/
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
header('Access-Control-Allow-Methods: GET, OPTIONS');
|
||||
header('Access-Control-Allow-Headers: Content-Type');
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
|
||||
http_response_code(200);
|
||||
exit;
|
||||
}
|
||||
|
||||
$domain = isset($_GET['domain']) ? trim($_GET['domain']) : '';
|
||||
|
||||
if (empty($domain)) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['error' => 'Domain-Parameter fehlt']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Nur Root-Domain extrahieren
|
||||
$domain = extractRootDomain($domain);
|
||||
|
||||
if (!preg_match('/^[a-zA-Z0-9][a-zA-Z0-9\-]*\.[a-zA-Z]{2,}$/', $domain)) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['error' => 'Ungültiges Domain-Format']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$startTime = microtime(true);
|
||||
$whoisData = performWhoisLookup($domain);
|
||||
$queryTime = round((microtime(true) - $startTime) * 1000, 2);
|
||||
|
||||
if ($whoisData === null) {
|
||||
http_response_code(500);
|
||||
echo json_encode(['error' => 'WHOIS-Abfrage fehlgeschlagen']);
|
||||
exit;
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'domain' => $domain,
|
||||
'query_time_ms' => $queryTime,
|
||||
'timestamp' => date('Y-m-d H:i:s'),
|
||||
'whois' => $whoisData
|
||||
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
||||
|
||||
/**
|
||||
* Extrahiert die Root-Domain (ohne Subdomain)
|
||||
*/
|
||||
function extractRootDomain(string $domain): string {
|
||||
$domain = strtolower($domain);
|
||||
$domain = preg_replace('/^(https?:\/\/)?(www\.)?/', '', $domain);
|
||||
$domain = explode('/', $domain)[0];
|
||||
|
||||
$parts = explode('.', $domain);
|
||||
if (count($parts) > 2) {
|
||||
// Einfache Logik: nimm die letzten 2 Teile
|
||||
// (funktioniert nicht perfekt für .co.uk etc., aber gut genug)
|
||||
return implode('.', array_slice($parts, -2));
|
||||
}
|
||||
|
||||
return $domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Führt WHOIS-Lookup durch
|
||||
*/
|
||||
function performWhoisLookup(string $domain): ?array {
|
||||
// Primär: Socket-basierte Abfrage (funktioniert ohne shell_exec)
|
||||
$whoisRaw = whoisViaSocket($domain);
|
||||
|
||||
// Fallback: Shell-Kommando (sicher escaped)
|
||||
if (empty($whoisRaw) && function_exists('shell_exec')) {
|
||||
$escapedDomain = escapeshellarg($domain);
|
||||
$whoisRaw = @shell_exec("whois {$escapedDomain} 2>/dev/null");
|
||||
}
|
||||
|
||||
if (empty($whoisRaw)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Parse WHOIS-Daten
|
||||
return parseWhoisData($whoisRaw, $domain);
|
||||
}
|
||||
|
||||
/**
|
||||
* WHOIS-Abfrage über Socket (unabhängig von shell_exec)
|
||||
*/
|
||||
function whoisViaSocket(string $domain): ?string {
|
||||
$whoisServer = getWhoisServer($domain);
|
||||
|
||||
if (!$whoisServer) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$result = queryWhoisServer($whoisServer, $domain);
|
||||
|
||||
// Prüfe auf Weiterleitungen zu anderen WHOIS-Servern
|
||||
if ($result && preg_match('/Registrar WHOIS Server:\s*(\S+)/i', $result, $matches)) {
|
||||
$referralServer = trim($matches[1]);
|
||||
if ($referralServer && $referralServer !== $whoisServer) {
|
||||
$referralResult = queryWhoisServer($referralServer, $domain);
|
||||
if ($referralResult) {
|
||||
$result = $referralResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Abfrage an einen spezifischen WHOIS-Server
|
||||
*/
|
||||
function queryWhoisServer(string $server, string $domain): ?string {
|
||||
$port = 43;
|
||||
$timeout = 10;
|
||||
|
||||
$socket = @fsockopen($server, $port, $errno, $errstr, $timeout);
|
||||
|
||||
if (!$socket) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Setze Stream-Timeout
|
||||
stream_set_timeout($socket, $timeout);
|
||||
|
||||
// Sende Anfrage
|
||||
fwrite($socket, $domain . "\r\n");
|
||||
|
||||
// Lese Antwort
|
||||
$response = '';
|
||||
while (!feof($socket)) {
|
||||
$response .= fread($socket, 8192);
|
||||
}
|
||||
|
||||
fclose($socket);
|
||||
|
||||
return !empty($response) ? $response : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ermittelt den zuständigen WHOIS-Server für eine TLD
|
||||
*/
|
||||
function getWhoisServer(string $domain): ?string {
|
||||
$parts = explode('.', $domain);
|
||||
$tld = strtolower(end($parts));
|
||||
|
||||
// Bekannte WHOIS-Server nach TLD
|
||||
$whoisServers = [
|
||||
// Generische TLDs
|
||||
'com' => 'whois.verisign-grs.com',
|
||||
'net' => 'whois.verisign-grs.com',
|
||||
'org' => 'whois.pir.org',
|
||||
'info' => 'whois.afilias.net',
|
||||
'biz' => 'whois.biz',
|
||||
'name' => 'whois.nic.name',
|
||||
'mobi' => 'whois.dotmobiregistry.net',
|
||||
'pro' => 'whois.registrypro.pro',
|
||||
'aero' => 'whois.aero',
|
||||
'asia' => 'whois.nic.asia',
|
||||
'cat' => 'whois.nic.cat',
|
||||
'coop' => 'whois.nic.coop',
|
||||
'edu' => 'whois.educause.edu',
|
||||
'gov' => 'whois.dotgov.gov',
|
||||
'int' => 'whois.iana.org',
|
||||
'jobs' => 'whois.nic.jobs',
|
||||
'mil' => 'whois.nic.mil',
|
||||
'museum' => 'whois.museum',
|
||||
'post' => 'whois.dotpostregistry.net',
|
||||
'tel' => 'whois.nic.tel',
|
||||
'travel' => 'whois.nic.travel',
|
||||
'xxx' => 'whois.nic.xxx',
|
||||
|
||||
// Neue gTLDs
|
||||
'app' => 'whois.nic.google',
|
||||
'dev' => 'whois.nic.google',
|
||||
'page' => 'whois.nic.google',
|
||||
'blog' => 'whois.nic.blog',
|
||||
'cloud' => 'whois.nic.cloud',
|
||||
'shop' => 'whois.nic.shop',
|
||||
'store' => 'whois.nic.store',
|
||||
'online' => 'whois.nic.online',
|
||||
'site' => 'whois.nic.site',
|
||||
'website' => 'whois.nic.website',
|
||||
'tech' => 'whois.nic.tech',
|
||||
'io' => 'whois.nic.io',
|
||||
'co' => 'whois.nic.co',
|
||||
'me' => 'whois.nic.me',
|
||||
'tv' => 'whois.nic.tv',
|
||||
'cc' => 'ccwhois.verisign-grs.com',
|
||||
'ws' => 'whois.website.ws',
|
||||
|
||||
// Europäische ccTLDs
|
||||
'de' => 'whois.denic.de',
|
||||
'at' => 'whois.nic.at',
|
||||
'ch' => 'whois.nic.ch',
|
||||
'li' => 'whois.nic.li',
|
||||
'uk' => 'whois.nic.uk',
|
||||
'fr' => 'whois.nic.fr',
|
||||
'it' => 'whois.nic.it',
|
||||
'es' => 'whois.nic.es',
|
||||
'pt' => 'whois.dns.pt',
|
||||
'nl' => 'whois.domain-registry.nl',
|
||||
'be' => 'whois.dns.be',
|
||||
'pl' => 'whois.dns.pl',
|
||||
'cz' => 'whois.nic.cz',
|
||||
'sk' => 'whois.sk-nic.sk',
|
||||
'hu' => 'whois.nic.hu',
|
||||
'ro' => 'whois.rotld.ro',
|
||||
'bg' => 'whois.register.bg',
|
||||
'hr' => 'whois.dns.hr',
|
||||
'si' => 'whois.register.si',
|
||||
'rs' => 'whois.rnids.rs',
|
||||
'gr' => 'grwhois.ics.forth.gr',
|
||||
'dk' => 'whois.punktum.dk',
|
||||
'se' => 'whois.iis.se',
|
||||
'no' => 'whois.norid.no',
|
||||
'fi' => 'whois.fi',
|
||||
'ie' => 'whois.iedr.ie',
|
||||
'eu' => 'whois.eu',
|
||||
'lu' => 'whois.dns.lu',
|
||||
|
||||
// Andere ccTLDs
|
||||
'ru' => 'whois.tcinet.ru',
|
||||
'ua' => 'whois.ua',
|
||||
'us' => 'whois.nic.us',
|
||||
'ca' => 'whois.cira.ca',
|
||||
'mx' => 'whois.mx',
|
||||
'br' => 'whois.registro.br',
|
||||
'ar' => 'whois.nic.ar',
|
||||
'au' => 'whois.auda.org.au',
|
||||
'nz' => 'whois.srs.net.nz',
|
||||
'jp' => 'whois.jprs.jp',
|
||||
'kr' => 'whois.kr',
|
||||
'cn' => 'whois.cnnic.cn',
|
||||
'in' => 'whois.registry.in',
|
||||
'sg' => 'whois.sgnic.sg',
|
||||
'hk' => 'whois.hkirc.hk',
|
||||
'tw' => 'whois.twnic.net.tw',
|
||||
'za' => 'whois.registry.net.za',
|
||||
];
|
||||
|
||||
// Spezielle Behandlung für .co.uk, .com.au etc.
|
||||
if (count($parts) >= 2) {
|
||||
$sld = $parts[count($parts) - 2];
|
||||
$combinedTld = $sld . '.' . $tld;
|
||||
|
||||
$secondLevelTlds = [
|
||||
'co.uk' => 'whois.nic.uk',
|
||||
'org.uk' => 'whois.nic.uk',
|
||||
'me.uk' => 'whois.nic.uk',
|
||||
'com.au' => 'whois.auda.org.au',
|
||||
'net.au' => 'whois.auda.org.au',
|
||||
'org.au' => 'whois.auda.org.au',
|
||||
'co.nz' => 'whois.srs.net.nz',
|
||||
'com.br' => 'whois.registro.br',
|
||||
];
|
||||
|
||||
if (isset($secondLevelTlds[$combinedTld])) {
|
||||
return $secondLevelTlds[$combinedTld];
|
||||
}
|
||||
}
|
||||
|
||||
return $whoisServers[$tld] ?? 'whois.iana.org';
|
||||
}
|
||||
|
||||
/**
|
||||
* Parsed WHOIS-Rohdaten in strukturiertes Format
|
||||
*/
|
||||
function parseWhoisData(string $raw, string $domain): array {
|
||||
$data = [
|
||||
'raw' => $raw,
|
||||
'parsed' => [
|
||||
'domain_name' => $domain,
|
||||
'registrar' => null,
|
||||
'registrar_url' => null,
|
||||
'creation_date' => null,
|
||||
'expiration_date' => null,
|
||||
'updated_date' => null,
|
||||
'status' => [],
|
||||
'nameservers' => [],
|
||||
'dnssec' => null,
|
||||
]
|
||||
];
|
||||
|
||||
$lines = explode("\n", $raw);
|
||||
|
||||
foreach ($lines as $line) {
|
||||
$line = trim($line);
|
||||
if (empty($line) || strpos($line, '%') === 0 || strpos($line, '#') === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Key: Value Format
|
||||
if (strpos($line, ':') !== false) {
|
||||
list($key, $value) = array_map('trim', explode(':', $line, 2));
|
||||
$keyLower = strtolower($key);
|
||||
|
||||
// Registrar
|
||||
if (strpos($keyLower, 'registrar') !== false && strpos($keyLower, 'abuse') === false && strpos($keyLower, 'url') === false) {
|
||||
if (empty($data['parsed']['registrar'])) {
|
||||
$data['parsed']['registrar'] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// Registrar URL
|
||||
if (strpos($keyLower, 'registrar') !== false && strpos($keyLower, 'url') !== false) {
|
||||
$data['parsed']['registrar_url'] = $value;
|
||||
}
|
||||
|
||||
// Erstellungsdatum
|
||||
if (preg_match('/(creation|created|registered)/i', $keyLower) && strpos($keyLower, 'registrar') === false) {
|
||||
if (empty($data['parsed']['creation_date'])) {
|
||||
$data['parsed']['creation_date'] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// Ablaufdatum
|
||||
if (preg_match('/(expir|paid-till)/i', $keyLower)) {
|
||||
if (empty($data['parsed']['expiration_date'])) {
|
||||
$data['parsed']['expiration_date'] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// Aktualisierungsdatum
|
||||
if (preg_match('/(updated|modified|changed)/i', $keyLower) && strpos($keyLower, 'registrar') === false) {
|
||||
if (empty($data['parsed']['updated_date'])) {
|
||||
$data['parsed']['updated_date'] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// Status
|
||||
if (preg_match('/(status|state)/i', $keyLower) && !empty($value)) {
|
||||
$data['parsed']['status'][] = $value;
|
||||
}
|
||||
|
||||
// Nameserver
|
||||
if (preg_match('/^(name.?server|nserver)/i', $keyLower) && !empty($value)) {
|
||||
$ns = strtolower(explode(' ', $value)[0]);
|
||||
if (!in_array($ns, $data['parsed']['nameservers'])) {
|
||||
$data['parsed']['nameservers'][] = $ns;
|
||||
}
|
||||
}
|
||||
|
||||
// DNSSEC
|
||||
if (strpos($keyLower, 'dnssec') !== false) {
|
||||
$data['parsed']['dnssec'] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Status einzigartig machen
|
||||
$data['parsed']['status'] = array_unique($data['parsed']['status']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
Reference in New Issue
Block a user