patchcenter/app/templates/audit_full_detail.html
Khalid MOUTAOUAKIL 40b0307f62 Accents dans tous les templates: audité, réseau, corrélation, patché, données, décommissionnés
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 22:28:33 +02:00

242 lines
14 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>
{% if is_partial %}
<div class="card p-8 text-center mb-4" style="background:#111827;">
<div class="text-3xl font-bold text-gray-500 mb-2">Pas encore audité</div>
<p class="text-sm text-gray-600">Ce serveur n'a pas encore été audité via SSH (Windows, EMV...)</p>
<p class="text-xs text-gray-600 mt-2">{{ a.hostname }} — {{ a.os_release or 'OS inconnu' }}</p>
{% if a.last_patch_week %}<p class="text-xs text-cyber-green mt-2">Dernier patch : {{ a.last_patch_week }} {{ a.last_patch_year }}</p>{% endif %}
</div>
{% else %}
<!-- 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','Corrélation')] %}
<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" style="max-width:200px;word-break:break-all;">{{ p.exe or '' }}</td>
<td class="p-2 font-mono text-gray-500" style="max-width:180px;word-break:break-all;">{{ p.cwd or '' }}</td>
<td class="p-2 font-mono text-cyber-accent" style="max-width:300px;word-break:break-all;">{{ p.cmdline or '' }}</td>
<td class="p-2 font-mono text-cyber-yellow" style="word-break:break-all;">{{ p.restart_hint or '' }}</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>
<!-- Corrélation -->
<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>
{% endif %}{# end is_partial else #}
{% endblock %}