140 lines
5.9 KiB
PHP
140 lines
5.9 KiB
PHP
<?php
|
|
// Configuration : ports à ne JAMAIS supprimer via l'interface
|
|
$protected_ports = ['22', '2222', '80', '443'];
|
|
|
|
$message = "";
|
|
$status = "Inactive";
|
|
|
|
// --- LOGIQUE D'ACTION ---
|
|
|
|
// Ajouter un port
|
|
if (isset($_POST['add_port']) && !empty($_POST['port'])) {
|
|
$port = escapeshellarg(trim($_POST['port']));
|
|
$proto = escapeshellarg($_POST['proto']);
|
|
|
|
exec("sudo /usr/sbin/ufw allow $port/$proto", $output, $return);
|
|
$message = ($return == 0) ? "✅ Port $port/$proto ouvert." : "❌ Erreur UFW.";
|
|
}
|
|
|
|
// Supprimer une règle
|
|
if (isset($_GET['delete'])) {
|
|
$id = (int)$_GET['delete'];
|
|
|
|
// Récupérer les détails de la règle avant suppression pour la sécurité
|
|
exec("sudo /usr/sbin/ufw status numbered", $check_output);
|
|
foreach ($check_output as $line) {
|
|
if (strpos($line, "[$id]") !== false) {
|
|
foreach ($protected_ports as $p) {
|
|
if (strpos($line, $p) !== false) {
|
|
die("🛑 ERREUR : La règle #$id semble protéger un port critique ($p). Suppression annulée par sécurité.");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
exec("echo 'y' | sudo /usr/sbin/ufw delete $id", $output, $return);
|
|
header("Location: " . strtok($_SERVER["REQUEST_URI"], '?') . "?msg=deleted");
|
|
exit;
|
|
}
|
|
|
|
if (isset($_GET['msg']) && $_GET['msg'] == 'deleted') $message = "🗑️ Règle supprimée.";
|
|
|
|
// --- RÉCUPÉRATION DES DONNÉES ---
|
|
exec("sudo /usr/sbin/ufw status numbered", $ufw_output);
|
|
if (isset($ufw_output[0]) && strpos($ufw_output[0], 'active') !== false) {
|
|
$status = "Active";
|
|
}
|
|
?>
|
|
|
|
<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>UFW Manager Local</title>
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
|
|
<style>
|
|
.status-badge { font-weight: bold; padding: 5px 10px; border-radius: 4px; }
|
|
.status-Active { background: #48c78e; color: white; }
|
|
.status-Inactive { background: #f14668; color: white; }
|
|
</style>
|
|
</head>
|
|
<body class="has-background-light" style="min-height: 100vh;">
|
|
<section class="section">
|
|
<div class="container is-max-desktop">
|
|
<div class="level">
|
|
<div class="level-left">
|
|
<h1 class="title">🔥 UFW Manager</h1>
|
|
</div>
|
|
<div class="level-right">
|
|
<span class="status-badge status-<?php echo $status; ?>">Status: <?php echo $status; ?></span>
|
|
</div>
|
|
</div>
|
|
|
|
<?php if ($message): ?>
|
|
<div class="notification is-primary is-light"><?php echo $message; ?></div>
|
|
<?php endif; ?>
|
|
|
|
<div class="box">
|
|
<form method="POST" class="field is-grouped">
|
|
<div class="control is-expanded">
|
|
<input class="input" type="text" name="port" placeholder="Port ou Service (ex: 8080)">
|
|
</div>
|
|
<div class="control">
|
|
<div class="select">
|
|
<select name="proto">
|
|
<option value="tcp">TCP</option>
|
|
<option value="udp">UDP</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="control">
|
|
<button type="submit" name="add_port" class="button is-dark">Autoriser</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<div class="box p-0">
|
|
<table class="table is-fullwidth is-hoverable m-0">
|
|
<thead>
|
|
<tr class="has-background-white-ter">
|
|
<th class="pl-5">#</th>
|
|
<th>Vers</th>
|
|
<th>Action</th>
|
|
<th>Depuis</th>
|
|
<th class="has-text-right pr-5">Action</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php
|
|
$rules_found = false;
|
|
foreach ($ufw_output as $line) {
|
|
if (preg_match('/\[\s*(\d+)\]\s+(.*?)\s+(ALLOW|DENY|ALLOW IN|DENY IN)\s+(.*)/', $line, $matches)) {
|
|
$rules_found = true;
|
|
$is_critical = false;
|
|
foreach ($protected_ports as $p) { if (strpos($matches[2], $p) !== false) $is_critical = true; }
|
|
|
|
echo "<tr>
|
|
<td class='pl-5'><b>{$matches[1]}</b></td>
|
|
<td><code>{$matches[2]}</code></td>
|
|
<td><span class='tag is-light is-success'>{$matches[3]}</span></td>
|
|
<td><small>{$matches[4]}</small></td>
|
|
<td class='has-text-right pr-5'>";
|
|
if (!$is_critical) {
|
|
echo "<a href='?delete={$matches[1]}' class='button is-small is-danger is-outlined' onclick='return confirm(\"Supprimer la règle #{$matches[1]} ?\")'>Supprimer</a>";
|
|
} else {
|
|
echo "<span class='tag is-warning is-light'>Protégé</span>";
|
|
}
|
|
echo "</td></tr>";
|
|
}
|
|
}
|
|
if (!$rules_found) echo "<tr><td colspan='5' class='has-text-centered p-5'>Aucune règle active.</td></tr>";
|
|
?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<p class="help has-text-centered mt-4">Lancé en mode local. Ctrl+C dans le terminal pour quitter.</p>
|
|
</div>
|
|
</section>
|
|
</body>
|
|
</html>
|