Fișierul de configurare al unei aplicații a fost modificat, dar simpla alertă „checksum changed” nu spune dacă intervenția aparține administratorului sau trebuie investigată. În acest laborator, Wazuh urmărește în timp real /srv/fim-lab/app.conf, păstrează diferențele dintre versiuni și adaugă informații despre utilizatorul și procesul care au produs schimbarea.
Rezultatul este verificabil: o modificare făcută prin contul dedicat fimadmin apare drept candidat administrativ, iar una făcută direct de root intră în coada de investigație. Clasificarea nu transformă numele utilizatorului într-o dovadă de autorizare: intervenția administrativă se acceptă numai dacă identitatea, intervalul, înregistrarea schimbării și diferența de conținut concordă.
Laboratorul produce două evenimente FIM care pot fi comparate
Scenariul folosește un server Ubuntu pe care rulează agentul Wazuh și un manager Wazuh deja funcțional. Vom crea:
- un fișier de configurare demonstrativ, nefolosit de vreun serviciu;
- un manifest SHA-256 independent, util pentru verificarea manuală a stării inițiale;
- monitorizare Wazuh cu
whodata="yes"șireport_changes="yes"; - un cont dedicat schimbărilor administrative;
- o evidență locală a intervenției aprobate;
- un script de triere care citește alertele JSON de pe manager.
Wazuh își construiește propriul baseline în baza internă FIM. Manifestul SHA-256 creat aici nu înlocuiește baza Wazuh; este reperul extern pe care administratorul îl poate arhiva și compara fără să modifice datele interne ale agentului.
Fixăm Ubuntu 24.04 și Wazuh 4.14.8 înainte de configurare
Varianta testată este Ubuntu Server 24.04 LTS pentru endpoint și Wazuh 4.14.8 pentru agent și manager. Managerul trebuie să fie la aceeași versiune sau la una compatibilă mai nouă. Adresa de documentație 192.0.2.10 reprezintă managerul și trebuie înlocuită cu adresa sa reală.
Pentru laborator rezervă două nuclee virtuale, 2 GB RAM, 5 GB liberi și aproximativ 45 de minute. Pe endpoint rulează:
cat /etc/os-release
uname -r
free -h
df -h /
systemctl is-active auditd
Pe manager rulează:
sudo /var/ossec/bin/wazuh-control info
sudo dpkg-query -W -f='${Package} ${Version}n' wazuh-manager
Outputul relevant trebuie să includă valori similare celor de mai jos. Versiunea exactă a kernelului, memoria și spațiul disponibil vor diferi:
VERSION_ID="24.04"
auditd: active
wazuh-manager 4.14.8-1
Tutorialul presupune acces administrativ la ambele sisteme și conectivitate între agent și manager. Nu expune porturile Wazuh direct la internet; folosește rețeaua internă sau un canal VPN administrat.
Instalăm agentul, Audit și uneltele de verificare
Pe endpoint, instalăm pachetele într-un singur bloc. Înlocuiește 192.0.2.10 cu adresa managerului înainte de execuție:
set -euo pipefail
sudo apt-get update
sudo apt-get install -y curl gnupg apt-transport-https auditd openssh-server jq
curl -s https://packages.wazuh.com/key/GPG-KEY-WAZUH
| sudo gpg --no-default-keyring
--keyring gnupg-ring:/usr/share/keyrings/wazuh.gpg
--import
sudo chmod 644 /usr/share/keyrings/wazuh.gpg
echo 'deb [signed-by=/usr/share/keyrings/wazuh.gpg] https://packages.wazuh.com/4.x/apt/ stable main'
| sudo tee /etc/apt/sources.list.d/wazuh.list >/dev/null
sudo apt-get update
sudo env
WAZUH_MANAGER="192.0.2.10"
WAZUH_AGENT_NAME="web-01"
apt-get install -y wazuh-agent=4.14.8-1
sudo systemctl daemon-reload
sudo systemctl enable --now auditd
sudo systemctl enable --now ssh
sudo systemctl enable --now wazuh-agent
dpkg-query -W -f='${Package} ${Version}n' wazuh-agent
systemctl is-active auditd ssh wazuh-agent
WAZUH_MANAGER stabilește destinația agentului, iar WAZUH_AGENT_NAME oferă endpointului numele stabil web-01. Modul who-data folosește subsistemul Linux Audit pentru a adăuga identitatea și procesul asociate modificării.
Outputul așteptat este:
wazuh-agent 4.14.8-1
active
active
active
Dacă managerul nu afișează agentul ca activ, rezolvă înrolarea înainte de a continua. FIM local poate observa fișiere, dar evenimentele nu vor ajunge în jurnalul de alerte al managerului.
Fișierele separă configurația monitorizată de evidența administrativă
La final, componentele relevante sunt:
/srv/fim-lab/
└── app.conf # fișierul demonstrativ monitorizat
/var/lib/fim-lab/
├── baseline.sha256 # hash-ul inițial, independent de baza Wazuh
└── change-record.tsv # evidența intervenției administrative
/var/ossec/etc/
├── ossec.conf # configurația agentului Wazuh
└── ossec.conf.before-fim-lab # copia de siguranță
/root/.ssh/
├── fimadmin-lab # cheie privată, mod 600
└── fimadmin-lab.pub # cheia publică pentru contul dedicat
/usr/local/sbin/
└── fim-triage # raportul executat pe manager
Fișierul monitorizat nu conține parole, tokenuri sau chei. Aceasta contează deoarece report_changes="yes" poate include în alertă textul adăugat sau eliminat. Pentru fișiere sensibile se păstrează alerta de integritate, dar se aplică nodiff, conform documentației Wazuh.
Pasul 1 — Creăm fișierul și identitatea folosită numai pentru schimbări planificate
Contul separat oferă un semnal de triere ușor de urmărit. Cheia este creată local pentru laborator, protejată cu permisiunea 600 și autorizată numai pentru fimadmin.
Rulează pe endpoint:
set -euo pipefail
id fimadmin >/dev/null 2>&1
|| sudo useradd --create-home --shell /bin/bash fimadmin
sudo install -d -o root -g root -m 0755 /srv/fim-lab
sudo install -d -o root -g root -m 0700 /var/lib/fim-lab
sudo install -d -o fimadmin -g fimadmin -m 0700 /home/fimadmin/.ssh
sudo install -d -o root -g root -m 0700 /root/.ssh
if [ ! -f /root/.ssh/fimadmin-lab ]; then
sudo ssh-keygen -q -t ed25519 -N ''
-C 'fimadmin-lab'
-f /root/.ssh/fimadmin-lab
fi
sudo sh -c
'cat /root/.ssh/fimadmin-lab.pub > /home/fimadmin/.ssh/authorized_keys'
sudo chown fimadmin:fimadmin /home/fimadmin/.ssh/authorized_keys
sudo chmod 0600 /home/fimadmin/.ssh/authorized_keys
cat <<'EOF' | sudo tee /srv/fim-lab/app.conf >/dev/null
mode=production
listen=127.0.0.1
timeout=30
EOF
sudo chown root:fimadmin /srv/fim-lab/app.conf
sudo chmod 0664 /srv/fim-lab/app.conf
sudo sha256sum /srv/fim-lab/app.conf
| sudo tee /var/lib/fim-lab/baseline.sha256 >/dev/null
sudo cat /var/lib/fim-lab/baseline.sha256
sudo stat -c '%U:%G %a %n' /srv/fim-lab/app.conf
Grupul fimadmin poate scrie în fișier, dar nu poate crea alte fișiere în director. Cheia privată rămâne accesibilă numai lui root.
Trebuie să vezi un hash de 64 de caractere hexazecimale și permisiunile:
root:fimadmin 664 /srv/fim-lab/app.conf
Punct de control: dacă ssh -i /root/.ssh/fimadmin-lab fimadmin@localhost true nu se încheie fără parolă, verifică serviciul ssh, proprietarul fișierului authorized_keys și permisiunile directoarelor.
Pasul 2 — Activăm who-data și diferențele de conținut în agent
Înainte de modificare salvăm configurația originală. Comanda refuză să continue dacă laboratorul a fost configurat deja, evitând o intrare duplicată.
Rulează pe endpoint:
set -euo pipefail
test ! -e /var/ossec/etc/ossec.conf.before-fim-lab
sudo cp -a
/var/ossec/etc/ossec.conf
/var/ossec/etc/ossec.conf.before-fim-lab
if sudo grep -qF '/srv/fim-lab' /var/ossec/etc/ossec.conf; then
echo 'Directorul este deja prezent în ossec.conf' >&2
exit 1
fi
sudo sed -i
'#</syscheck>#i <directories check_all="yes" whodata="yes" report_changes="yes">/srv/fim-lab</directories>'
/var/ossec/etc/ossec.conf
sudo /var/ossec/bin/wazuh-syscheckd -t
sudo systemctl restart wazuh-agent
sudo systemctl is-active wazuh-agent
sudo grep -F '/srv/fim-lab' /var/ossec/etc/ossec.conf
check_all="yes" urmărește hashurile și atributele acceptate de FIM. whodata="yes" solicită informații despre autorul și procesul schimbării, iar report_changes="yes" păstrează diferența pentru fișiere text.
Rezultatul trebuie să confirme o configurație validă, un serviciu activ și linia:
<directories check_all="yes" whodata="yes" report_changes="yes">/srv/fim-lab</directories>
Punct de control: dacă agentul nu pornește, nu edita configurația la întâmplare. Restaurează copia .before-fim-lab, pornește agentul și verifică poziția elementului <directories> în blocul <syscheck>.
Pasul 3 — Lăsăm scanarea inițială să devină baseline Wazuh
După restart, modulul syscheck inventariază fișierul. Nu modifica app.conf până când scanarea inițială nu s-a încheiat.
Rulează pe endpoint:
set -euo pipefail
for attempt in $(seq 1 30); do
if sudo grep -q 'File integrity monitoring scan ended'
/var/ossec/logs/ossec.log; then
break
fi
sleep 2
done
sudo grep -E
'File integrity monitoring scan (started|ended)'
/var/ossec/logs/ossec.log
| tail -n 4
sudo sha256sum --check /var/lib/fim-lab/baseline.sha256
Mesajele pot include timestampuri și identificatori diferiți, dar verificarea hashului trebuie să se termine astfel:
/srv/fim-lab/app.conf: OK
Acesta este momentul în care starea inițială devine reper. În producție, arhivează manifestul într-un spațiu la care administratorul endpointului nu poate rescrie istoricul.
Punct de control: dacă nu apare finalul scanării, inspectează journalctl -u wazuh-agent și /var/ossec/logs/ossec.log înainte de a genera evenimente.
Pasul 4 — Înregistrăm intervenția și o executăm prin contul dedicat
O identitate administrativă nu este suficientă. Mai întâi scriem un număr de schimbare și acțiunea așteptată într-un registru separat, apoi modificăm fișierul printr-o sesiune SSH autenticată ca fimadmin.
Rulează pe endpoint:
set -euo pipefail
printf '%stCHG-2026-0926tfimadmintadaugare maintenance=truen'
"$(date --iso-8601=seconds)"
| sudo tee -a /var/lib/fim-lab/change-record.tsv >/dev/null
sudo ssh
-o IdentitiesOnly=yes
-o StrictHostKeyChecking=accept-new
-i /root/.ssh/fimadmin-lab
fimadmin@localhost
"printf '%sn' 'maintenance=true' >> /srv/fim-lab/app.conf"
sleep 5
sudo tail -n 1 /var/lib/fim-lab/change-record.tsv
sudo tail -n 2 /srv/fim-lab/app.conf
IdentitiesOnly=yes împiedică alegerea altei chei din agentul SSH. Sesiunea reală prin sshd permite subsistemului Audit să asocieze operația cu utilizatorul conectat, nu doar cu un proces lansat printr-un sudo intermediar.
Outputul relevant este:
timeout=30
maintenance=true
Pe manager, verifică ultimul eveniment:
sudo jq -c '
select(
.agent.name == "web-01" and
.syscheck.path == "/srv/fim-lab/app.conf"
)
| {
timestamp,
event: .syscheck.event,
user: (.audit.user.name // "necunoscut"),
process: (.audit.process.name // "necunoscut"),
diff: (.syscheck.diff // "fara_diff")
}
' /var/ossec/logs/alerts/alerts.json | tail -n 1
Un exemplu de rezultat este:
{"timestamp":"...","event":"modified","user":"fimadmin","process":"bash","diff":"...maintenance=true..."}
Timestampul, procesul și forma exactă a diferenței pot varia. Criteriile de acceptare sunt utilizatorul fimadmin, calea corectă și conținutul prevăzut în CHG-2026-0926.
Punct de control: dacă lipsește câmpul audit.user.name, nu eticheta evenimentul drept administrativ; verifică Audit și activarea who-data.
Pasul 5 — Generăm o abatere fără înregistrare administrativă
Fișierul este demonstrativ și nu controlează un serviciu real. Comanda următoare adaugă intenționat o schimbare neplanificată pentru a testa trierea:
set -euo pipefail
printf '%sn' 'debug=true'
| sudo tee -a /srv/fim-lab/app.conf >/dev/null
sleep 5
sudo tail -n 3 /srv/fim-lab/app.conf
Pe manager, repetă interogarea pentru ultimele două evenimente:
sudo jq -c '
select(
.agent.name == "web-01" and
.syscheck.path == "/srv/fim-lab/app.conf"
)
| {
timestamp,
user: (.audit.user.name // "necunoscut"),
process: (.audit.process.name // "necunoscut"),
class: (
if .audit.user.name == "fimadmin"
then "CANDIDAT_ADMIN"
else "INVESTIGHEAZA"
end
),
diff: (.syscheck.diff // "fara_diff")
}
' /var/ossec/logs/alerts/alerts.json | tail -n 2
Exemplul trebuie să conțină două clase distincte:
{"user":"fimadmin","class":"CANDIDAT_ADMIN","diff":"...maintenance=true..."}
{"user":"root","class":"INVESTIGHEAZA","diff":"...debug=true..."}
CANDIDAT_ADMIN înseamnă „compară cu registrul și aprobarea”, nu „închide automat alerta”. Un cont dedicat poate fi compromis, iar o schimbare legitimă poate avea un conținut greșit.
Punct de control: dacă ambele evenimente au același utilizator, verifică dacă prima modificare a fost făcută prin sesiunea SSH fimadmin, nu direct din shellul administratorului.
Pasul 6 — Transformăm trierea într-un raport repetabil
Pe manager, creează fișierul complet /usr/local/sbin/fim-triage:
#!/usr/bin/env bash
set -euo pipefail
alerts_file="/var/ossec/logs/alerts/alerts.json"
agent_name="${1:-web-01}"
monitored_path="${2:-/srv/fim-lab/app.conf}"
if [[ ! -r "$alerts_file" ]]; then
printf 'Nu pot citi %s; rulează scriptul cu privilegii administrative.n'
"$alerts_file" >&2
exit 1
fi
printf 'timestamptutilizatortprocestevenimentttrieretdiferentan'
jq -r
--arg agent "$agent_name"
--arg path "$monitored_path" '
select(
.agent.name == $agent and
.syscheck.path == $path
)
| [
.timestamp,
(.audit.user.name // "necunoscut"),
(.audit.process.name // "necunoscut"),
(.syscheck.event // "necunoscut"),
(
if .audit.user.name == "fimadmin"
then "CANDIDAT_ADMIN"
else "INVESTIGHEAZA"
end
),
(
(.syscheck.diff // "fara_diff")
| gsub("n"; "\n")
)
]
| @tsv
' "$alerts_file"
Instalează și execută scriptul:
sudo install -o root -g root -m 0750
/usr/local/sbin/fim-triage
/usr/local/sbin/fim-triage
sudo /usr/local/sbin/fim-triage
web-01
/srv/fim-lab/app.conf
| tail -n 3
Dacă ai creat fișierul direct la destinație, comanda install asupra aceleiași căi nu este necesară; păstrează însă proprietarul root:root și modul 0750.
Raportul trebuie să aibă antetul și cele două evenimente:
timestamp utilizator proces eveniment triere diferenta
... fimadmin ... modified CANDIDAT_ADMIN ...
... root ... modified INVESTIGHEAZA ...
Testul de capăt este îndeplinit numai dacă apar calea monitorizată, două identități diferite și diferențele maintenance=true, respectiv debug=true.
Pentru configurații care conțin certificate sau chei, FIM trebuie corelat cu un proces separat de emitere și rotație, precum cel descris în ghidul despre infrastructura Smallstep CA și rotația automată. Nu activa raportarea diferențelor pe cheia privată.
Cinci defecțiuni care indică exact unde s-a rupt laboratorul
E: Version '4.14.8-1' for 'wazuh-agent' was not found — indexul APT nu a fost actualizat, depozitul nu este accesibil sau versiunea a fost retrasă din canalul curent. Rulează apt-cache policy wazuh-agent; pentru reproducerea acestui tutorial folosește depozitul oficial care încă oferă 4.14.8-1, nu înlocui versiunea fără să verifici compatibilitatea managerului.
ssh: connect to host localhost port 22: Connection refused — sshd nu rulează sau nu ascultă local. Remedierea este:
sudo systemctl enable --now ssh
sudo ss -lnt | grep ':22'
Host key verification failed. — intrarea existentă pentru localhost nu mai corespunde gazdei. Verifică motivul schimbării; numai în acest laborator local, după confirmare, elimină intrarea veche cu sudo ssh-keygen -R localhost -f /root/.ssh/known_hosts, apoi reconectează-te.
Job for wazuh-agent.service failed because the control process exited with error code. — linia XML a ajuns în afara blocului <syscheck> sau configurația a fost deteriorată. Rulează testul, restaurează copia și reia editarea:
sudo /var/ossec/bin/wazuh-syscheckd -t
sudo cp -a /var/ossec/etc/ossec.conf.before-fim-lab
/var/ossec/etc/ossec.conf
sudo systemctl restart wazuh-agent
Raportul nu afișează niciun eveniment, deși fișierul s-a schimbat — o configurație centralizată poate suprascrie configurația locală a aceluiași director. Verifică în manager configurația grupului agentului și confirmă în ossec.log că /srv/fim-lab este monitorizat. Documentația Wazuh precizează prioritatea configurației centralizate.
Dacă abaterea indică un proces pornit de un browser sau de o extensie instalată pe o stație administrativă, investigația FIM trebuie completată pe endpoint; procedura de curățare a extensiilor suspecte fără pierderea parolelor oferă o ordine defensivă pentru acel caz.
Eliminăm laboratorul fără să ștergem istoricul incidentelor
Avertisment: comenzile următoare opresc temporar agentul și elimină contul, cheia și fișierele laboratorului. Nu le executa dacă ai reutilizat aceste căi pentru date reale.
Pe endpoint:
set -euo pipefail
sudo systemctl stop wazuh-agent
if [ -f /var/ossec/etc/ossec.conf.before-fim-lab ]; then
sudo cp -a
/var/ossec/etc/ossec.conf.before-fim-lab
/var/ossec/etc/ossec.conf
sudo rm -f /var/ossec/etc/ossec.conf.before-fim-lab
fi
sudo rm -rf /srv/fim-lab /var/lib/fim-lab
sudo rm -f /root/.ssh/fimadmin-lab /root/.ssh/fimadmin-lab.pub
sudo userdel -r fimadmin 2>/dev/null || true
sudo /var/ossec/bin/wazuh-syscheckd -t
sudo systemctl start wazuh-agent
sudo systemctl is-active wazuh-agent
Pe manager:
sudo rm -f /usr/local/sbin/fim-triage
Alertele istorice rămân în manager până când politica de retenție le elimină. Nu șterge manual alerts.json sau indecșii Wazuh pentru a „curăța” laboratorul.
Bifele care confirmă că trierea este utilizabilă
- ☐ Agentul și managerul rulează Wazuh
4.14.8. - ☐
auditd,sshșiwazuh-agentsunt active. - ☐ Manifestul inițial trece
sha256sum --check. - ☐
/srv/fim-labapare o singură dată în blocul<syscheck>. - ☐ Scanarea inițială FIM s-a încheiat înaintea modificărilor.
- ☐ Schimbarea planificată are contul
fimadmin, înregistrareaCHG-2026-0926și diferența așteptată. - ☐ Schimbarea făcută de
rooteste marcatăINVESTIGHEAZA. - ☐ Lipsa câmpului who-data nu este tratată drept aprobare.
- ☐
report_changesnu este activat pe fișiere cu secrete. - ☐ Nicio alertă nu este închisă automat numai pe baza numelui utilizatorului.
Următorul pas practic este mutarea registrului de schimbări într-un sistem extern de ticketing și corelarea ferestrei aprobate cu timestampul Wazuh. Pentru directoare mari, măsoară volumul de evenimente înainte de extindere și aplică nodiff fișierelor sensibile. Abia după aceste două controale merită transformat CANDIDAT_ADMIN într-o regulă de severitate redusă pe manager.
Întrebări frecvente
De ce nu este suficient hashul SHA-256?
Hashul confirmă că fișierul diferă de baseline, dar nu arată cine l-a modificat și prin ce proces. Who-data completează alerta cu identitatea și procesul observate de subsistemul Audit.
O schimbare făcută de fimadmin este automat legitimă?
Nu. Ea este doar un candidat administrativ și trebuie să corespundă înregistrării schimbării, intervalului aprobat, căii și diferenței de conținut.
Pot folosi report_changes pentru orice fișier?
Nu pentru fișiere care conțin parole, tokenuri sau chei private, deoarece diferența poate ajunge în alertă. Pentru acestea se păstrează monitorizarea integrității și se folosește nodiff.
Ce se întâmplă dacă audit.user.name lipsește?
Evenimentul rămâne în categoria INVESTIGHEAZA. Mai întâi se verifică serviciul auditd, configurația who-data și jurnalul agentului.

















































