Les tres lliçons anteriors han construït prevenció: un model de control d'accés, identitats ben gestionades, un servei confinat i un sistema enfortit. Tot això redueix la probabilitat que passi alguna cosa dolenta i limita el dany si passa. Però cap d'aquestes mesures no respon a la pregunta que de debò angoixa qui administra un servidor en producció: com sé si ha passat alguna cosa?

Imagina l'escenari concret que resoldrem al final d'aquesta lliçó. Són les 09:00 i el monitoratge va avisar de matinada: entre les 03:12 i les 03:40 hi va haver un pic d'escriptures a /var/lib/meteora que multiplica per vint el que és normal a aquella hora, i ara mateix hi ha un procés en execució el nom del qual ningú de l'equip no reconeix. Què fas? El mates? Reinicies el servidor? Desconnectes la xarxa? Mires primer els registres o el procés? Cadascuna d'aquestes decisions, presa en l'ordre equivocat, destrueix informació que no tornarà, i algunes empitjoren l'incident en lloc de contenir-lo.

Aquesta lliçó dona el mètode. Primer, què es registra en un Linux i on: syslog amb les seves facilitats i prioritats, i journald amb els seus filtres —els que faràs servir de debò—. Després, com es dissenya el registre d'una aplicació com ara meteo-api: què ha de contenir cada esdeveniment i, sobretot, què no hi ha d'aparèixer mai, amb l'advertència d'RGPD que correspon. Després la rotació i la retenció, el subsistema auditd del nucli amb el seu cost real en rendiment, i el problema més incòmode de tots: la integritat d'un registre escrit per un sistema que l'atacant controla. Continuem amb la detecció de canvis a l'amfitrió —AIDE, rootkits, indicadors concrets— i acabem amb el cicle de resposta a incidents aplicat pas a pas al cas de les 03:12, amb la preservació d'evidències i les seves implicacions legals.

Contingut

  1. Per què sense registre no hi ha detecció ni resposta
  2. syslog: facilitats, prioritats i /var/log/
  3. journald i journalctl a la pràctica
  4. Disseny del registre d'una aplicació
  5. Rotació i retenció amb logrotate
  6. El subsistema d'auditoria del nucli: auditd
  7. Integritat dels registres davant d'un atacant amb privilegis
  8. Detecció de canvis i intrusos a l'amfitrió
  9. El cicle de resposta a incidents
  10. Cas pràctic: el pic de les 03:12
  11. Preservació d'evidències
  12. Quines mesures preventives deixa cada incident

Per què sense registre no hi ha detecció ni resposta

Els controls de seguretat s'agrupen en tres famílies, i convé veure on encaixa cada cosa que hem après:

Tipus de control Què fa Exemples del mòdul
Preventiu Impedeix que passi Permisos, capabilities, AppArmor, tallafocs, seccomp
Detectiu Avisa que ha passat Registres, auditd, AIDE, monitoratge
Correctiu Repara o conté Còpies de seguretat, aïllament, reinstal·lació

Un sistema amb controls preventius i sense controls detectius té un problema estructural: quan la prevenció falla, ningú no se n'assabenta. I la prevenció falla sempre alguna vegada, perquè el programari té errades, les configuracions es degraden i les persones cometen errors.

Sense registres, quatre coses resulten impossibles, no difícils:

  • Detectar. Un atacant que no trenca res visible pot romandre mesos. La mediana del temps de permanència no detectada en incidents reals es mesura en setmanes, no en hores.
  • Investigar. Sense traça no es pot respondre a les preguntes que importen: què va entrar, quan, per on, què va tocar i què se'n va endur.
  • Contenir amb criteri. Sense saber l'abast, l'única opció és apagar-ho tot, cosa que sol ser desproporcionada i de vegades destrueix l'evidència.
  • Aprendre. Un incident del qual no se'n treu una mesura preventiva concreta es repetirà.

D'aquí la regla de treball d'aquesta lliçó: el registre no és un subproducte del sistema, és un control de seguretat i es dissenya com a tal, amb el seu contingut, la seva retenció, la seva protecció i la seva verificació.

syslog: facilitats, prioritats i /var/log/

syslog és el mecanisme clàssic d'UNIX: un dimoni rep missatges de tots els programes i els classifica per dues dimensions. Continua sent rellevant perquè és el llenguatge comú de la indústria: encaminadors, tallafocs, cabines d'emmagatzematge i col·lectors centralitzats parlen syslog.

Dimensió Valors
Facilitat (d'on ve) kern, user, mail, daemon, auth, authpriv, cron, syslog, lpr, news, uucp, local0local7
Prioritat (què de greu és) emerg(0), alert(1), crit(2), err(3), warning(4), notice(5), info(6), debug(7)

Les que més t'importaran: auth i authpriv recullen tot el relatiu a autenticació i elevació —inicis de sessió, sudo, PAM—, i authpriv és la variant per al que pot contenir dades sensibles, per la qual cosa el seu fitxer té permisos més restrictius. I local0local7 estan reservades per a aplicacions pròpies: meteo-api pot fer servir local3, per exemple, i així se separa de tota la resta sense tocar la resta del sistema.

Fitxer Què conté Per què mirar-lo
/var/log/auth.log Autenticació, sudo, SSH, PAM El primer en qualsevol investigació
/var/log/syslog Tot el general Visió conjunta
/var/log/kern.log Missatges del nucli OOM killer, discos, denegacions d'AppArmor
/var/log/meteora/meteo-api.log El registre de l'aplicació Activitat del servei
/var/log/audit/audit.log Subsistema auditd Auditoria fina (apartat 6)
/var/log/wtmp, btmp, lastlog Sessions correctes, fallides i últim accés Binaris: es llegeixen amb last, lastb, lastlog
# /etc/rsyslog.d/50-meteora.conf
local3.*                       /var/log/meteora/meteo-api.log
auth,authpriv.*                /var/log/auth.log
*.emerg                        :omusrmsg:*
auth,authpriv.*                @@colector.meteora.example:6514   # còpia REMOTA per TLS

Com es llegeix aquella configuració: cada línia és un selector (facilitat.prioritat) seguit d'una destinació. local3.* envia tot el de l'aplicació al seu propi fitxer. *.emerg avisa tots els usuaris connectats de les emergències. I l'última línia és la important per a l'apartat 7: @@ significa enviament per TCP amb TLS a un col·lector remot —amb una sola @ seria UDP, sense garantia de lliurament—, de manera que els esdeveniments d'autenticació existeixen també fora de la màquina. Aquell detall és el que separa un registre que serveix en una investigació d'un que no.

journald i journalctl a la pràctica

En un Debian actual, el registre principal és el diari de systemd: un magatzem binari i indexat en què cada entrada porta camps estructurats a més del text —unitat, PID, UID, executable, prioritat, identificador d'arrencada—, i per això es pot consultar com una petita base de dades.

syslog journald
Format Text pla Binari indexat
Consulta grep, awk journalctl amb filtres per camp
Metadades Les que porti la línia Automàtiques i no falsificables per l'emissor
Persistència Sempre al disc Configurable: volàtil o persistent
Integritat Cap Segellat amb FSS (--setup-keys)
Interoperabilitat Universal Pròpia de systemd (amb reenviament a syslog)

La propietat decisiva és la tercera: journald afegeix les metadades pel seu compte, prenent-les del sistema mateix i no del text del missatge. Un procés no pot mentir sobre el seu PID, el seu UID o la seva unitat, perquè no és ell qui els escriu. A syslog, qualsevol que escrigui al sòcol pot afirmar que és qui vulgui.

# --- Persistència: el PRIMER que cal comprovar ---
sudo mkdir -p /var/log/journal && sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald
journalctl --disk-usage

# --- Filtres essencials ---
journalctl -u meteo-api                    # per unitat
journalctl -u meteo-api -f                 # seguir en directe
journalctl -p err                          # prioritat err o superior
journalctl --since "2026-09-01 03:00" --until "2026-09-01 04:00"
journalctl --since "-2h"                   # les dues últimes hores
journalctl -b                              # només aquesta arrencada
journalctl -b -1                           # l'arrencada ANTERIOR
journalctl _UID=990                        # per camp: tot el de l'usuari meteora
journalctl _COMM=sudo                      # totes les elevacions
journalctl -k -g -i apparmor               # missatges del nucli que casin amb un patró
journalctl -u meteo-api -o json-pretty     # amb TOTS els camps, per automatitzar

Els que marquen la diferència en una investigació. --since i --until acoten la finestra temporal, que és sempre el primer pas: no es llegeix "el log", es llegeix la mitja hora rellevant. -b -1 consulta l'arrencada anterior, imprescindible quan el servidor s'ha reiniciat —o l'han reiniciat— i necessites veure què va passar just abans. Els filtres per camp (_UID=, _COMM=, _PID=) són l'avantatge real del format indexat: journalctl _UID=990 --since "-24h" et dona tot el que va fer la identitat del servei en un dia, sense dependre que el text del missatge contingui la paraula adequada. I -o json-pretty exposa tots els camps, que és el que necessites per enviar a un col·lector o per automatitzar una comprovació.

La comprovació de persistència no és opcional. Sense /var/log/journal, el diari viu a /run, que és tmpfs (04-03): es perd sencer a cada reinici. Un atacant que reiniciï la màquina esborra el registre sense tocar ni un sol fitxer, i tu et quedes investigant un incident del qual no queda res. És de les primeres coses que cal verificar en un servidor acabat d'instal·lar.

I els tres límits de retenció, que cal fixar de manera conscient:

# /etc/systemd/journald.conf
Storage=persistent
SystemMaxUse=2G                # sostre total del diari
SystemMaxFileSize=128M
MaxRetentionSec=90day          # ← la FINESTRA D'INVESTIGACIÓ
ForwardToSyslog=yes            # còpia a rsyslog, i d'allà al col·lector remot

MaxRetentionSec és la decisió de seguretat d'aquest bloc: defineix fins a quan enrere pots investigar. Si un compromís es detecta al cap de sis setmanes —l'habitual— i la teva retenció és de set dies, els registres del moment de l'entrada ja no existeixen i mai no sabràs per on van entrar.

Disseny del registre d'una aplicació

Un registre útil no surt sol: es dissenya. Aquests són els camps que ha de portar cada esdeveniment de meteo-api:

Camp Per què Exemple
Marca de temps amb zona Sense zona, correlacionar amb altres sistemes és impossible 2026-09-01T03:12:07.481+02:00
Esdeveniment Què va passar, en vocabulari tancat auth.fallada, consulta.ok, export.denegat
Identitat Qui ho va fer client_id=CLI-4471
Origen Des d'on origen=203.0.113.45
Objecte Sobre què recurs=/lectures/2026-08-31
Resultat Èxit o fracàs, sempre resultat=denegat
Identificador de correlació Per seguir una petició entre serveis traca=7f3a9c21
Severitat Per filtrar i alertar nivell=warning
import logging, json, uuid
from logging.handlers import SysLogHandler

log = logging.getLogger("meteo-api")
log.addHandler(SysLogHandler(address="/dev/log", facility=SysLogHandler.LOG_LOCAL3))

def registrar(esdeveniment, resultat, **camps):
    log.info(json.dumps({"esdeveniment": esdeveniment, "resultat": resultat, **camps}))

# Al punt de l'aplicació:
traca = uuid.uuid4().hex[:8]
registrar("auth.fallada", "denegat", client="CLI-4471",
          origen=peticio.ip, motiu="token_caducat", traca=traca)

Tres decisions d'aquest codi. El format estructurat (JSON) permet consultar i agregar sense dependre d'expressions regulars fràgils; un col·lector pot filtrar per esdeveniment sense entendre el text. L'identificador de correlació es genera en rebre la petició i acompanya tots els esdeveniments que provoqui, inclosos els de l'ingestor i l'agregador si es propaga: és el que permet reconstruir una petició entre tres serveis. I el motiu de la fallada es registra sempre, perquè "denegat" sense motiu no serveix de res en una investigació.

Què NO ha d'aparèixer mai en un registre

Mai Per què
Contrasenyes, ni tan sols fallides Una fallada sol ser un error de tecleig sobre la contrasenya correcta
Tokens, claus d'API, galetes de sessió Qui llegeixi el registre els pot reutilitzar tal qual
Números de targeta, dades bancàries Prohibit per normativa sectorial
Dades personals innecessàries Minimització: si no cal per operar o investigar, no es registra
Contingut complet de peticions Arrossega tot l'anterior sense voler
Bolcats de memòria al registre Contenen secrets acabats de llegir (05-03)

El cas de les contrasenyes fallides mereix aturar-s'hi. Sembla inofensiu registrar l'intent fallit "per investigar", i és una de les pitjors pràctiques possibles: la majoria de les fallades són errors de tecleig sobre la contrasenya bona, així que el registre acaba contenint, en clar i amb el nom d'usuari al costat, les credencials reals dels teus usuaris. I aquell registre el llegeix tot el grup adm, viatja al col·lector central i entra a les còpies de seguretat.

Amb dades personals, la regla operativa és registrar identificadors, no persones: client=CLI-4471 en lloc del nom i el correu, i una taula a part —amb el seu propi control d'accés— que tradueixi l'identificador quan calgui de debò.

Advertència d'RGPD i compliment normatiu. Una adreça IP, un identificador d'usuari o un historial d'accessos són dades personals en el marc de l'RGPD. Registrar-los exigeix base legal, informació als interessats, minimització, termini de conservació definit i justificat, control d'accés i, quan escaigui, avaluació d'impacte. La retenció de registres entra a més en conflicte habitual amb el dret de supressió, i hi ha obligacions sectorials que imposen terminis mínims. Defineix la política de registre i retenció juntament amb el responsable de compliment normatiu o amb assessoria jurídica, per escrit, abans de desplegar-la, i no la improvisis enmig d'un incident.

Rotació i retenció amb logrotate

Sense rotació, un registre creix fins a omplir el disc, i un /var/log ple atura serveis —inclòs el registre mateix, amb la qual cosa deixes de tenir traça justament quan més falta fa—.

# /etc/logrotate.d/meteora
/var/log/meteora/*.log {
    daily                    # rotar cada dia
    rotate 90                # conservar 90 fitxers = 90 dies de finestra
    compress                 # comprimir els antics (els .log comprimeixen ~10:1)
    delaycompress            # no comprimir el més recent: pot continuar obert
    missingok                # no fallar si encara no existeix
    notifempty               # no rotar un fitxer buit
    create 0640 meteora adm  # el nou neix amb els permisos de 04-06
    dateext                  # noms per data: meteo-api.log-20260901
    sharedscripts
    postrotate
        systemctl reload meteo-api > /dev/null 2>&1 || true
    endscript
}

Les tres directives que causen problemes si s'entenen malament. create 0640 meteora adm és imprescindible: sense ella, el fitxer nou hereta la umask del procés de rotació —que s'executa com a root— i pot quedar amb permisos incorrectes o amb propietari root, i llavors el servei deixa de poder escriure al seu propi registre. postrotate amb reload existeix per una raó que ja coneixes de 04-04: quan logrotate reanomena el fitxer, el procés continua escrivint al mateix inode a través del seu descriptor obert, així que els seus missatges van al fitxer rotat i el nou es queda buit; cal avisar-lo perquè el reobri. L'alternativa és copytruncate, que copia i trunca al lloc, però perd les línies escrites entre la còpia i el truncament, així que només es fa servir quan no hi ha manera d'avisar el procés. I delaycompress evita comprimir un fitxer que encara pot estar obert.

El compromís de la retenció es calcula amb números concrets. meteo-api genera uns 40 MB de registre al dia; noranta dies sense comprimir serien 3,6 GB, i comprimits ronden els 400 MB. La pregunta que decideix el valor no és quant ocupa, sinó fins a quan enrere necessites poder investigar:

Retenció Espai (comprimit) Què permet investigar
7 dies ~30 MB Només incidents detectats immediatament
90 dies ~400 MB Compromís detectat setmanes després: l'habitual
365 dies ~1,6 GB Investigació completa; pot xocar amb la minimització de dades

Noranta dies és un punt de partida raonable per a meteo-01: cobreix el cas realista de detecció tardana sense acumular dades personals durant un any. Però és una decisió que s'ha de validar amb compliment normatiu, perquè pot haver-hi terminis mínims obligatoris o màxims exigits per la minimització.

sudo logrotate -d /etc/logrotate.d/meteora     # simular SENSE fer res
sudo logrotate -f /etc/logrotate.d/meteora     # forçar una rotació de prova

El subsistema d'auditoria del nucli: auditd

journald registra el que els programes decideixen explicar. auditd registra el que passa al nucli, tant si el programa vol com si no: quin procés va obrir quin fitxer, quina crida al sistema es va executar, qui va canviar un permís. És la diferència entre el testimoni del sospitós i l'enregistrament de la càmera.

sudo apt install auditd audispd-plugins
sudo systemctl enable --now auditd
# /etc/audit/rules.d/meteora.rules

## 1. Vigilància sobre fitxers crítics (w = escriptura, a = canvi d'atributs)
-w /etc/meteora/meteora.conf -p wa -k meteora_conf
-w /etc/meteora/secrets.conf -p rwa -k meteora_secrets   # també LECTURA
-w /etc/passwd  -p wa -k identitat
-w /etc/shadow  -p wa -k identitat
-w /etc/sudoers -p wa -k escalada
-w /etc/sudoers.d/ -p wa -k escalada
-w /etc/ssh/sshd_config -p wa -k acces_remot

## 2. Crides al sistema sensibles
-a always,exit -F arch=b64 -S execve -F euid=0 -F auid>=1000 -F auid!=-1 -k root_exec
-a always,exit -F arch=b64 -S mount -S umount2 -k muntatge
-a always,exit -F arch=b64 -S init_module -S finit_module -k moduls
-a always,exit -F arch=b64 -S chmod -S chown -S setxattr -F dir=/var/lib/meteora -k permisos

## 3. Immutabilitat de les regles: NINGÚ no les pot canviar sense reiniciar
-e 2

Cada bloc respon a una necessitat diferent. Les regles -w vigilen rutes: fixa't que secrets.conf porta també r, perquè en un fitxer de claus llegir-lo ja és l'esdeveniment rellevant, no només modificar-lo. Les regles de crides al sistema són més precises: la primera registra tot execve executat amb privilegis de root per algú que va iniciar sessió com a usuari normalauid és l'identificador d'auditoria, que no canvia amb su ni amb sudo i per això permet atribuir l'acció a la persona real—; les següents cobreixen muntatge, càrrega de mòduls i canvis de permisos a l'arbre de dades. I -e 2 fa les regles immutables: a partir d'aquí ni root les pot modificar sense reiniciar la màquina, i un reinici és en si mateix un esdeveniment molt visible.

sudo augenrules --load && sudo auditctl -l          # carregar i verificar
# Consultes
sudo ausearch -k meteora_secrets -i                # -i tradueix UID i crides a noms
sudo ausearch -k escalada --start today -i
sudo ausearch -ua 1001 --start recent -i           # tot el de l'auid 1001 (carlos)
sudo aureport --summary ; sudo aureport --auth --failed -i

ausearch cerca per clau, per usuari d'auditoria, per rang temporal o per procés, i -i és pràcticament obligatori perquè tradueix els números a noms llegibles. aureport genera resums: el d'autenticacions fallides és dels més útils per a una revisió diària.

El cost en rendiment és real i cal dimensionar-lo. Cada esdeveniment auditat suposa feina al nucli i una escriptura al disc, i una regla mal pensada pot degradar el sistema notablement. La regla perillosa per excel·lència és auditar totes les lectures i escriptures d'un arbre actiu: l'ingestor escriu 720.000 lectures al dia a /var/lib/meteora/lectures, així que una regla -S read -S write sobre aquell directori generaria milions d'esdeveniments diaris, ompliria el disc en hores i afegiria latència a cada operació. El criteri correcte és auditar el que és rar, no el que és freqüent: canvis de configuració, accessos a secrets, elevacions de privilegi, càrrega de mòduls, muntatges. I comprovar el volum amb aureport --summary durant els primers dies per ajustar.

Integritat dels registres davant d'un atacant amb privilegis

Arribem al problema més incòmode, i el que cal tenir clar abans que cap altre:

Un atacant amb root a meteo-01 pot modificar o esborrar qualsevol registre local. Pot editar /var/log/auth.log, purgar el diari, aturar auditd, treure un chattr +a amb CAP_LINUX_IMMUTABLE i reescriure la història. Un registre local mai no és prova suficient de res.

Això no vol dir que les defenses locals siguin inútils; vol dir que cal entendre què aporta cadascuna.

Defensa Què aporta Què no aporta
chattr +a (04-06) Impedeix truncar i modificar; només s'hi pot afegir Root pot treure l'atribut. Evita accidents i obliga a un pas deliberat
Permisos 0640 meteora:adm Impedeix lectura i escriptura per altres usuaris Res davant de root
Segellat FSS de journald Detecta manipulació a posteriori amb una clau externa No la impedeix
Enviament remot immediat L'esdeveniment ja és fora abans que el puguin esborrar Si l'enviament és per lots, es perd la finestra
Col·lector amb credencials pròpies El servidor no pot esborrar el que ja s'ha enviat Requereix infraestructura separada
# 1. Només-afegir als registres locals
sudo chattr +a /var/log/meteora/meteo-api.log /var/log/auth.log

# 2. Segellat criptogràfic del diari (guarda la clau FORA de la màquina)
sudo journalctl --setup-keys --interval=1h
sudo journalctl --verify        # detecta si el diari ha estat manipulat

# 3. Enviament immediat al col·lector, per TCP amb TLS
#    /etc/rsyslog.d/60-remot.conf
#    *.* action(type="omfwd" target="colector.meteora.example" port="6514"
#               protocol="tcp" StreamDriverMode="1" StreamDriverAuthMode="x509/name"
#               queue.type="LinkedList" queue.saveOnShutdown="on"
#               action.resumeRetryCount="-1")

La configuració d'enviament remot té quatre decisions importants. TCP amb TLS garanteix lliurament i confidencialitat, davant d'UDP que perd missatges en silenci justament quan hi ha saturació —que és quan passen els incidents—. StreamDriverAuthMode="x509/name" fa que l'emissor verifiqui la identitat del col·lector, perquè ningú no el pugui suplantar i absorbir els teus registres. La cua al disc amb saveOnShutdown evita perdre esdeveniments si el col·lector no està disponible una estona. I resumeRetryCount="-1" reintenta indefinidament.

I les tres propietats que ha de complir el col·lector perquè tot això valgui:

Credencials separades. meteo-01 ha de poder enviar esdeveniments i no poder-los llegir ni esborrar. Si el certificat del servidor permetés administrar el col·lector, un atacant amb root a meteo-01 esborraria també la còpia remota, i no hauríem guanyat res.

Escriptura immediata i de només afegir a la destinació. El valor de l'enviament remot és que l'esdeveniment surt en el moment, abans que ningú el pugui esborrar; un enviament per lots cada quinze minuts deixa una finestra de quinze minuts perfectament aprofitable.

Retenció independent. El termini el fixa el col·lector, no el servidor d'origen.

La idea de fons, que convé formular explícitament: l'evidència ha de sortir de l'abast de l'atacant tan aviat com sigui possible. És el mateix raonament que les còpies immutables de 05-03 i, per cert, la raó per la qual a l'apartat 11 la còpia de la memòria es fa abans de tocar res.

Detecció de canvis i intrusos a l'amfitrió

Comprovació d'integritat de fitxers amb AIDE

AIDE calcula una base de referència amb les sumes de verificació, permisos, propietaris i temps de tots els fitxers que li indiquis, i després compara periòdicament contra ella. Detecta exactament el que un atacant necessita fer per persistir: modificar un binari, afegir una unitat de systemd, tocar la configuració.

# /etc/aide/aide.conf (extracte)
Binari = p+i+n+u+g+s+m+c+md5+sha256       # tot, incloses les sumes
Config  = p+i+n+u+g+s+m+c+sha256
Registre = p+u+g+n+S                       # els logs CREIXEN: no en vigilis la mida

/usr/bin        Binari
/usr/sbin       Binari
/etc            Config
/etc/meteora    Config
/var/log/meteora Registre
!/var/lib/meteora/lectures                 # els .dat canvien sense parar: EXCLOURE
!/var/log/journal
sudo aideinit                                   # crear la base de referència
sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db
sudo aide --check                               # comparar

Dues decisions són les que fan que AIDE funcioni o es converteixi en soroll inútil. Les regles per tipus de fitxer: a un binari se li vigila tot, però a un registre que creix cada segon no se li pot vigilar la mida ni la suma, només permisos i propietari —d'aquí la regla Registre amb S, que tolera el creixement però detecta un truncament—. I les exclusions: /var/lib/meteora/lectures canvia constantment per disseny, així que incloure-ho generaria milers de diferències diàries i ningú no tornaria a llegir l'informe.

I el punt crític: la base de referència s'ha de guardar fora de la màquina, o almenys en un mitjà de només lectura. Si viu a /var/lib/aide/aide.db i l'atacant té root, l'actualitza després de fer els seus canvis i AIDE informarà que tot està en ordre. El mateix val per a les llistes de referència de setuid i capabilities de 05-02.

Detecció de rootkits i indicadors de compromís

sudo apt install rkhunter chkrootkit
sudo rkhunter --update && sudo rkhunter --check --skip-keypress
sudo debsums -c                    # fitxers de paquets ALTERATS
sudo dpkg --verify                 # equivalent, integrat a dpkg

Aquestes eines comparen binaris contra sumes conegudes i busquen patrons habituals. Són útils i tenen un límit que cal conèixer: si el compromís és al nucli, les respostes del sistema no són fiables, incloses les que reben aquestes eines. Serveixen per al que és freqüent, no per al que és sofisticat.

Els indicadors que es busquen a mà, amb l'ordre i per què és sospitós:

# 1. Processos SENSE binari al disc (l'executable es va esborrar després d'arrencar)
sudo ls -l /proc/*/exe 2>/dev/null | grep -i deleted

# 2. Ports a l'escolta no previstos i connexions establertes
sudo ss -tulnp ; sudo ss -tp state established

# 3. Fitxers setuid o amb capabilities NOUS (05-02)
sudo find / -xdev -perm -4000 -type f 2>/dev/null | sort | diff /root/ref/suid.ref -
sudo getcap -r / 2>/dev/null | sort | diff /root/ref/caps.ref -

# 4. Tasques programades i unitats desconegudes
sudo ls -la /etc/cron.* /var/spool/cron/crontabs/ ; systemctl list-timers --all
systemctl list-unit-files --state=enabled | grep -v '@'

# 5. Fitxers modificats recentment en rutes de sistema
sudo find /etc /usr/bin /usr/sbin -newermt '-3 days' -type f -ls 2>/dev/null

# 6. Claus SSH afegides
sudo find /home /root -name authorized_keys -newermt '-30 days' -ls

El primer mereix explicació perquè és el més revelador de tots: (deleted) a /proc/<pid>/exe significa que el programa s'està executant però el seu fitxer ja no existeix al disc. És una tècnica d'evasió clàssica —s'executa el binari i s'esborra tot seguit, de manera que cap anàlisi del sistema de fitxers no el troba—, i encara que té explicacions legítimes (un binari actualitzat mentre el procés vell continua viu, exactament el cas de 04-02), en un servidor estable és una anomalia que cal explicar. I té una conseqüència forense preciosa que farem servir a l'apartat 11: el fitxer continua existint mentre el procés visqui, perquè el seu comptador d'enllaços no ha arribat a zero, i es pot recuperar copiant /proc/<pid>/exe.

Correlació centralitzada

Un sol servidor produeix esdeveniments; una organització en produeix milions, repartits entre servidors, tallafocs, aplicacions i serveis al núvol. La correlació centralitzada —el que es coneix genèricament com a SIEM, sense entrar en producte— fa tres coses que cap amfitrió no pot fer sol: normalitza formats diferents a un esquema comú, correlaciona esdeveniments de fonts diferents —"un accés SSH correcte des d'una IP que el tallafocs va veure escanejant fa deu minuts"—, i alerta sobre patrons definits. Requereix l'enviament remot de l'apartat 7 i una disciplina de noms d'esdeveniment com la de l'apartat 4; sense aquestes dues coses, és un magatzem car de text que ningú no consulta.

El cicle de resposta a incidents

Un incident es gestiona amb un mètode, no improvisant. Les sis fases són les mateixes en tots els marcs de referència:

graph LR
    A["1. PREPARACIÓ<br/>Abans que passi"] --> B["2. DETECCIÓ<br/>I ANÀLISI<br/>Què passa?"]
    B --> C["3. CONTENCIÓ<br/>Frenar sense destruir"]
    C --> D["4. ERADICACIÓ<br/>Treure la causa"]
    D --> E["5. RECUPERACIÓ<br/>Tornar al servei"]
    E --> F["6. LLIÇONS<br/>APRESES"]
    F -.millora.-> A
Fase Què es fa Error típic
1. Preparació Registre, còpies, contactes, procediment escrit, pràctica No tenir-la: improvisar sota pressió
2. Detecció i anàlisi Confirmar, delimitar l'abast, preservar evidència Actuar abans d'entendre; destruir l'evidència
3. Contenció Frenar el dany sense destruir la informació Apagar el servidor immediatament
4. Eradicació Eliminar la causa arrel, no només el símptoma Matar el procés i donar-ho per tancat
5. Recuperació Restaurar servei i vigilar de prop Tornar a producció sense saber si continua a dins
6. Lliçons apreses Mesures preventives concretes, amb responsable i data Un document que ningú no llegeix

Els dos errors que més dany fan són de la fase 3, i convé entendre'ls abans del cas pràctic. Apagar el servidor destrueix tota la memòria volàtil: processos, connexions, claus de xifratge a la RAM i el contingut dels binaris esborrats que només existeixen a través de /proc. I matar el procés sospitós sense més elimina l'evidència i no resol res, perquè si hi ha un mecanisme de persistència —una tasca programada, una unitat de systemd, una clau SSH— el procés tornarà en minuts i hauràs perdut l'oportunitat d'observar-lo.

Cas pràctic: el pic de les 03:12

Situació. Són les 09:00 de l'1 de setembre de 2026. El monitoratge va avisar d'un pic d'escriptures a /var/lib/meteora entre les 03:12 i les 03:40, vint vegades el que és normal a aquella hora. Hi ha un procés anomenat kworkerd que ningú de l'equip no reconeix.

Fase 2: detecció i anàlisi (sense tocar res)

# 1. FOTOGRAFIA DE L'ESTAT VOLÀTIL — primer, perquè és el que abans desapareix
ps auxf > /tmp/ev/ps.txt ; ss -tunap > /tmp/ev/xarxa.txt
sudo lsof -n > /tmp/ev/lsof.txt ; date -Iseconds > /tmp/ev/hora.txt

# 2. EL PROCÉS: què és i d'on ve
pgrep -a kworkerd                                   # PID i línia d'ordres
sudo ls -l /proc/<PID>/exe                          # el binari existeix?
#   /proc/4471/exe -> /var/tmp/.cache/kworkerd (deleted)   ← ESBORRAT
sudo cat /proc/<PID>/environ | tr '\0' '\n'         # entorn
sudo ls -l /proc/<PID>/cwd ; sudo cat /proc/<PID>/status | grep -E 'Uid|PPid'
#   Uid: 990 990 990 990    ← s'executa com a meteora
#   PPid: 1                 ← el seu pare va morir: va ser "adoptat" per init (02-01)

# 3. RECUPERAR EL BINARI abans que el procés mori
sudo cp /proc/<PID>/exe /tmp/ev/binari-recuperat
sha256sum /tmp/ev/binari-recuperat > /tmp/ev/binari.sha256

# 4. LA FINESTRA TEMPORAL als registres
journalctl --since "2026-09-01 02:30" --until "2026-09-01 04:30" > /tmp/ev/journal.txt
sudo ausearch --start 09/01/2026 02:30:00 --end 09/01/2026 04:30:00 -i > /tmp/ev/audit.txt
sudo grep -E 'sshd|sudo|su\[' /var/log/auth.log | sed -n '/Sep  1 02:/,/Sep  1 05:/p'
last -F | head -20 ; sudo lastb -F | head -20      # sessions correctes i FALLIDES

Com es llegeix el que s'ha obtingut, i per què en aquest ordre. La fotografia de l'estat volàtil va primer per l'ordre de volatilitat de l'apartat següent: processos i connexions desapareixen tan bon punt canviï alguna cosa, mentre que els fitxers continuaran allà d'aquí a una hora. El (deleted) a /proc/<PID>/exe confirma la tècnica d'evasió de l'apartat 8, i el PPid: 1 indica que el procés pare ja va morir, cosa que sol significar que va ser llançat i abandonat deliberadament. L'Uid: 990 és la informació més valuosa de tot el bloc: el procés s'executa com a meteora, no com a root, així que el vector és gairebé segur meteo-api o l'ingestor, i el confinament de 05-03 ens diu immediatament fins on ha pogut arribar. I la còpia del binari des de /proc cal fer-la ja: si el procés mor, l'inode s'allibera i el binari desapareix per sempre.

# 5. QUÈ VA ESCRIURE? Correlacionar amb els fitxers de dades
ls -la --time-style=full-iso /var/lib/meteora/lectures/ | head -20
sudo find /var/lib/meteora -newermt '2026-09-01 03:00' ! -newermt '2026-09-01 04:00' -ls
sudo ausearch -k meteora_secrets --start 09/01/2026 -i       # va llegir les claus?
sudo ausearch -k escalada --start 09/01/2026 -i              # va intentar pujar a root?

# 6. HI HA PERSISTÈNCIA?
sudo find / -xdev -perm -4000 -type f 2>/dev/null | sort | diff /root/ref/suid.ref -
systemctl list-unit-files --state=enabled | diff /root/ref/units.ref -
sudo ls -la /etc/cron.* /var/spool/cron/crontabs/
sudo find /home /root -name authorized_keys -newermt '-7 days' -ls
sudo aide --check | head -40

Troballes del cas. El procés s'executa com a meteora des d'un binari esborrat a /var/tmp/.cache/. auditd mostra que a les 03:11:58 hi va haver un execve des de l'arbre de processos de meteo-api, un minut abans del pic. No hi ha esdeveniments a meteora_secrets, així que no va arribar a llegir les claus d'API. No hi ha esdeveniments a escalada, i NoNewPrivileges=yes explica per què. I aide --check no marca canvis a /usr/bin ni a /etc: el confinament de l'apartat 9 de 05-03 va impedir escriure fora de les rutes declarades. La persistència es limita a una entrada de cron de l'usuari meteora que rellança el binari cada hora.

Fase 3: contenció (frenar sense destruir)

# a) AÏLLAR LA XARXA sense apagar: manté la memòria i els processos vius
sudo nft insert rule inet filter sortida ip daddr != 10.0.1.0/24 drop
# b) CONGELAR el procés en lloc de matar-lo: deixa d'actuar i continua inspeccionable
sudo kill -STOP <PID>
# c) Tallar la persistència
sudo crontab -l -u meteora > /tmp/ev/cron-meteora.txt && sudo crontab -r -u meteora
# d) Preservar les dades ABANS de qualsevol neteja
sudo cp -a --preserve=all /var/lib/meteora /mnt/evidencia/

Les quatre decisions, amb el seu perquè. Aïllar la xarxa en lloc d'apagar atura l'exfiltració i el comandament a distància conservant tot l'estat volàtil, que és l'evidència més valuosa i la primera a perdre's. kill -STOP en lloc de kill -9: el procés deixa d'executar-se però continua existint, amb la seva memòria, els seus descriptors oberts i el seu /proc/<PID>/exe intactes i disponibles per a l'anàlisi. Tallar la persistència abans que res més, perquè si no tornarà en menys d'una hora. I copiar les dades amb -a --preserve=all per conservar permisos, ACL i marques de temps (04-06), que formen part de l'evidència.

Fases 4 a 6

Eradicació. No n'hi ha prou d'esborrar el binari: cal trobar com va entrar. L'execve a les 03:11:58 des de l'arbre de meteo-api apunta a l'aplicació; amb l'identificador de correlació de l'apartat 4 es localitza la petició concreta que el va provocar i s'identifica l'errada. Es corregeix, s'actualitzen les dependències, i es roten totes les credencials que el procés podia llegir —encara que auditd digui que no les va llegir, perquè l'absència d'un esdeveniment és una prova més feble que la seva presència—.

Recuperació. Restaurar les dades afectades des de la còpia (05-03) verificant les sumes, tornar a posar el servei en producció, i mantenir vigilància reforçada durant setmanes: alertes específiques sobre execve de meteora, sobre escriptures fora d'horari i sobre connexions sortints noves. Si hi hagués hagut qualsevol indici de compromís del nucli o d'accés a root, l'única opció defensable seria reinstal·lar des de zero, perquè en un sistema amb el nucli compromès no es pot confiar en res del que el sistema diu de si mateix.

Lliçons apreses. Una reunió sense buscar culpables, amb una taula de mesures concretes, cadascuna amb responsable i data. Per a aquest cas: noexec a /var/tmp (que hauria impedit executar el binari), SystemCallFilter sense execve a la unitat de meteo-api (que hauria impedit llançar-lo), revisió del codi d'anàlisi de peticions, alerta automàtica sobre execve amb _UID=990, i cron deshabilitat per als comptes de servei.

Preservació d'evidències

Si l'incident pot tenir conseqüències legals —denúncia, assegurança, reclamació laboral, notificació a l'autoritat de protecció de dades—, la manera de recollir l'evidència determina si servirà d'alguna cosa.

L'ordre de volatilitat dicta la seqüència de recollida, del més efímer al més durador:

Ordre Què Es perd quan
1 Registres i memòries cau de la CPU A l'instant
2 Memòria RAM: processos, connexions, claus, binaris esborrats En apagar
3 Estat de xarxa: connexions, taula ARP En minuts
4 Processos en execució En acabar o en reiniciar
5 Sistemes de fitxers temporals (/tmp, /run, /dev/shm) En reiniciar (04-03)
6 Disc Persisteix
7 Còpies de seguretat i registres remots Persisteix fora de l'abast de l'atacant

Per què no apagar sense pensar. Un reinici destrueix els nivells 1 a 5 d'aquella taula: tota la memòria, les connexions actives, les claus de xifratge que només existien a la RAM, el contingut de /tmp i /dev/shm —inclòs /dev/shm/meteora-cache— i els binaris esborrats que només eren accessibles a través de /proc. És, amb diferència, la manera més ràpida de perdre la meitat de la investigació. Apagar només es justifica si el dany en curs és més gran que el valor de l'evidència; en la majoria dels casos, aïllar la xarxa conté igual de bé i ho conserva tot.

# Bolcat de memòria (requereix eina específica, p. ex. LiME) — ABANS de res
# Imatge del disc: bit a bit, amb verificació, i treballant sempre sobre la CÒPIA
sudo dd if=/dev/sda of=/mnt/evidencia/meteo01-sda.img bs=4M status=progress conv=noerror
sha256sum /mnt/evidencia/meteo01-sda.img | tee /mnt/evidencia/meteo01-sda.sha256

La suma de verificació és el que dona valor a la imatge: es calcula en copiar i es torna a calcular després, i si coincideix demostra que la imatge no s'ha alterat des de la seva obtenció. L'anàlisi es fa sempre sobre una còpia de treball, muntada en només lectura, mai sobre l'original ni sobre el sistema afectat.

Cadena de custòdia. És el registre documental de qui ha tingut l'evidència en cada moment, i sense ella una prova tècnicament impecable pot ser inadmissible. Ha d'anotar, per a cada element: què és i d'on va sortir, qui el va obtenir i quan (amb zona horària), la seva suma de verificació, on es guarda, i cada transferència amb data, persones i motiu. Amb accés restringit i sense buits.

Advertència legal, i és important. Un incident de seguretat pot comportar obligacions formals amb termini: en el marc de l'RGPD, una bretxa que afecti dades personals exigeix notificar-ho a l'autoritat de control en un termini molt breu, i en certs casos també a les persones afectades. Pot haver-hi a més obligacions sectorials, contractuals i amb l'asseguradora. Tan bon punt se sospiti d'una bretxa amb dades personals, involucra immediatament l'assessoria jurídica i el responsable de protecció de dades, i valora amb ells la denúncia davant de les autoritats competents. No esborris res, no negociïs amb un atacant pel teu compte i no facis públiques conclusions abans de tenir-les confirmades. Les decisions sobre notificació, conservació d'evidències i comunicació no són decisions tècniques.

Quines mesures preventives deixa cada incident

Un incident que no produeix mesures concretes és un incident que es repetirà. Aquesta és la traducció del cas de les 03:12, i serveix de model per a qualsevol altre:

Troballa de l'incident Mesura preventiva On s'implementa
Binari executat des de /var/tmp noexec a /var/tmp, /tmp i /dev/shm /etc/fstab (05-03)
meteo-api va poder llançar un procés SystemCallFilter sense execve; AppArmor sense regles d'execució Unitat de systemd (05-01, 05-03)
Persistència via cron de meteora cron deshabilitat per a comptes de servei /etc/cron.deny
Ningú no ho va detectar fins a les 09:00 Alerta automàtica sobre execve amb _UID=990 Col·lector i regles d'alerta
El binari estava esborrat Alerta sobre processos amb exe (deleted) Comprovació periòdica
L'errada era al codi Revisió, sanitizers i actualització de dependències Integració contínua (05-03)
La investigació va ser lenta Procediment escrit i assajat Fase de preparació

Fixa't en el patró: la majoria de les mesures són directives de configuració que ja coneixies. La diferència entre saber-les i tenir-les aplicades és exactament el que separa un incident contingut d'un compromís complet.

Errors Habituals i Consells

No comprovar que el diari és persistent. Sense /var/log/journal, journald guarda a tmpfs i es perd tot en reiniciar. Un atacant que reiniciï esborra el registre sense tocar cap fitxer. Verifica-ho a cada servidor nou.

Registrar contrasenyes o tokens "per depurar". Les fallades de contrasenya solen ser errors de tecleig sobre la bona, així que el registre acaba contenint les credencials reals en clar, llegibles pel grup adm, replicades al col·lector i presents a les còpies.

Retenir set dies. Un compromís es detecta setmanes després. Amb set dies de retenció, els registres del moment de l'entrada ja no existeixen i mai no sabràs per on van entrar.

Confiar en el registre local després d'un compromís. Un atacant amb root el modifica. Envia els esdeveniments a un col·lector amb credencials diferents i en el moment, no per lots.

Auditar massa amb auditd. Una regla sobre lectures i escriptures de /var/lib/meteora generaria milions d'esdeveniments diaris, ompliria el disc i afegiria latència. Audita el que és rar, no el que és freqüent, i mesura amb aureport --summary.

Apagar el servidor en detectar un incident. Destrueix la memòria, les connexions, /tmp i els binaris esborrats accessibles només per /proc. Aïlla la xarxa en el seu lloc.

Matar el procés sospitós. Elimina l'evidència i no resol res: si hi ha persistència, torna en minuts. Fes servir kill -STOP i busca el mecanisme de persistència.

Guardar la base de referència d'AIDE a la màquina mateixa. Un atacant amb root la regenera després dels seus canvis i l'informe sortirà net. El mateix amb les llistes de setuid i capabilities.

Oblidar create a logrotate. El fitxer nou pot néixer amb propietari o permisos incorrectes, i el servei deixa de poder escriure el seu propi registre. I sense postrotate amb reload, el procés continua escrivint a l'inode antic.

Consell: assaja la resposta abans de necessitar-la. Un simulacre anual de dues hores —"apareix un procés desconegut, què fem i en quin ordre?"— revela que falten els telèfons, que ningú no sap on són les còpies i que la retenció és de set dies. Descobrir això en un simulacre costa un matí; descobrir-ho en un incident real costa moltíssim més.

Exercicis

Exercici 1: auditar el teu propi sistema de registre

Sobre una màquina pròpia o virtual: (a) comprova si el diari és persistent i quina és la seva retenció real, i corregeix-ho si escau; (b) localitza els cinc últims intents fallits d'autenticació i els cinc últims usos de sudo, indicant l'ordre feta servir en cada cas; (c) escriu tres consultes de journalctl que facin servir filtres per camp en lloc de grep, i explica quin avantatge té cadascuna; (d) calcula quant espai ocuparia retenir 90 dies dels teus registres actuals i decideix una política de retenció justificada, indicant quins aspectes consultaries amb compliment normatiu.

Exercici 2: dissenyar el registre i l'auditoria de Meteora

Dissenya el sistema de registre complet del servei: (a) els esdeveniments que meteo-api ha de registrar, amb els seus camps, en format estructurat, i almenys tres que no ha de registrar mai, amb la raó; (b) el fitxer de logrotate per a /var/log/meteora/, justificant cada directiva; (c) cinc regles d'auditd per a meteo-01, explicant què detecta cadascuna i per què no has inclòs una regla sobre les escriptures de /var/lib/meteora/lectures; i (d) l'esquema de protecció de la integritat dels registres, explicant què aporta i què no aporta cada capa davant d'un atacant que ha obtingut root.

Exercici 3: resposta a un incident

A les 08:15 detectes: meteo-api reiniciant-se en bucle cada pocs minuts; /var/lib/meteora al 98 % d'ocupació quan ahir era al 60 %; un fitxer /var/lib/meteora/lectures/README_RECOVER.txt; i els .dat dels últims tres dies amb extensió .dat.locked. Redacta el pla d'actuació complet per fases, amb les ordres exactes en l'ordre correcte i la justificació de cada decisió. Indica expressament: què no has de fer i per què; quines evidències preserves i en quin ordre; quan i per què involucres l'assessoria jurídica; i les cinc mesures preventives que deixaria aquest incident.

Solucions

Solució 1

# (a) Persistència i retenció
ls -ld /var/log/journal 2>/dev/null || echo "VOLÀTIL: es perd en reiniciar"
journalctl --disk-usage ; journalctl --header | grep -i -A2 'sequential\|boot'
journalctl | head -1        # data de l'entrada MÉS ANTIGA = retenció real
sudo mkdir -p /var/log/journal && sudo systemctl restart systemd-journald  # corregir

# (b) Autenticació fallida i elevacions
sudo journalctl _COMM=sshd -p warning -n 20
sudo lastb -F | head -5
sudo journalctl _COMM=sudo -n 5 -o short-full

# (c) Tres consultes per CAMP
journalctl _UID=990 --since "-24h"          # tot el fet per la identitat del servei
journalctl _SYSTEMD_UNIT=ssh.service -p err # errors d'una unitat concreta
journalctl _COMM=sudo _UID=1001             # elevacions d'un usuari concret

(a) La retenció real no és la configurada, sinó la que resulta dels sostres d'espai: si SystemMaxUse s'assoleix abans que MaxRetentionSec, journald esborra el que és antic i la finestra efectiva és menor del que et penses. Per això la comprovació vàlida és mirar la data de l'entrada més antiga, no el fitxer de configuració.

(c) L'avantatge dels filtres per camp sobre grep és doble. Són precisos: _UID=990 selecciona els esdeveniments que el nucli atribueix a aquell UID, mentre que grep 990 casaria també amb un 990 que aparegués en un missatge qualsevol. I són no falsificables: els camps amb guió baix els afegeix journald prenent-los del sistema, no del text de l'emissor, així que un procés no pot mentir sobre el seu UID o la seva unitat, cosa que sí que pot fer amb el contingut del missatge.

(d) El càlcul és journalctl --disk-usage dividit pels dies de retenció actual, multiplicat per 90. La decisió ha d'equilibrar la finestra d'investigació —90 dies cobreix el cas realista de detecció tardana— amb la minimització de dades, perquè els registres contenen IP i identificadors d'usuari, que són dades personals. Amb compliment normatiu cal consultar: la base legal del tractament, el termini màxim justificable, si hi ha terminis mínims obligatoris al sector, com s'atenen els drets d'accés i supressió sobre els registres, i qui els pot llegir.

Solució 2

(a) Esdeveniments de meteo-api:

{"ts":"2026-09-01T03:12:07.481+02:00","esdeveniment":"auth.fallada","resultat":"denegat",
 "client":"CLI-4471","origen":"203.0.113.45","motiu":"token_caducat","traca":"7f3a9c21"}
{"ts":"2026-09-01T03:12:09.112+02:00","esdeveniment":"consulta.ok","resultat":"exit",
 "client":"CLI-2210","recurs":"/lectures/2026-08-31","files":720000,"ms":184,"traca":"9a1b4e77"}
{"ts":"2026-09-01T03:12:11.004+02:00","esdeveniment":"config.recarrega","resultat":"exit",
 "actor":"uid=990","fitxer":"/etc/meteora/meteora.conf","traca":"c2d8f013"}

Registrar sempre: autenticacions (amb èxit i amb fracàs, amb el seu motiu), accessos a dades amb el recurs i el volum, canvis de configuració, arrencades i aturades, i errors amb context suficient per reproduir-los.

Mai, amb la raó: contrasenyes, incloses les fallides, perquè la majoria de les fallades són errors de tecleig sobre la contrasenya correcta i el registre acabaria contenint credencials reals en clar; tokens i claus d'API, perquè qui llegeixi el registre els pot reutilitzar directament —i el registre el llegeix el grup adm, viatja al col·lector i entra a les còpies—; i dades personals innecessàries com ara el nom i el correu del client, que se substitueixen per l'identificador CLI-4471 i una taula de traducció amb el seu propi control d'accés, aplicant el principi de minimització.

(b) El fitxer de logrotate és el de l'apartat 5. Justificació per directiva: daily + rotate 90 fixa la finestra d'investigació en 90 dies; compress redueix ~10:1 l'espai dels .log; delaycompress evita comprimir un fitxer que encara pot estar obert; create 0640 meteora adm és imprescindible perquè sense ella el fitxer nou pot néixer amb propietari root i el servei deixaria de poder escriure; i postrotate amb reload existeix perquè després de reanomenar, el procés continua escrivint al mateix inode pel seu descriptor obert (04-04), de manera que sense avisar-lo el fitxer nou es queda buit.

(c) Cinc regles i què detecta cadascuna:

-w /etc/meteora/secrets.conf -p rwa -k meteora_secrets    # 1. LECTURA de les claus
-w /etc/sudoers.d/ -p wa -k escalada                      # 2. regles de sudo noves
-a always,exit -F arch=b64 -S execve -F euid=990 -k meteora_exec   # 3. execucions del servei
-a always,exit -F arch=b64 -S init_module -S finit_module -k moduls  # 4. mòduls del nucli
-w /root/.ssh/ -p wa -k persistencia                      # 5. claus SSH de root
-e 2

(1) detecta l'accés als secrets, i porta r perquè en un fitxer de claus llegir-lo ja és l'esdeveniment. (2) detecta la concessió de privilegis nous. (3) és la que hauria detectat l'incident de les 03:12 en el moment, perquè meteo-api no ha d'executar res. (4) detecta el pas previ a un rootkit de nucli. (5) detecta una de les persistències més habituals.

No hi incloc una regla sobre les escriptures de /var/lib/meteora/lectures perquè l'ingestor escriu 720.000 lectures diàries: generaria milions d'esdeveniments al dia, ompliria el disc en hores i afegiria latència a la ruta crítica del servei, amb un valor de detecció pràcticament nul, ja que aquelles escriptures són el funcionament normal. El criteri és auditar el que és rar, no el que és freqüent.

(d) Integritat dels registres:

Capa Què aporta Què NO aporta
chattr +a Impedeix truncar i modificar; obliga a un pas deliberat i auditable Root ho pot treure amb CAP_LINUX_IMMUTABLE
Permisos 0640 meteora:adm Aïlla de la resta d'usuaris i serveis Res davant de root
Segellat FSS Detecta manipulació amb una clau guardada fora No la impedeix
Enviament remot immediat per TLS L'esdeveniment ja és fora de l'abast de l'atacant Requereix col·lector; si va per lots, deixa finestra
Credencials de només enviament El servidor no pot esborrar el que ja s'ha enviat Requereix infraestructura separada

La conclusió que ordena la taula: només l'última fila protegeix de debò davant d'un atacant amb root, i les anteriors tenen valor real contra accidents, contra usuaris sense privilegis i per detectar la manipulació a posteriori.

Solució 3

El que NO has de fer, i per què. No apagar ni reiniciar: destruiria la memòria, les connexions, /tmp i /dev/shm, i amb elles possibles claus de xifratge a la RAM que en alguns casos de segrest de dades permeten recuperar les dades sense pagar. No esborrar els fitxers xifrats: són evidència i de vegades són recuperables. No restaurar la còpia de seguretat immediatament sobre el mateix sistema: si l'atacant continua a dins, xifrarà també el que s'hagi restaurat. No pagar ni negociar per iniciativa pròpia: és una decisió de direcció amb implicacions legals. I no matar el procés abans d'haver-lo documentat.

# --- FASE 2: anàlisi i preservació, per ordre de volatilitat ---
mkdir -p /tmp/ev && date -Iseconds > /tmp/ev/hora.txt
ps auxf > /tmp/ev/ps.txt ; ss -tunap > /tmp/ev/xarxa.txt ; sudo lsof -n > /tmp/ev/lsof.txt
cat /var/lib/meteora/lectures/README_RECOVER.txt | tee /tmp/ev/nota.txt   # només LLEGIR
sudo find /var/lib/meteora -name '*.locked' -newermt '-24 hours' -ls > /tmp/ev/xifrats.txt
sudo journalctl --since "-24h" > /tmp/ev/journal.txt
sudo ausearch --start recent -i > /tmp/ev/audit.txt
sudo grep -E 'sshd|sudo' /var/log/auth.log > /tmp/ev/auth.txt
df -h ; sudo du -sh /var/lib/meteora/*        # el 98 % explica el bucle de reinicis

# --- FASE 3: contenció sense destruir ---
sudo nft insert rule inet filter sortida ip daddr != 10.0.1.0/24 drop   # aïllar xarxa
sudo systemctl stop meteo-api ingestor agregador   # aturar el servei, NO la màquina
PID=$(pgrep -f '<proces sospitos>') && sudo kill -STOP $PID
sudo mount -o remount,ro /var/lib/meteora          # congelar l'estat del volum

Justificació. El disc al 98 % explica el bucle de reinicis: meteo-api no pot escriure i Restart=on-failure el rellança; és un símptoma, no la causa. La nota de rescat i les extensions .locked confirmen segrest de dades. S'aïlla la xarxa per tallar la comunicació amb l'atacant conservant l'estat volàtil; s'atura el servei, que ja no funciona i només afegeix soroll; es congela el procés en lloc de matar-lo per poder analitzar-lo; i es remunta el volum en només lectura perquè no es xifri res més. Les evidències es recullen en l'ordre de volatilitat: memòria i processos, després xarxa, després fitxers temporals, i finalment el disc.

Assessoria jurídica: immediatament, i en paral·lel a l'anàlisi. Un segrest de dades implica gairebé segur una bretxa de dades personals, amb possible obligació de notificar-ho a l'autoritat de control en un termini molt breu, i potser als clients afectats. A més cal valorar la denúncia davant de les autoritats competents, les obligacions contractuals amb els clients i la comunicació amb l'asseguradora. Res d'això no és una decisió tècnica i tot té terminis.

Recuperació: reconstruir el servidor des de zero —no netejar l'existent, perquè no es pot demostrar que no hi queda persistència—, restaurar des d'una còpia anterior al compromís verificant sumes, aplicar l'enfortiment de 05-03 abans de tornar-lo a exposar, rotar totes les credencials, i mantenir vigilància reforçada.

Cinc mesures preventives: (1) còpies immutables amb credencials separades i retenció forçada a la destinació, que és l'única defensa real contra el segrest de dades; (2) prova de restauració trimestral amb temps mesurat; (3) alerta per volum d'escriptures fora del patró horari, que hauria avisat a les 03:20 en lloc de a les 08:15; (4) noexec i ProtectSystem=strict per impedir l'execució des de rutes de dades; i (5) procediment de resposta escrit i assajat, amb els telèfons, la ubicació de les còpies i els passos en ordre, perquè a les 08:15 d'un incident real no s'improvisa.

Conclusió

Sense registre no hi ha detecció, ni investigació, ni contenció amb criteri, ni aprenentatge: els controls preventius de les tres lliçons anteriors necessiten controls detectius al costat, perquè la prevenció falla alguna vegada i, quan falla en silenci, l'atacant s'hi queda setmanes. A Linux, aquell registre té dues cares: syslog, amb les seves facilitats i prioritats —auth i authpriv són les primeres que es miren— i el seu valor com a llenguatge comú de la indústria; i journald, binari i indexat, l'avantatge decisiu del qual és que afegeix les metadades pel seu compte i l'emissor no pot mentir sobre elles, cosa que fa que journalctl _UID=990 --since "-24h" valgui més que qualsevol grep. El primer que cal verificar en un servidor és que el diari sigui persistent, perquè a /run es perd sencer en reiniciar, i el segon, que la retenció real cobreixi la finestra d'investigació que necessites —90 dies, no set—.

El registre d'una aplicació es dissenya: marca de temps amb zona, esdeveniment de vocabulari tancat, identitat, origen, objecte, resultat sempre, identificador de correlació i severitat, en format estructurat. I amb una llista d'exclusions tan important com la d'inclusions: mai contrasenyes —les fallades solen ser errors de tecleig sobre la bona—, mai tokens ni claus, i dades personals minimitzades a identificadors amb una taula de traducció a part; tot això amb la política de retenció acordada per escrit amb compliment normatiu, perquè una IP és una dada personal. La rotació amb logrotate evita omplir el disc, i les seves dues directives crítiques són create, que preserva permisos i propietari, i postrotate amb reload, perquè el procés continua escrivint a l'inode antic pel seu descriptor obert. auditd afegeix el que el nucli veu tant si el programa vol com si no —vigilància de secrets.conf incloent-hi la lectura, de sudoers, d'execve amb privilegi, de mòduls i muntatges, amb -e 2 per fer les regles immutables—, amb la regla d'or d'auditar el que és rar i no el que és freqüent, perquè una regla sobre les escriptures de l'ingestor generaria milions d'esdeveniments diaris.

Sobre la integritat, l'afirmació que cal interioritzar és dura: un atacant amb root modifica qualsevol registre local, així que un registre local mai no és prova suficient. chattr +a, els permisos i el segellat FSS aporten protecció davant d'accidents i detecció a posteriori; l'única cosa que protegeix de debò és l'enviament immediat a un col·lector amb credencials de només enviament, perquè treu l'evidència de l'abast de l'atacant en el moment en què es genera. A l'amfitrió, AIDE detecta canvis en binaris i configuració —amb regles per tipus de fitxer, exclusions sensates i la base de referència fora de la màquina—, i els indicadors manuals cobreixen la resta: processos amb exe (deleted), ports inesperats, setuid i capabilities nous, tasques i unitats desconegudes, i claus SSH recents.

I el cicle de resposta en sis fases —preparació, detecció i anàlisi, contenció, eradicació, recuperació, lliçons apreses— amb els seus dos errors capitals ben identificats: apagar el servidor, que destrueix la memòria, les connexions, /tmp i els binaris esborrats accessibles només per /proc, quan aïllar la xarxa conté igual i ho conserva tot; i matar el procés, quan kill -STOP el congela i el deixa inspeccionable. El cas de les 03:12 va mostrar el mètode complet: fotografia de l'estat volàtil primer per l'ordre de volatilitat, lectura de /proc/<PID>/ per descobrir el binari esborrat i l'UID 990, recuperació del binari des de /proc abans que el procés mori, finestra temporal a journalctl i ausearch, cerca de persistència contra les llistes de referència, contenció sense destruir i, al final, una taula de mesures preventives concretes amb responsable i data. La preservació d'evidències —ordre de volatilitat, imatge amb suma de verificació, treball sempre sobre la còpia, cadena de custòdia sense buits— i l'advertència legal: davant d'una bretxa amb dades personals hi ha terminis de notificació breus i decisions que no són tècniques, així que l'assessoria jurídica i el responsable de protecció de dades entren des del primer minut.

Tancament del mòdul 5

Val la pena mirar el recorregut complet, perquè el mòdul ha tingut un fil molt clar: dels mecanismes a la pràctica, i de la prevenció a la detecció.

Vam començar amb el marc (05-01): la distinció entre protecció —mecanisme intern, demostrable— i seguretat —propietat global davant d'un adversari—, que imposa la regla que cap mecanisme no és una solució i tots són capes. Vam veure els quatre conceptes que descriuen qualsevol control d'accés —subjectes, objectes, drets i dominis de protecció, on l'interessant són els canvis de domini—, la matriu d'accés amb les seves dues úniques implementacions possibles —ACL per columnes i capacitats per files, amb el descobriment que un descriptor de fitxer és una capacitat—, els vuit principis de Saltzer i Schroeder aplicats un a un a Meteora, i els quatre models DAC, MAC, RBAC i ABAC. I els tres mecanismes que Linux posa sobre els nou bits: les capabilities que trossegen el "tot o res" de root, SELinux i AppArmor que afegeixen una comprovació obligatòria que ni root no es salta, i seccomp que redueix la superfície de syscalls de 350 a 40. Vam tancar amb la TCB, la superfície d'atac i el delegat confús.

Després vam baixar a la identitat (05-02): l'UID com a identitat real, els tres UID de cada procés i el patró d'alliberar privilegi, els tres fitxers de /etc camp a camp, el cicle de vida d'un compte amb els seus dos punts de risc —l'acumulació de privilegis i la baixa incompleta, on authorized_keys és el que tothom oblida—, les KDF amb sal i cost que protegeixen les contrasenyes, PAM amb les seves quatre piles, SSH amb clau pública, i sudo amb la seva lliçó més subtil: una regla no acota el que l'usuari pot fer, sinó el que pot executar.

Després l'adversari i l'enfortiment (05-03): el catàleg d'amenaces amb el seu indici observable i els quatre eixos comuns —procés, port, fitxer, connexió—, el model d'amenaces com a exercici que dona criteri per prioritzar, les classes de vulnerabilitat explicades per la seva causa arrel, les defenses del sistema (ASLR, NX, canaris, PIE, RELRO) com a capes que encareixen però no arreglen, i l'enfortiment ordenat de meteo-01: actualitzacions, superfície mínima, tallafocs amb policy drop, aïllament amb systemd —el bloc de més valor per línia escrita—, muntatge, límits, xifratge, secrets i còpies 3-2-1 amb la seva prova de restauració.

I aquesta última lliçó ha respost a com se sap que alguna cosa ha passat, i què fer llavors.

Si el mòdul 4 responia a com es guarda alguna cosa perquè continuï sent-hi demà, el mòdul 5 ha respost a com es garanteix que només qui ha de pugui tocar-ho, i com se sap si algú ho va intentar. La resposta ha tingut sempre la mateixa forma: capes independents, cadascuna acotant una superfície diferent, cap no suficient tota sola, i totes verificables amb una ordre concreta.

Però fixa't en el que hem donat per suposat durant cinc lliçons senceres. Hem protegit meteo-01 com si fos una màquina: un nucli, un sistema de fitxers, un conjunt de processos que ho comparteixen tot excepte el que hem separat a mà amb permisos, capabilities, perfils i directives de systemd. Cada capa d'aquest mòdul ha estat, en el fons, un intent de simular aïllament dins d'un sistema que no està aïllat. ProtectSystem=strict fingeix que el sistema de fitxers és de només lectura; PrivateTmp fingeix que el /tmp és propi; IPAddressDeny fingeix que la xarxa no existeix.

I si l'aïllament no s'hagués de fingir? I si meteo-api es pogués executar amb el seu propi sistema de fitxers, la seva pròpia taula de processos, la seva pròpia xarxa, sense veure ni tan sols que existeix la resta? I si el nucli mateix es pogués duplicar, de manera que un compromís total d'un sistema operatiu no arribés al del costat? Això ja no és control d'accés: és aïllament, i és el següent nivell de defensa —a més de la base sobre la qual funciona tota la informàtica moderna al núvol—.

És el Mòdul 6: Virtualització i Contenidors, i comença a Virtualització: Hipervisors i Màquines Virtuals.

Fonaments de Sistemes Operatius

Mòdul 1: Introducció als Sistemes Operatius

Mòdul 2: Gestió de Recursos

Mòdul 3: Concurrència

Mòdul 4: Estructures de Fitxers

Mòdul 5: Protecció i Seguretat del Sistema

Mòdul 6: Virtualització i Contenidors

Mòdul 7: Administració i Diagnòstic a la Pràctica

© Copyright 2026. Tots els drets reservats