115 lines
5.3 KiB
Python
115 lines
5.3 KiB
Python
from __future__ import annotations
|
|
|
|
import shutil
|
|
import subprocess
|
|
from dataclasses import dataclass
|
|
from pathlib import Path
|
|
|
|
from .system_info import SystemInfo
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class StatusItem:
|
|
category: str
|
|
label: str
|
|
ok: bool
|
|
detail: str
|
|
|
|
|
|
def _command_exists(command: str) -> bool:
|
|
return shutil.which(command) is not None
|
|
|
|
|
|
def _run(command: list[str]) -> subprocess.CompletedProcess[str]:
|
|
return subprocess.run(command, text=True, capture_output=True, check=False)
|
|
|
|
|
|
def _service_active(service: str) -> bool:
|
|
if not _command_exists("systemctl"):
|
|
return False
|
|
return _run(["systemctl", "is-active", service]).returncode == 0
|
|
|
|
|
|
def _binary_status(category: str, label: str, command: str) -> StatusItem:
|
|
exists = _command_exists(command)
|
|
return StatusItem(category=category, label=label, ok=exists, detail="installé" if exists else "absent")
|
|
|
|
|
|
def collect_status(system: SystemInfo) -> list[StatusItem]:
|
|
maintenance: list[StatusItem] = []
|
|
security: list[StatusItem] = []
|
|
services: list[StatusItem] = []
|
|
performance: list[StatusItem] = []
|
|
poste: list[StatusItem] = []
|
|
|
|
p10k_path = system.target_home / ".p10k.zsh"
|
|
poste.append(StatusItem("Poste", "Config p10k", p10k_path.exists(), str(p10k_path if p10k_path.exists() else "absente")))
|
|
|
|
unattended_ok = False
|
|
unattended_detail = "non configuré"
|
|
if system.package_manager == "apt-get":
|
|
unattended_ok = _service_active("unattended-upgrades.service") and Path("/etc/apt/apt.conf.d/20auto-upgrades").exists()
|
|
unattended_detail = "service actif" if unattended_ok else "service inactif"
|
|
elif system.package_manager in {"dnf", "yum"}:
|
|
unattended_ok = _service_active("dnf-automatic.timer")
|
|
unattended_detail = "timer actif" if unattended_ok else "timer inactif"
|
|
maintenance.append(StatusItem("Maintenance", "MAJ auto", unattended_ok, unattended_detail))
|
|
|
|
logrotate_ok = Path("/etc/logrotate.d/securecheck").exists()
|
|
maintenance.append(StatusItem("Maintenance", "Rotation logs", logrotate_ok, "config présente" if logrotate_ok else "config absente"))
|
|
|
|
zram_ok = _service_active("securecheck-zram.service") or ("zram" in _run(["swapon", "--show"]).stdout if _command_exists("swapon") else False)
|
|
performance.append(StatusItem("Performance", "zram", zram_ok, "actif" if zram_ok else "inactif"))
|
|
|
|
if _command_exists("ufw"):
|
|
ufw_result = _run(["ufw", "status"])
|
|
firewall_ok = "Status: active" in ufw_result.stdout
|
|
firewall_detail = "ufw actif" if firewall_ok else "ufw inactif"
|
|
elif _command_exists("firewall-cmd"):
|
|
firewall_ok = _service_active("firewalld.service")
|
|
firewall_detail = "firewalld actif" if firewall_ok else "firewalld inactif"
|
|
else:
|
|
firewall_ok = False
|
|
firewall_detail = "pare-feu absent"
|
|
security.append(StatusItem("Sécurité", "Firewall", firewall_ok, firewall_detail))
|
|
apparmor_active = _service_active("apparmor") or _command_exists("apparmor_status")
|
|
security.append(StatusItem("Sécurité", "AppArmor", apparmor_active, "activé" if apparmor_active else "inactif"))
|
|
|
|
clamav_active = _service_active("clamav-daemon") or _service_active("clamav-freshclam")
|
|
security.append(StatusItem("Sécurité", "ClamAV", clamav_active, "actif" if clamav_active else "inactif"))
|
|
wazuh_active = _service_active("wazuh-agent")
|
|
security.append(StatusItem("Sécurité", "Wazuh agent", wazuh_active, "actif" if wazuh_active else "inactif"))
|
|
aide_timer_active = _service_active("aidecheck.timer")
|
|
aide_db_exists = Path("/var/lib/aide/aide.db").exists()
|
|
aide_ok = aide_timer_active or aide_db_exists
|
|
detail = "timer actif" if aide_timer_active else "db présent" if aide_db_exists else "inactif"
|
|
security.append(StatusItem("Sécurité", "AIDE", aide_ok, detail))
|
|
|
|
security.append(_binary_status("Sécurité", "Lynis", "lynis"))
|
|
security.append(_binary_status("Sécurité", "rkhunter", "rkhunter"))
|
|
security.append(_binary_status("Sécurité", "chkrootkit", "chkrootkit"))
|
|
|
|
docker_active = _command_exists("docker") and _service_active("docker.service")
|
|
fail2ban_active = _command_exists("fail2ban-client") and _service_active("fail2ban.service")
|
|
services.append(StatusItem("Services", "Service Docker", docker_active, "actif" if docker_active else "inactif"))
|
|
services.append(StatusItem("Services", "Service fail2ban", fail2ban_active, "actif" if fail2ban_active else "inactif"))
|
|
avahi_running = _command_exists("avahi-daemon") and _service_active("avahi-daemon")
|
|
services.append(StatusItem("Services", "Avahi", not avahi_running, "désactivé" if not avahi_running else "actif"))
|
|
services.append(_binary_status("Services", "Docker", "docker"))
|
|
services.append(_binary_status("Services", "fail2ban", "fail2ban-client"))
|
|
|
|
poste.extend([
|
|
_binary_status("Poste", "zsh", "zsh"),
|
|
_binary_status("Poste", "git", "git"),
|
|
_binary_status("Poste", "curl", "curl"),
|
|
_binary_status("Poste", "ncdu", "ncdu"),
|
|
_binary_status("Poste", "needrestart", "needrestart"),
|
|
_binary_status("Poste", "htop", "htop"),
|
|
_binary_status("Poste", "nmon", "nmon"),
|
|
_binary_status("Poste", "duf", "duf"),
|
|
_binary_status("Poste", "net-tools", "ifconfig"),
|
|
])
|
|
|
|
ordered = maintenance + security + performance + services + poste
|
|
return ordered
|