diff --git a/Backend/fail2ban_log2json.sh b/Backend/fail2ban_log2json.sh index 6887ed8..dd6deff 100644 --- a/Backend/fail2ban_log2json.sh +++ b/Backend/fail2ban_log2json.sh @@ -1,5 +1,6 @@ #!/bin/bash -# This is the Logfile-Reader for the local installation - so you will have to edit the OUTPUT_JSON_DIR to fit your Webserver Installation +# This is the Logfile-Reader for the local installation +# You have to edit the OUTPUT_JSON_DIR to fit your Webserver Installation # LOGFILE="/var/log/fail2ban.log" OUTPUT_JSON_DIR="/var/www/html/Fail2Ban-Report/archive//fail2ban" @@ -9,27 +10,35 @@ TODAY=$(date +"%Y-%m-%d") OUTPUT_JSON_FILE="$OUTPUT_JSON_DIR/fail2ban-events-$(date +"%Y%m%d").json" mkdir -p "$OUTPUT_JSON_DIR" +# IPv4 regex: nnn.nnn.nnn.nnn (0-255 simplified to 0-999 for awk) +IPv4='([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})' +# IPv6 regex: blocks of hex split by collon, allowed "::" short format +IPv6='(([0-9A-Fa-f]{1,4}:){1,7}[0-9A-Fa-f]{1,4}|([0-9A-Fa-f]{1,4}:){1,7}:|:([0-9A-Fa-f]{1,4}:){1,7}[0-9A-Fa-f]{1,4}|::)' +# complete IPv4 and IPv6 pattern +IP_PATTERN="($IPv4|$IPv6)" + echo "[" > "$OUTPUT_JSON_FILE" # Grep all relevant Events -grep -E "(Ban|Unban)" "$LOGFILE" | awk -v today="$TODAY" ' +grep -E "(Ban|Unban)" "$LOGFILE" | awk -v today="$TODAY" -v ip_pattern="$IP_PATTERN" ' { timestamp = $1 " " $2; if (index(timestamp, today) != 1) next; action = ""; ip = ""; + if ($0 ~ /Increase Ban/) { action = "Increase Ban"; - match($0, /Increase Ban ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/, m); + match($0, action " " ip_pattern, m); if (m[1]) ip = m[1]; } else if ($0 ~ /Ban/) { action = "Ban"; - match($0, /Ban ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/, m); + match($0, action " " ip_pattern, m); if (m[1]) ip = m[1]; } else if ($0 ~ /Unban/) { action = "Unban"; - match($0, /Unban ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/, m); + match($0, action " " ip_pattern, m); if (m[1]) ip = m[1]; } diff --git a/Web-UI/assets/css/style.css b/Web-UI/assets/css/style.css index 82e22e1..52282d7 100644 --- a/Web-UI/assets/css/style.css +++ b/Web-UI/assets/css/style.css @@ -166,7 +166,7 @@ tr:nth-child(even) { font-family: monospace; font-size: 14px; opacity: 0.95; - animation: fadein 0.3s ease-out, fadeout 0.5s ease-in 4s forwards; + animation: fadein 0.3s ease-out, fadeout 0.5s ease-in 20s forwards; } @keyframes fadein { diff --git a/Web-UI/assets/js/action-collector.js b/Web-UI/assets/js/action-collector.js index ad74975..f2218d6 100644 --- a/Web-UI/assets/js/action-collector.js +++ b/Web-UI/assets/js/action-collector.js @@ -35,7 +35,7 @@ function collectAndExecuteActions(ips, action, jails = []) { const prefix = `[${action.toUpperCase()}] `; const message = data.message || 'No message returned.'; const type = data.type || (data.success ? 'success' : 'error'); - const duration = (action === 'report') ? 7000 : 7000; + const duration = (action === 'report') ? 25000 : 7000; showNotification(prefix + message, type, duration); }) .catch(err => { diff --git a/Web-UI/assets/js/ufw-report.js b/Web-UI/assets/js/ufw-report.js new file mode 100644 index 0000000..104a2fa --- /dev/null +++ b/Web-UI/assets/js/ufw-report.js @@ -0,0 +1,30 @@ +document.addEventListener('DOMContentLoaded', () => { + async function updateUFWBlocks() { + const div = document.getElementById('ufw-blocks-info'); + if (!div) return; + + try { + const response = await fetch('includes/ufw-report.php'); + if (!response.ok) throw new Error(`Network response was not ok`); + const data = await response.json(); + + // Gesamt + let output = `Total Matches: ${data.total}`; + + // Per IP + if (data.per_ip && Object.keys(data.per_ip).length > 0) { + const ipInfo = Object.entries(data.per_ip).map(([ip, info]) => { + return `${info.blocklist}: ${ip} (${info.count})`; + }); + output += ' | ' + ipInfo.join(' | '); + } + + div.textContent = output; + } catch (err) { + console.error('Error fetching UFW blocklist data:', err); + div.textContent = '⚠ Error loading UFW blocklist info'; + } + } + + updateUFWBlocks(); +}); diff --git a/Web-UI/includes/actions/action_ban-ip.php b/Web-UI/includes/actions/action_ban-ip.php index 17f9909..89f7912 100644 --- a/Web-UI/includes/actions/action_ban-ip.php +++ b/Web-UI/includes/actions/action_ban-ip.php @@ -2,7 +2,7 @@ // includes/actions/action_ban-ip.php header('Content-Type: application/json; charset=utf-8'); -require_once __DIR__ . '/../block-ip.php'; +require_once dirname(__DIR__) . '/block-ip.php'; // Check if IP(s) were provided if (!isset($_POST['ip'])) { diff --git a/Web-UI/includes/actions/action_report-ip.php b/Web-UI/includes/actions/action_report-ip.php index 1ee590f..f8060c7 100644 --- a/Web-UI/includes/actions/action_report-ip.php +++ b/Web-UI/includes/actions/action_report-ip.php @@ -3,10 +3,11 @@ header('Content-Type: application/json; charset=utf-8'); -$config = parse_ini_file('/opt/Fail2Ban-Report/Settings/fail2ban-report.config'); +// Read config to flat array $infoConfig (to avoid overwrite from included $script) +$infoConfig = parse_ini_file('/opt/Fail2Ban-Report/Settings/fail2ban-report.config'); $ips = $_POST['ip'] ?? null; -if (!$config['report'] || !$config['report_types'] || !$ips) { +if (!$infoConfig['report'] || !$infoConfig['report_types'] || !$ips) { echo json_encode([ 'success' => false, 'message' => 'Reporting not enabled or invalid IP(s).', @@ -19,7 +20,7 @@ $ips = [$ips]; // Convert single IP to array } -$services = array_map('trim', explode(',', $config['report_types'])); +$services = array_map('trim', explode(',', $infoConfig['report_types'])); $results = []; $allMessages = []; $overallSuccess = true; @@ -34,7 +35,7 @@ $script = __DIR__ . "/reports/$service.php"; // Check API keys for services that require them - if ($service === 'abuseipdb' && empty($config['abuseipdb_key'])) { + if ($service === 'abuseipdb' && empty($infoConfig['abuseipdb_key'])) { $ipSuccess = false; $reportResults[$service] = [ 'success' => false, @@ -43,8 +44,7 @@ ]; $messages[] = "[$service] API key missing"; continue; - } - if ($service === 'ipinfo' && empty($config['ipinfo_key'])) { + } elseif ($service === 'ipinfo' && empty($infoConfig['ipinfo_key'])) { $ipSuccess = false; $reportResults[$service] = [ 'success' => false, diff --git a/Web-UI/includes/actions/action_unban-ip.php b/Web-UI/includes/actions/action_unban-ip.php index 4ff8b61..51019ee 100644 --- a/Web-UI/includes/actions/action_unban-ip.php +++ b/Web-UI/includes/actions/action_unban-ip.php @@ -3,7 +3,7 @@ header('Content-Type: application/json; charset=utf-8'); -require_once __DIR__ . '/../unblock-ip.php'; +require_once dirname(__DIR__) . '/unblock-ip.php'; // Validate input if (!isset($_POST['ip']) || !isset($_POST['jail'])) { diff --git a/Web-UI/includes/actions/reports/abuseipdb.php b/Web-UI/includes/actions/reports/abuseipdb.php index b21f956..e850d07 100644 --- a/Web-UI/includes/actions/reports/abuseipdb.php +++ b/Web-UI/includes/actions/reports/abuseipdb.php @@ -1,7 +1,7 @@ true, diff --git a/Web-UI/includes/header.php b/Web-UI/includes/header.php index 3aa8b69..a37d60e 100644 --- a/Web-UI/includes/header.php +++ b/Web-UI/includes/header.php @@ -8,7 +8,7 @@ Fail2Ban Report - + @@ -64,7 +64,7 @@ - +
@@ -76,12 +76,13 @@
+
- + diff --git a/Web-UI/includes/list-files.php b/Web-UI/includes/list-files.php index 4c6d076..bd84fed 100644 --- a/Web-UI/includes/list-files.php +++ b/Web-UI/includes/list-files.php @@ -1,10 +1,11 @@ 'disabled', 'reason' => 'No config found']); exit;