Files
wevads-platform/scripts/api_dns-push.php
2026-02-26 04:53:11 +01:00

428 lines
14 KiB
PHP
Executable File

<?php
/**
* DNS Push API - Unified DNS Management
* Supports: Cloudflare, FreeDNS, Namecheap
*
* Usage: POST /api/dns-push.php
* Params: domain_id, provider, action (push, verify, delete)
*/
header('Content-Type: application/json');
function getDB() {
static $pdo = null;
if ($pdo === null) {
$pdo = new PDO("pgsql:host=localhost;dbname=adx_system", "admin", "admin123",
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
}
return $pdo;
}
// =====================================================
// CLOUDFLARE API
// =====================================================
class CloudflareAPI {
private $email;
private $apiKey;
private $apiToken;
private $baseUrl = 'https://api.cloudflare.com/client/v4';
public function __construct($accountId) {
$pdo = getDB();
$stmt = $pdo->prepare("SELECT * FROM admin.cloudflare_accounts WHERE id = ?");
$stmt->execute([$accountId]);
$account = $stmt->fetch(PDO::FETCH_ASSOC);
$this->email = $account['email'] ?? '';
$this->apiKey = $account['api_key'] ?? '';
$this->apiToken = $account['api_token'] ?? '';
}
private function request($endpoint, $method = 'GET', $data = null) {
$ch = curl_init($this->baseUrl . $endpoint);
$headers = ['Content-Type: application/json'];
if ($this->apiToken) {
$headers[] = 'Authorization: Bearer ' . $this->apiToken;
} else {
$headers[] = 'X-Auth-Email: ' . $this->email;
$headers[] = 'X-Auth-Key: ' . $this->apiKey;
}
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_TIMEOUT => 30
]);
if ($data && in_array($method, ['POST', 'PUT', 'PATCH'])) {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
}
$response = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
if ($error) {
return ['success' => false, 'errors' => [['message' => $error]]];
}
return json_decode($response, true);
}
public function getZoneId($domain) {
// Extraire le domaine racine
$parts = explode('.', $domain);
$rootDomain = implode('.', array_slice($parts, -2));
$result = $this->request('/zones?name=' . $rootDomain);
if ($result['success'] && !empty($result['result'])) {
return $result['result'][0]['id'];
}
return null;
}
public function createRecord($zoneId, $type, $name, $content, $ttl = 1, $proxied = false) {
return $this->request("/zones/$zoneId/dns_records", 'POST', [
'type' => $type,
'name' => $name,
'content' => $content,
'ttl' => $ttl,
'proxied' => $proxied
]);
}
public function listRecords($zoneId, $type = null, $name = null) {
$params = [];
if ($type) $params[] = "type=$type";
if ($name) $params[] = "name=$name";
$query = $params ? '?' . implode('&', $params) : '';
return $this->request("/zones/$zoneId/dns_records$query");
}
public function deleteRecord($zoneId, $recordId) {
return $this->request("/zones/$zoneId/dns_records/$recordId", 'DELETE');
}
public function pushDNSRecords($domain, $records) {
$results = [];
$zoneId = $this->getZoneId($domain);
if (!$zoneId) {
return ['success' => false, 'error' => 'Zone not found for domain: ' . $domain];
}
foreach ($records as $record) {
$name = $record['name'] === '@' ? $domain : $record['name'] . '.' . $domain;
// Vérifier si le record existe déjà
$existing = $this->listRecords($zoneId, $record['type'], $name);
if (!empty($existing['result'])) {
// Supprimer l'ancien
foreach ($existing['result'] as $old) {
$this->deleteRecord($zoneId, $old['id']);
}
}
// Créer le nouveau
$result = $this->createRecord(
$zoneId,
$record['type'],
$name,
$record['content'],
$record['ttl'] ?? 1,
$record['proxied'] ?? false
);
$results[] = [
'record' => $record['type'] . ' ' . $record['name'],
'success' => $result['success'] ?? false,
'id' => $result['result']['id'] ?? null,
'error' => $result['errors'][0]['message'] ?? null
];
}
return ['success' => true, 'results' => $results];
}
}
// =====================================================
// FREEDNS API (via scraping)
// =====================================================
class FreeDNSAPI {
private $cookie;
private $accountId;
private $baseUrl = 'https://freedns.afraid.org';
public function __construct($accountId) {
$this->accountId = $accountId;
$pdo = getDB();
$stmt = $pdo->prepare("SELECT * FROM admin.freedns_accounts WHERE id = ?");
$stmt->execute([$accountId]);
$account = $stmt->fetch(PDO::FETCH_ASSOC);
$this->cookie = $account['cookie'] ?? '';
}
public function login($username, $password) {
$ch = curl_init($this->baseUrl . '/zc.php?action=auth');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query([
'username' => $username,
'password' => $password,
'submit' => 'Login'
]),
CURLOPT_HEADER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_USERAGENT => 'Mozilla/5.0'
]);
$response = curl_exec($ch);
curl_close($ch);
preg_match_all('/Set-Cookie:\s*([^;]+)/', $response, $matches);
$this->cookie = implode('; ', $matches[1] ?? []);
if (strpos($this->cookie, 'dns_cookie') !== false) {
// Sauvegarder le cookie
$pdo = getDB();
$stmt = $pdo->prepare("UPDATE admin.freedns_accounts SET cookie = ?, last_login = NOW() WHERE id = ?");
$stmt->execute([$this->cookie, $this->accountId]);
return ['success' => true];
}
return ['success' => false, 'error' => 'Login failed'];
}
public function addRecord($subdomain, $baseDomain, $type, $value) {
// Cette fonction nécessite le scraping de FreeDNS
// Implémentation simplifiée
return ['success' => false, 'error' => 'FreeDNS requires manual configuration'];
}
}
// =====================================================
// NAMECHEAP API
// =====================================================
class NamecheapAPI {
private $apiUser;
private $apiKey;
private $username;
private $clientIP;
private $baseUrl = 'https://api.namecheap.com/xml.response';
public function __construct($accountId) {
$pdo = getDB();
$stmt = $pdo->prepare("SELECT * FROM admin.namecheap_accounts WHERE id = ?");
$stmt->execute([$accountId]);
$account = $stmt->fetch(PDO::FETCH_ASSOC);
$this->apiUser = $account['api_user'] ?? $account['username'];
$this->apiKey = $account['api_key'] ?? '';
$this->username = $account['username'] ?? '';
$this->clientIP = $account['client_ip'] ?? $_SERVER['SERVER_ADDR'];
}
private function request($command, $params = []) {
$defaultParams = [
'ApiUser' => $this->apiUser,
'ApiKey' => $this->apiKey,
'UserName' => $this->username,
'ClientIp' => $this->clientIP,
'Command' => $command
];
$allParams = array_merge($defaultParams, $params);
$url = $this->baseUrl . '?' . http_build_query($allParams);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30
]);
$response = curl_exec($ch);
curl_close($ch);
return simplexml_load_string($response);
}
public function getDomains() {
return $this->request('namecheap.domains.getList');
}
public function getHosts($sld, $tld) {
return $this->request('namecheap.domains.dns.getHosts', [
'SLD' => $sld,
'TLD' => $tld
]);
}
public function setHosts($sld, $tld, $records) {
$params = [
'SLD' => $sld,
'TLD' => $tld
];
$i = 1;
foreach ($records as $record) {
$params["HostName$i"] = $record['name'];
$params["RecordType$i"] = $record['type'];
$params["Address$i"] = $record['content'];
$params["TTL$i"] = $record['ttl'] ?? 1800;
$i++;
}
return $this->request('namecheap.domains.dns.setHosts', $params);
}
public function pushDNSRecords($domain, $records) {
$parts = explode('.', $domain);
$tld = array_pop($parts);
$sld = array_pop($parts);
// Récupérer les records existants
$existing = $this->getHosts($sld, $tld);
// Fusionner avec les nouveaux
$allRecords = [];
// Garder les existants qui ne sont pas remplacés
if (isset($existing->CommandResponse->DomainDNSGetHostsResult->host)) {
foreach ($existing->CommandResponse->DomainDNSGetHostsResult->host as $host) {
$allRecords[] = [
'name' => (string)$host['Name'],
'type' => (string)$host['Type'],
'content' => (string)$host['Address'],
'ttl' => (int)$host['TTL']
];
}
}
// Ajouter/remplacer les nouveaux
foreach ($records as $newRecord) {
$found = false;
foreach ($allRecords as &$existing) {
if ($existing['name'] === $newRecord['name'] && $existing['type'] === $newRecord['type']) {
$existing['content'] = $newRecord['content'];
$found = true;
break;
}
}
if (!$found) {
$allRecords[] = $newRecord;
}
}
$result = $this->setHosts($sld, $tld, $allRecords);
return [
'success' => (string)$result['Status'] === 'OK',
'results' => $allRecords
];
}
}
// =====================================================
// MAIN API HANDLER
// =====================================================
function getDNSRecordsFromDB($domainId) {
$pdo = getDB();
// Récupérer le domaine
$stmt = $pdo->prepare("SELECT domain FROM admin.domains_pool WHERE id = ?");
$stmt->execute([$domainId]);
$domain = $stmt->fetchColumn();
if (!$domain) {
return ['error' => 'Domain not found'];
}
// Récupérer les IPs MTA actives
$stmt = $pdo->query("SELECT main_ip FROM admin.mta_servers WHERE status = 'Activated' AND main_ip IS NOT NULL LIMIT 5");
$ips = $stmt->fetchAll(PDO::FETCH_COLUMN);
if (empty($ips)) {
$ips = ['176.52.128.44', '119.8.153.154', '101.44.3.125'];
}
// Générer les records via la fonction SQL
$ipArray = "ARRAY['" . implode("','", $ips) . "']";
$stmt = $pdo->query("SELECT * FROM admin.generate_dns_records('$domain', $ipArray)");
$records = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Convertir au format API
$formatted = [];
foreach ($records as $r) {
$formatted[] = [
'type' => $r['record_type'],
'name' => $r['record_name'],
'content' => $r['record_value'],
'ttl' => 1
];
}
return ['domain' => $domain, 'records' => $formatted, 'mta_ips' => $ips];
}
function pushDNS($domainId, $provider, $providerAccountId) {
$dnsData = getDNSRecordsFromDB($domainId);
if (isset($dnsData['error'])) {
return $dnsData;
}
switch ($provider) {
case 'cloudflare':
$api = new CloudflareAPI($providerAccountId);
return $api->pushDNSRecords($dnsData['domain'], $dnsData['records']);
case 'namecheap':
$api = new NamecheapAPI($providerAccountId);
return $api->pushDNSRecords($dnsData['domain'], $dnsData['records']);
case 'freedns':
return ['success' => false, 'error' => 'FreeDNS requires manual configuration via web interface'];
default:
return ['success' => false, 'error' => 'Unknown provider: ' . $provider];
}
}
// Handle request
$action = $_REQUEST['action'] ?? 'status';
$domainId = $_REQUEST['domain_id'] ?? null;
$provider = $_REQUEST['provider'] ?? 'cloudflare';
$providerAccountId = $_REQUEST['provider_account_id'] ?? 1;
switch ($action) {
case 'generate':
// Juste générer les records sans pousser
echo json_encode(getDNSRecordsFromDB($domainId));
break;
case 'push':
// Générer et pousser vers le provider
echo json_encode(pushDNS($domainId, $provider, $providerAccountId));
break;
case 'status':
default:
echo json_encode([
'status' => 'ok',
'endpoints' => [
'generate' => '?action=generate&domain_id=123',
'push' => '?action=push&domain_id=123&provider=cloudflare&provider_account_id=1'
],
'providers' => ['cloudflare', 'namecheap', 'freedns']
]);
}