233 lines
13 KiB
HTML
233 lines
13 KiB
HTML
{% extends 'base.html' %}
|
|
{% block title %}{{ a.hostname }}{% endblock %}
|
|
{% block content %}
|
|
<a href="/audit-full" class="text-xs text-gray-500 hover:text-gray-300">< Retour</a>
|
|
<div class="flex justify-between items-center mb-4">
|
|
<div>
|
|
<h2 class="text-xl font-bold text-cyber-accent">{{ a.hostname }}</h2>
|
|
<p class="text-xs text-gray-500">{{ a.os_release }} | {{ a.kernel }} | {{ a.uptime }}</p>
|
|
</div>
|
|
<div class="flex gap-2 text-xs">
|
|
{% for iface in interfaces %}{% if iface.ip != '127.0.0.1' %}
|
|
<span class="badge badge-blue">{{ iface.ip }}{{ iface.mask }} ({{ iface.iface }})</span>
|
|
{% endif %}{% endfor %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- KPI -->
|
|
<div style="display:flex;flex-wrap:nowrap;gap:8px;margin-bottom:16px;">
|
|
<div class="card p-2 text-center" style="flex:1;min-width:0"><div class="text-base font-bold text-cyber-accent">{{ services|length }}</div><div class="text-xs text-gray-500">Services</div></div>
|
|
<div class="card p-2 text-center" style="flex:1;min-width:0"><div class="text-base font-bold text-cyber-accent">{{ processes|length }}</div><div class="text-xs text-gray-500">Process</div></div>
|
|
<div class="card p-2 text-center" style="flex:1;min-width:0"><div class="text-base font-bold text-cyber-accent">{{ listen_ports|length }}</div><div class="text-xs text-gray-500">Ports</div></div>
|
|
<div class="card p-2 text-center" style="flex:1;min-width:0"><div class="text-base font-bold text-cyber-accent">{{ connections|length }}</div><div class="text-xs text-gray-500">Connexions</div></div>
|
|
<div class="card p-2 text-center" style="flex:1;min-width:0"><div class="text-base font-bold {% if a.reboot_required %}text-cyber-red{% else %}text-cyber-green{% endif %}">{% if a.reboot_required %}Oui{% else %}Non{% endif %}</div><div class="text-xs text-gray-500">Reboot</div></div>
|
|
<div class="card p-2 text-center" style="flex:1;min-width:0"><div class="text-base font-bold {% if a.services_failed %}text-cyber-red{% else %}text-cyber-green{% endif %}">{% if a.services_failed %}KO{% else %}OK{% endif %}</div><div class="text-xs text-gray-500">Failed svc</div></div>
|
|
</div>
|
|
|
|
<!-- Onglets -->
|
|
<div x-data="{ tab: 'services' }">
|
|
<div class="flex gap-1 mb-3 flex-wrap">
|
|
{% for t, label in [('services','Services'),('processes','Processus'),('ports','Ports'),('connections','Connexions'),('flux','Flux'),('disk','Disque'),('firewall','Firewall'),('correlation','Correlation')] %}
|
|
<button @click="tab='{{ t }}'" class="px-3 py-1 text-xs rounded" :class="tab==='{{ t }}' ? 'bg-cyber-accent text-black font-bold' : 'bg-cyber-border text-gray-400'">{{ label }}</button>
|
|
{% endfor %}
|
|
</div>
|
|
|
|
<!-- Services -->
|
|
<div x-show="tab==='services'" class="card overflow-x-auto">
|
|
<table class="w-full table-cyber text-xs"><thead><tr>
|
|
<th class="text-left p-2">Service</th><th class="p-2">Enabled</th><th class="p-2">PID</th><th class="p-2">User</th><th class="text-left p-2">Exec</th>
|
|
</tr></thead><tbody>
|
|
{% for s in services %}<tr>
|
|
<td class="p-2 font-mono text-cyber-accent">{{ s.name }}</td>
|
|
<td class="p-2 text-center"><span class="badge {% if s.enabled == 'enabled' %}badge-green{% else %}badge-gray{% endif %}">{{ s.enabled }}</span></td>
|
|
<td class="p-2 text-center font-mono">{{ s.pid }}</td>
|
|
<td class="p-2 text-center">{{ s.user }}</td>
|
|
<td class="p-2 text-gray-400">{{ s.exec[:80] }}</td>
|
|
</tr>{% endfor %}
|
|
</tbody></table>
|
|
</div>
|
|
|
|
<!-- Processus -->
|
|
<div x-show="tab==='processes'" class="card overflow-x-auto">
|
|
<table class="w-full table-cyber text-xs"><thead><tr>
|
|
<th class="p-2">PID</th><th class="p-2">User</th><th class="text-left p-2">Exe</th><th class="text-left p-2">CWD</th><th class="text-left p-2">Cmdline</th><th class="text-left p-2">Restart</th>
|
|
</tr></thead><tbody>
|
|
{% for p in processes %}<tr class="{% if '/applis' in (p.cwd or '') %}bg-green-900/10{% endif %}">
|
|
<td class="p-2 font-mono text-center">{{ p.pid }}</td>
|
|
<td class="p-2 text-center">{{ p.user }}</td>
|
|
<td class="p-2 font-mono text-gray-400">{{ (p.exe or '')[:40] }}</td>
|
|
<td class="p-2 font-mono text-gray-500">{{ (p.cwd or '')[:30] }}</td>
|
|
<td class="p-2 font-mono text-cyber-accent">{{ (p.cmdline or '')[:60] }}</td>
|
|
<td class="p-2 text-gray-400">{{ (p.restart_hint or '')[:60] }}</td>
|
|
</tr>{% endfor %}
|
|
</tbody></table>
|
|
</div>
|
|
|
|
<!-- Ports -->
|
|
<div x-show="tab==='ports'" class="card overflow-x-auto">
|
|
<table class="w-full table-cyber text-xs"><thead><tr>
|
|
<th class="p-2">Proto</th><th class="p-2">Addr:Port</th><th class="p-2">PID</th><th class="p-2">Process</th><th class="p-2">User</th><th class="p-2">Service</th>
|
|
</tr></thead><tbody>
|
|
{% for lp in listen_ports %}<tr>
|
|
<td class="p-2 text-center">{{ lp.proto }}</td>
|
|
<td class="p-2 font-mono text-cyber-accent">{{ lp.addr_port }}</td>
|
|
<td class="p-2 text-center font-mono">{{ lp.pid }}</td>
|
|
<td class="p-2 text-center">{{ lp.process }}</td>
|
|
<td class="p-2 text-center">{{ lp.user }}</td>
|
|
<td class="p-2 text-center text-gray-400">{{ lp.service }}</td>
|
|
</tr>{% endfor %}
|
|
</tbody></table>
|
|
</div>
|
|
|
|
<!-- Connexions -->
|
|
<div x-show="tab==='connections'" class="card overflow-x-auto">
|
|
<table class="w-full table-cyber text-xs"><thead><tr>
|
|
<th class="p-2">Dir</th><th class="p-2">Local</th><th class="p-2">Remote</th><th class="p-2">PID</th><th class="p-2">Process</th><th class="p-2">User</th><th class="p-2">State</th>
|
|
</tr></thead><tbody>
|
|
{% for c in connections %}<tr class="{% if c.state == 'CLOSE-WAIT' %}bg-red-900/10{% endif %}">
|
|
<td class="p-2 text-center"><span class="badge {% if c.direction == 'IN' %}badge-green{% else %}badge-yellow{% endif %}">{{ c.direction }}</span></td>
|
|
<td class="p-2 font-mono">{{ c.local }}</td>
|
|
<td class="p-2 font-mono text-cyber-accent">{{ c.remote }}</td>
|
|
<td class="p-2 text-center font-mono">{{ c.pid }}</td>
|
|
<td class="p-2 text-center">{{ c.process }}</td>
|
|
<td class="p-2 text-center">{{ c.user }}</td>
|
|
<td class="p-2 text-center"><span class="badge {% if c.state == 'ESTAB' %}badge-green{% elif c.state == 'CLOSE-WAIT' %}badge-red{% else %}badge-gray{% endif %}">{{ c.state }}</span></td>
|
|
</tr>{% endfor %}
|
|
</tbody></table>
|
|
</div>
|
|
|
|
<!-- Flux -->
|
|
<div x-show="tab==='flux'" class="space-y-3">
|
|
{% if flux_in %}
|
|
<div class="card overflow-x-auto">
|
|
<div class="p-2 border-b border-cyber-border"><span class="text-xs font-bold text-cyber-green">Flux entrants</span></div>
|
|
<table class="w-full table-cyber text-xs"><thead><tr>
|
|
<th class="p-2">Port</th><th class="p-2">Service</th><th class="p-2">Process</th><th class="p-2">Nb</th><th class="text-left p-2">Sources</th>
|
|
</tr></thead><tbody>
|
|
{% for f in flux_in %}<tr>
|
|
<td class="p-2 text-center font-mono text-cyber-accent">{{ f.port }}</td>
|
|
<td class="p-2 text-center">{{ f.service }}</td>
|
|
<td class="p-2 text-center">{{ f.process }}</td>
|
|
<td class="p-2 text-center font-bold">{{ f.count }}</td>
|
|
<td class="p-2 font-mono text-gray-400">{{ f.sources }}</td>
|
|
</tr>{% endfor %}
|
|
</tbody></table>
|
|
</div>
|
|
{% endif %}
|
|
{% if flux_out %}
|
|
<div class="card overflow-x-auto">
|
|
<div class="p-2 border-b border-cyber-border"><span class="text-xs font-bold text-cyber-yellow">Flux sortants</span></div>
|
|
<table class="w-full table-cyber text-xs"><thead><tr>
|
|
<th class="text-left p-2">Destination</th><th class="p-2">Port</th><th class="p-2">Service</th><th class="p-2">Process</th><th class="p-2">Nb</th>
|
|
</tr></thead><tbody>
|
|
{% for f in flux_out %}<tr>
|
|
<td class="p-2 font-mono text-cyber-accent">{{ f.dest_ip }}</td>
|
|
<td class="p-2 text-center">{{ f.dest_port }}</td>
|
|
<td class="p-2 text-center">{{ f.service }}</td>
|
|
<td class="p-2 text-center">{{ f.process }}</td>
|
|
<td class="p-2 text-center font-bold">{{ f.count }}</td>
|
|
</tr>{% endfor %}
|
|
</tbody></table>
|
|
</div>
|
|
{% endif %}
|
|
{% if flows %}
|
|
<div class="card overflow-x-auto">
|
|
<div class="p-2 border-b border-cyber-border"><span class="text-xs font-bold text-cyber-accent">Carte flux (resolu)</span></div>
|
|
<table class="w-full table-cyber text-xs"><thead><tr>
|
|
<th class="p-2">Dir</th><th class="p-2">IP dest</th><th class="p-2">Port</th><th class="p-2">Serveur dest</th><th class="p-2">Process</th><th class="p-2">State</th>
|
|
</tr></thead><tbody>
|
|
{% for f in flows %}<tr>
|
|
<td class="p-2 text-center"><span class="badge {% if f.direction == 'IN' %}badge-green{% else %}badge-yellow{% endif %}">{{ f.direction }}</span></td>
|
|
<td class="p-2 font-mono">{{ f.dest_ip }}</td>
|
|
<td class="p-2 text-center">{{ f.dest_port }}</td>
|
|
<td class="p-2 font-mono text-cyber-accent">{{ f.dest_hostname or '-' }}</td>
|
|
<td class="p-2 text-center">{{ f.process_name }}</td>
|
|
<td class="p-2 text-center"><span class="badge {% if f.state == 'ESTAB' %}badge-green{% elif f.state == 'CLOSE-WAIT' %}badge-red{% else %}badge-gray{% endif %}">{{ f.state }}</span></td>
|
|
</tr>{% endfor %}
|
|
</tbody></table>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- Disque -->
|
|
<div x-show="tab==='disk'" class="card overflow-x-auto">
|
|
<table class="w-full table-cyber text-xs"><thead><tr>
|
|
<th class="text-left p-2">Mount</th><th class="p-2">Taille</th><th class="p-2">Utilise</th><th class="p-2">Dispo</th><th class="p-2">%</th>
|
|
</tr></thead><tbody>
|
|
{% for d in disk_usage %}<tr class="{% if d.pct >= 90 %}bg-red-900/20{% elif d.pct >= 80 %}bg-yellow-900/10{% endif %}">
|
|
<td class="p-2 font-mono">{{ d.mount }}</td>
|
|
<td class="p-2 text-center">{{ d.size }}</td>
|
|
<td class="p-2 text-center">{{ d.used }}</td>
|
|
<td class="p-2 text-center">{{ d.avail }}</td>
|
|
<td class="p-2 text-center font-bold {% if d.pct >= 90 %}text-cyber-red{% elif d.pct >= 80 %}text-cyber-yellow{% else %}text-cyber-green{% endif %}">{{ d.pct }}%</td>
|
|
</tr>{% endfor %}
|
|
</tbody></table>
|
|
</div>
|
|
|
|
<!-- Firewall -->
|
|
<div x-show="tab==='firewall'" class="space-y-3">
|
|
{% if firewall.policy %}
|
|
<div class="card p-3">
|
|
<span class="text-xs font-bold text-cyber-accent">Policy iptables :</span>
|
|
{% for chain, pol in firewall.policy.items() %}
|
|
<span class="badge {% if pol == 'DROP' %}badge-red{% elif pol == 'ACCEPT' %}badge-green{% else %}badge-gray{% endif %} ml-2">{{ chain }}={{ pol or '?' }}</span>
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
{% if firewall.firewalld %}
|
|
<div class="card p-3">
|
|
<span class="text-xs font-bold text-cyber-accent">Firewalld :</span>
|
|
{% for z in firewall.firewalld %}
|
|
<div class="mt-1 text-xs">Zone <span class="text-cyber-yellow">{{ z.zone }}</span> : services={{ z.services }} ports={{ z.ports }}</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
{% if conn_wait %}
|
|
<div class="card p-3">
|
|
<span class="text-xs font-bold text-cyber-accent">Connexions en attente :</span>
|
|
{% for cw in conn_wait %}
|
|
<span class="badge {% if cw.state == 'CLOSE-WAIT' %}badge-red{% else %}badge-gray{% endif %} ml-2">{{ cw.state }}={{ cw.count }}</span>
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- Correlation -->
|
|
<div x-show="tab==='correlation'" class="space-y-3">
|
|
{% if correlation %}
|
|
<div class="card overflow-x-auto">
|
|
<div class="p-2 border-b border-cyber-border"><span class="text-xs font-bold text-cyber-accent">Matrice process / ports / flux</span></div>
|
|
<table class="w-full table-cyber text-xs"><thead><tr>
|
|
<th class="text-left p-2">Process</th><th class="p-2">User</th><th class="p-2">PID</th><th class="p-2">Ports</th><th class="p-2">IN</th><th class="p-2">OUT</th><th class="text-left p-2">Destinations</th>
|
|
</tr></thead><tbody>
|
|
{% for c in correlation %}<tr>
|
|
<td class="p-2 font-mono text-cyber-accent">{{ c.process }}</td>
|
|
<td class="p-2 text-center">{{ c.user }}</td>
|
|
<td class="p-2 text-center font-mono">{{ c.pid }}</td>
|
|
<td class="p-2 text-center font-mono text-cyber-yellow">{{ c.listen_ports }}</td>
|
|
<td class="p-2 text-center font-bold text-cyber-green">{{ c.conn_in }}</td>
|
|
<td class="p-2 text-center font-bold text-cyber-yellow">{{ c.conn_out }}</td>
|
|
<td class="p-2 font-mono text-gray-400">{{ c.remote_dests }}</td>
|
|
</tr>{% endfor %}
|
|
</tbody></table>
|
|
</div>
|
|
{% endif %}
|
|
{% if outbound %}
|
|
<div class="card overflow-x-auto">
|
|
<div class="p-2 border-b border-cyber-border"><span class="text-xs font-bold text-cyber-yellow">Process sortants uniquement</span></div>
|
|
<table class="w-full table-cyber text-xs"><thead><tr>
|
|
<th class="text-left p-2">Process</th><th class="p-2">User</th><th class="p-2">PID</th><th class="text-left p-2">Destinations</th>
|
|
</tr></thead><tbody>
|
|
{% for o in outbound %}<tr>
|
|
<td class="p-2 font-mono text-cyber-accent">{{ o.process }}</td>
|
|
<td class="p-2 text-center">{{ o.user }}</td>
|
|
<td class="p-2 text-center font-mono">{{ o.pid }}</td>
|
|
<td class="p-2 font-mono text-gray-400">{{ o.dests }}</td>
|
|
</tr>{% endfor %}
|
|
</tbody></table>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|