new options

This commit is contained in:
Mateusz Gruszczyński
2025-11-03 10:18:10 +01:00
parent acef7eb610
commit df70118653
5 changed files with 355 additions and 139 deletions

View File

@@ -1,50 +1,162 @@
{% extends "base.html" %}
{% set active_page = "" %}
{% block title %}HAProxy • Logs{% endblock %}
{% block breadcrumb %}<nav aria-label="breadcrumb" class="mb-3"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="{{ url_for('main.index') }}"><i class="bi bi-house"></i></a></li><li class="breadcrumb-item active" aria-current="page">Logi</li></ol></nav>{% endblock %}
{% set active_page = "logs" %}
{% block title %}HAProxy • Access Logs{% endblock %}
{% block breadcrumb %}Access Logs{% endblock %}
{% block content %}
<h3 class="mb-4" id="status_header">Status 403 Forbidden</h3>
{% if entries %}
<div class="vstack gap-3">
{% for entry in entries %}
<div class="card">
<div class="card-body">
<div class="row g-3">
<div class="col-md-6">
<div><strong>Czas:</strong> {{ entry['timestamp'] }}</div>
<div><strong>IP:</strong> {{ entry['ip_address'] }}</div>
<div><strong>Metoda:</strong> {{ entry['http_method'] }}</div>
<div><strong>URL:</strong> {{ entry['requested_url'] }}</div>
<div><strong>Status:</strong> <span class="badge bg-danger">403</span></div>
<div class="card shadow-sm mb-4">
<div class="card-header bg-info text-white">
<h5 class="mb-0"><i class="bi bi-file-text me-2"></i>HAProxy Access Logs & Security Analysis</h5>
</div>
<div class="card-body">
{% if logs %}
<!-- Statistics Cards -->
<div class="row mb-4">
<div class="col-md-3">
<div class="card text-center">
<div class="card-body">
<h6 class="text-muted">Total Requests</h6>
<div class="fs-3 fw-bold text-primary">{{ logs|length }}</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-center">
<div class="card-body">
<h6 class="text-muted">Threats Detected</h6>
<div class="fs-3 fw-bold text-danger">
{{ logs|selectattr('is_threat')|list|length }}
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-center">
<div class="card-body">
<h6 class="text-muted">Unique IPs</h6>
<div class="fs-3 fw-bold text-warning">
{{ logs|map(attribute='ip_address')|unique|list|length }}
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-center">
<div class="card-body">
<h6 class="text-muted">Success Rate</h6>
<div class="fs-3 fw-bold text-success">
{% set success_count = logs|selectattr('status_code')|selectattr('status_code', 'ge', 200)|selectattr('status_code', 'lt', 300)|list|length %}
{{ ((success_count / logs|length * 100)|round(1)) if logs else 0 }}%
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6">
{% if entry['xss_alert'] %}
<p class="mb-1"><button class="btn btn-sm btn-outline-danger" data-bs-toggle="collapse" data-bs-target="#xssCollapse{{ loop.index }}"><i class="bi bi-bug"></i> XSS alert</button></p>
<div id="xssCollapse{{ loop.index }}" class="collapse"><pre class="mb-0 text-danger">{{ entry['xss_alert'] }}</pre></div>
{% endif %}
{% if entry['sql_alert'] %}
<p class="mb-1"><button class="btn btn-sm btn-outline-warning" data-bs-toggle="collapse" data-bs-target="#sqlCollapse{{ loop.index }}"><i class="bi bi-database-exclamation"></i> SQLi alert</button></p>
<div id="sqlCollapse{{ loop.index }}" class="collapse"><pre class="mb-0 text-warning">{{ entry['sql_alert'] }}</pre></div>
{% endif %}
{% if entry['put_method'] %}
<p class="mb-1"><button class="btn btn-sm btn-outline-info" data-bs-toggle="collapse" data-bs-target="#putCollapse{{ loop.index }}"><i class="bi bi-upload"></i> PUT alert</button></p>
<div id="putCollapse{{ loop.index }}" class="collapse"><pre class="mb-0 text-info">{{ entry['put_method'] }}</pre></div>
{% endif %}
{% if entry['illegal_resource'] %}
<p class="mb-1"><button class="btn btn-sm btn-outline-light" data-bs-toggle="collapse" data-bs-target="#illegalCollapse{{ loop.index }}"><i class="bi bi-shield-x"></i> Nielegalny zasób</button></p>
<div id="illegalCollapse{{ loop.index }}" class="collapse"><pre class="mb-0 text-light">{{ entry['illegal_resource'] }}</pre></div>
{% endif %}
{% if entry['webshell_alert'] %}
<p class="mb-1"><button class="btn btn-sm btn-outline-danger" data-bs-toggle="collapse" data-bs-target="#webshellCollapse{{ loop.index }}"><i class="bi bi-file-earmark-code"></i> WebShell alert</button></p>
<div id="webshellCollapse{{ loop.index }}" class="collapse"><pre class="mb-0 text-danger">{{ entry['webshell_alert'] }}</pre></div>
{% endif %}
<!-- Filters -->
<div class="card mb-4 bg-light">
<div class="card-body">
<h6 class="mb-3"><i class="bi bi-funnel me-2"></i>Filters</h6>
<div class="row g-3">
<div class="col-md-3">
<label class="form-label small">Status Code</label>
<select class="form-select form-select-sm" id="filter_status">
<option value="">All</option>
{% for log in logs %}
<option value="{{ log.status_code }}">{{ log.status_code }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-3">
<label class="form-label small">Threat Level</label>
<select class="form-select form-select-sm" id="filter_threat">
<option value="">All</option>
<option value="danger">Danger</option>
<option value="warning">Warning</option>
<option value="info">Info</option>
</select>
</div>
<div class="col-md-3">
<label class="form-label small">HTTP Method</label>
<select class="form-select form-select-sm" id="filter_method">
<option value="">All</option>
{% set methods = logs|map(attribute='http_method')|unique %}
{% for method in methods %}
<option value="{{ method }}">{{ method }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-3">
<label class="form-label small">Show Threats Only</label>
<div class="form-check mt-2">
<input class="form-check-input" type="checkbox" id="filter_threats_only">
<label class="form-check-label" for="filter_threats_only">
Threats
</label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="alert alert-info"><i class="bi bi-info-circle me-1"></i>No data.</div>
{% endif %}
<!-- Logs Table -->
<div class="table-responsive">
<table class="table table-striped table-hover table-sm">
<thead class="table-dark">
<tr>
<th>Timestamp</th>
<th>IP Address</th>
<th>Method</th>
<th>URL</th>
<th>Status</th>
<th>Threats</th>
</tr>
</thead>
<tbody id="logs_table_body">
{% for log in logs %}
<tr class="log-row" data-status="{{ log.status_code }}" data-threat="{{ log.threat_level }}" data-method="{{ log.http_method }}" data-threat-count="{{ 1 if log.is_threat else 0 }}">
<td class="small">{{ log.timestamp }}</td>
<td>
<span class="badge bg-secondary">{{ log.ip_address }}</span>
</td>
<td>
<span class="badge bg-primary">{{ log.http_method }}</span>
</td>
<td class="text-truncate" style="max-width: 300px;" title="{{ log.requested_url }}">
{{ log.requested_url }}
</td>
<td>
<span class="badge bg-{{ log.status_category }}">{{ log.status_code }}</span>
</td>
<td>
{% if log.is_threat %}
{% for threat in log.threats %}
<span class="badge bg-{{ log.threat_level }} me-1">{{ threat }}</span>
{% endfor %}
{% else %}
<span class="text-muted small"></span>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="alert alert-info">
<i class="bi bi-info-circle me-2"></i>No log entries found.
</div>
{% endif %}
</div>
</div>
<script src="{{ url_for('static', filename='js/logs.js') }}"></script>
{% endblock %}