Update backsync.php

This commit is contained in:
SubleXBle
2025-08-23 19:59:46 +02:00
committed by GitHub
parent 5bb996a2ed
commit afa15d6afb

View File

@@ -1,20 +1,20 @@
<?php
// backsync.php Empfängt aktualisierte Blocklists vom Client und synchronisiert diese auf den Server
// backsync.php Receives updated blocklists from the client and synchronizes them on the server
// === Konfiguration ===
$CLIENTS_FILE = "/opt/Fail2Ban-Report/Settings/client-list.json";
$ARCHIVE_BASE = __DIR__ . "/../archive/";
// === Configuration ===
$CLIENTS_FILE = "/opt/Fail2Ban-Report/Settings/client-list.json";
$ARCHIVE_BASE = __DIR__ . "/../archive/";
$TEMP_UPLOAD_DIR = sys_get_temp_dir() . "/backsync/";
// === Hilfsfunktion für JSON-Antworten ===
// === Helper function for JSON responses ===
function respond($statusCode, $data) {
http_response_code($statusCode);
header('Content-Type: application/json');
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
echo json_encode($data, JSON_PRETTY_PRINT);
exit;
}
// === 1) Clients laden ===
// === 1) Load clients ===
if (!file_exists($CLIENTS_FILE)) {
respond(500, ["success" => false, "message" => "Client list not found."]);
}
@@ -24,7 +24,7 @@ if (!is_array($clients)) {
respond(500, ["success" => false, "message" => "Client list corrupted."]);
}
// === 2) Authentifizierung ===
// === 2) Authenticate client ===
$username = $_POST['username'] ?? '';
$password = $_POST['password'] ?? '';
$uuid = $_POST['uuid'] ?? '';
@@ -42,14 +42,14 @@ if (!password_verify($password, $client['password'])) {
respond(403, ["success" => false, "message" => "Authentication failed (password)."]);
}
if (isset($client['ip']) && $client['ip'] !== $remoteIp) {
respond(403, ["success" => false, "message" => "Authentication failed (ip mismatch)."]);
respond(403, ["success" => false, "message" => "Authentication failed (IP mismatch)."]);
}
// === 3) Temp-Pfad vorbereiten ===
// === 3) Prepare temp upload directory ===
$userTempDir = $TEMP_UPLOAD_DIR . $username . "/";
if (!is_dir($userTempDir)) mkdir($userTempDir, 0770, true);
// === 4) Dateien entgegennehmen und temporär speichern ===
// === 4) Receive files and store them temporarily ===
if (!isset($_FILES['file'])) {
respond(400, ["success" => false, "message" => "No files uploaded."]);
}
@@ -61,62 +61,70 @@ foreach ($_FILES['file']['name'] as $index => $name) {
if (!preg_match('/^[a-z0-9_-]+\.blocklist\.json$/i', $name)) continue;
$destPath = $userTempDir . basename($name);
if (!move_uploaded_file($tmpName, $destPath)) {
continue;
}
if (!move_uploaded_file($tmpName, $destPath)) continue;
$uploadedFiles[] = $name;
}
// Sofortige Rückmeldung an Client
respond(200, [
"success" => true,
"message" => "Files uploaded, processing in background",
"files" => $uploadedFiles
]);
// If no valid files, respond early
if (empty($uploadedFiles)) {
respond(400, ["success" => false, "message" => "No valid blocklist files uploaded."]);
}
// === 5) Process files immediately, one by one ===
$processedFiles = [];
// === 5) Hintergrundverarbeitung ===
foreach ($uploadedFiles as $file) {
$tempFile = $userTempDir . $file;
$tempFile = $userTempDir . $file;
$targetDir = $ARCHIVE_BASE . $username . "/blocklists/";
if (!is_dir($targetDir)) mkdir($targetDir, 0770, true);
$targetFile = $targetDir . $file;
// Lock auf Ziel-Datei
// Acquire lock on the target blocklist file
$blockLockFile = "/tmp/{$username}_{$file}.lock";
$blockHandle = fopen($blockLockFile, 'c');
if ($blockHandle && flock($blockHandle, LOCK_EX)) {
if (!$blockHandle || !flock($blockHandle, LOCK_EX)) {
continue; // skip this file if lock cannot be acquired
}
// Alte Datei durch neue ersetzen
copy($tempFile, $targetFile);
// Replace old file with the new one
copy($tempFile, $targetFile);
// Lock auf update.json setzen
$updateFile = $ARCHIVE_BASE . "update.json";
$updateLockFile = "/tmp/update.json.lock";
$updateHandle = fopen($updateLockFile, 'c');
if ($updateHandle && flock($updateHandle, LOCK_EX)) {
$updateData = [];
if (file_exists($updateFile)) {
$updateData = json_decode(file_get_contents($updateFile), true);
if (!is_array($updateData)) $updateData = [];
}
// Eintrag für diese Blocklist entfernen
if (isset($updateData[$username][$file])) {
unset($updateData[$username][$file]);
file_put_contents($updateFile, json_encode($updateData, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
}
flock($updateHandle, LOCK_UN);
fclose($updateHandle);
// Acquire lock on update.json
$updateFile = $ARCHIVE_BASE . "update.json";
$updateLockFile = "/tmp/update.json.lock";
$updateHandle = fopen($updateLockFile, 'c');
if ($updateHandle && flock($updateHandle, LOCK_EX)) {
$updateData = [];
if (file_exists($updateFile)) {
$updateData = json_decode(file_get_contents($updateFile), true);
if (!is_array($updateData)) $updateData = [];
}
flock($blockHandle, LOCK_UN);
fclose($blockHandle);
// Remove the entry for this blocklist
if (isset($updateData[$username][$file])) {
unset($updateData[$username][$file]);
file_put_contents($updateFile, json_encode($updateData, JSON_PRETTY_PRINT));
}
// Temp-Datei löschen
unlink($tempFile);
flock($updateHandle, LOCK_UN);
fclose($updateHandle);
}
flock($blockHandle, LOCK_UN);
fclose($blockHandle);
// Delete temp file
unlink($tempFile);
$processedFiles[] = $file;
}
// Optional: Temp-Verzeichnis säubern, falls leer
// Optional: clean up temp directory if empty
if (is_dir($userTempDir)) rmdir($userTempDir);
// === 6) Respond to client after all processing ===
respond(200, [
"success" => true,
"message" => "All files processed successfully.",
"files" => $processedFiles
]);