La lliçó anterior va acabar assenyalant el pont: la infraestructura immutable i els contenidors són la millor forma d'aplicar una línia base, i tanmateix l'enfortiment clàssic no els cobreix. Un contenidor no és una màquina virtual, no s'hi apliquen pedaços sinó que es reconstrueix, i el compte cloud que l'executa té una superfície pròpia que cap lynis no mira. Aquesta lliçó tanca el pla tècnic del curs allà on avui es produeix la majoria de les bretxes: no en un exploit sofisticat, sinó en una casella mal marcada. Configurarem d'una vegada per totes el compte A-05, el bucket d'adjunts A-02 i les còpies A-03, i construirem imatges que no regalin la partida.

Contingut

  1. Per què el núvol canvia el model d'amenaça
  2. Responsabilitat compartida, en el tècnic
  3. La identitat és el nou perímetre
  4. El bucket A-02, ben configurat d'una vegada
  5. Xarxa i dades: subxarxes privades, xifratge i còpies aïllades
  6. Registre i auditoria del núvol
  7. Postura automatitzada: CSPM i infraestructura com a codi
  8. Contenidors: què aïlla i què no
  9. Execució segura i signatura d'imatges
  10. Orquestració i detecció en temps d'execució
  11. Què ha de fer Nimbus primer, amb el seu pressupost

  1. Per què el núvol canvia el model d'amenaça

En un centre de dades propi, atacar significava trobar un servei vulnerable i explotar-lo. Al núvol, la causa dominant de bretxes no és un exploit: és un error de configuració. Els grans incidents públics de l'última dècada en entorns cloud comparteixen un patró que no requereix cap habilitat ofensiva: un bucket marcat com a públic, una clau d'accés publicada en un repositori, un rol amb permisos d'administrador que només necessitava llegir un fitxer, una base de dades gestionada exposada sense autenticació.

Tres canvis de fons expliquen el desplaçament:

  • Tot és una API. Crear una màquina, obrir un port o donar accés a totes les dades són crides a una API, i una credencial amb permisos amplis permet fer-les totes. El pla de control importa més que el pla de dades: qui controla el compte no necessita entrar a cap servidor.
  • La velocitat és l'avantatge i el risc. Un terraform apply aixeca una infraestructura completa en minuts, i també publica un bucket en segons. La mateixa agilitat que fa competitiva Nimbus multiplica la probabilitat de l'error.
  • Tot és públic per omissió pel que fa a abast de xarxa. No hi ha una porta física ni una xarxa corporativa al voltant: el que es desplega és assolible des d'Internet llevat que es configuri el contrari.

La conseqüència pràctica inverteix la prioritat de treball: al núvol, revisar la configuració reteix més que buscar vulnerabilitats, i per això el CSPM de l'apartat 7 és, per a una pime, més rendible que un escàner de vulnerabilitats addicional.


  1. Responsabilitat compartida, en el tècnic

A 04-04 vam veure el model com a assumpte contractual. Aquí és una llista de tasques concretes, i la pregunta que l'ordena és: si això falla, a qui truques? Si la resposta ets tu, és teu.

Servei a Nimbus Responsabilitat del proveïdor Responsabilitat de Nimbus
Màquines virtuals Hipervisor, maquinari, xarxa física, disponibilitat de la zona Sistema operatiu, pedaços, usuaris, serveis, tallafoc local (tot 05-06)
Base de dades gestionada Motor, pedaços del motor, còpies automàtiques, rèpliques Esquema, usuaris i rols, xifratge activat, xarxa privada, retenció de còpies, RLS
Emmagatzematge d'objectes (A-02, A-03) Durabilitat, xifratge en trànsit, infraestructura Política d'accés, bloqueig públic, xifratge en repòs, versionat, registre
Contenidors gestionats Nodes, orquestrador, pla de control Imatge, usuari del procés, secrets, capacitats, polítiques de xarxa
Identitat del proveïdor Servei d'autenticació, disponibilitat Usuaris, rols, polítiques, MFA, rotació, revisió de permisos
Tots Les dades, sempre. Sense excepció i en qualsevol model de servei

Dues conclusions que convé tenir presents. La primera: com més gestionat és el servei, menys tasques tens, però les que queden són les més crítiques —la configuració d'accés i les dades—. La segona: el proveïdor no t'avisa quan ho fas malament. Publicar un bucket no genera cap alerta des del seu costat: la casella existeix, i fer-la servir és una decisió legítima del client. Aquesta asimetria és exactament el buit on viu l'error de configuració.


  1. La identitat és el nou perímetre

Sense xarxa per defensar, el control d'accés a l'API del proveïdor és el perímetre real. Cinc regles ordenades per impacte:

  1. MFA obligatori al compte arrel, amb la credencial custodiada i sense ús diari. L'arrel només es fa servir per al que cap altra identitat no pot fer.
  2. Res de claus d'accés de llarga durada. Una clau estàtica viu en un fitxer, viatja per xats, es copia a un portàtil i apareix en un repositori: és el risc R-06. Al seu lloc, rols assumibles amb credencials efímeres (minuts o hores) per a les persones, i identitat de la mateixa instància o del contenidor per als serveis, sense cap secret per gestionar.
  3. Federació amb el proveïdor d'identitat. Ningú no té usuari propi al núvol: s'entra amb la identitat corporativa, i la baixa d'un empleat revoca el seu accés a tot d'una vegada. És la correcció d'un problema clàssic: el compte cloud que sobreviu a qui el feia servir.
  4. Mínim privilegi real, que s'aconsegueix observant el que cada rol fa servir de debò i retallant la resta.
  5. Revisió periòdica de permisos excessius, amb l'analitzador d'accessos del proveïdor i amb la recertificació semestral del control C-18.
// ABANS — la politica que "funciona segur", i per aixo es tan comuna.
// Concedeix TOT sobre TOT: si aquesta credencial es filtra, es perd el compte.
{"Version": "2012-10-17", "Statement": [
  {"Effect": "Allow", "Action": "s3:*", "Resource": "*"}
]}
// DESPRES — permis minim per al rol de l'API de Nimbus.
{"Version": "2012-10-17", "Statement": [
  {
    "Sid": "LlegirIEscriureAdjuntsDelTenant",
    "Effect": "Allow",
    "Action": ["s3:GetObject", "s3:PutObject"],   // ni Delete, ni List del bucket
    "Resource": "arn:aws:s3:::nimbus-adjuntos-prod/tenant/*",
    "Condition": {
      "Bool": {"aws:SecureTransport": "true"},    // nomes per TLS
      "StringEquals": {"s3:x-amz-server-side-encryption": "aws:kms"}
    }
  },
  {
    "Sid": "DenegarSortidaDeLaVPC",
    "Effect": "Deny",                             // una DENEGACIO explicita guanya
    "Action": "s3:*",                             // sempre sobre qualsevol Allow:
    "Resource": "*",                              // encara que una altra politica concedeixi
    "Condition": {"StringNotEquals": {"aws:SourceVpce": "vpce-nimbus-s3"}}
  }
]}

Tres decisions mereixen justificar-se. No es concedeix s3:DeleteObject: l'API de Nimbus no necessita mai esborrar adjunts, i no tenir-ho converteix un compromís de l'API en una fuita —greu— en lloc d'en una destrucció —irreversible—. El Resource acota la ruta, no només el bucket, així que una fallada de l'aplicació no arriba a altres prefixos. I la denegació explícita per punt d'enllaç de la VPC és la més potent: encara que una altra política concedeixi accés per error, si la petició no ve per la xarxa privada de Nimbus, es denega. Una credencial robada i usada des de fora no serveix.


  1. El bucket A-02, ben configurat d'una vegada

Aquest és l'actiu que 02-06 va buidar durant set dies. Es tanca amb set controls que s'apliquen junts.

B=nimbus-adjuntos-prod

# 1) BLOQUEIG D'ACCES PUBLIC a nivell de compte i de bucket. Es la casella que
#    impedeix que una politica futura, escrita amb pressa, el faci public.
aws s3api put-public-access-block --bucket $B --public-access-block-configuration \
  BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true

# 2) XIFRATGE en repos amb clau gestionada per Nimbus (03-06: xifratge de sobre).
#    bucket-key-enabled redueix el cost de KMS sense perdre el control de la clau.
aws s3api put-bucket-encryption --bucket $B --server-side-encryption-configuration \
  '{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"aws:kms",
     "KMSMasterKeyID":"arn:aws:kms:eu-west-1:...:key/nimbus-adjuntos"},
     "BucketKeyEnabled":true}]}'

# 3) VERSIONAT: un esborrament deixa una versio anterior recuperable.
aws s3api put-bucket-versioning --bucket $B --versioning-configuration Status=Enabled

# 4) REGISTRE D'ACCESSOS: sense aixo no existeix la deteccio D-04 de 05-02.
aws s3api put-bucket-logging --bucket $B --bucket-logging-status \
  '{"LoggingEnabled":{"TargetBucket":"nimbus-logs-prod","TargetPrefix":"s3/adjuntos/"}}'

# 5) VERIFICAR que ja NO es public. La configuracio no val: val la prova.
curl -s -o /dev/null -w "%{http_code}\n" https://$B.s3.amazonaws.com/tenant/41/prova.pdf
# Esperat: 403. Qualsevol 200 significa que segueix exposat.

Els dos controls restants van sobre el bucket de còpies A-03, i són els que 02-06 va demostrar imprescindibles:

# nimbus-backups-prod — en un COMPTE SEPARAT de produccio
bloqueig_objectes:
  mode: COMPLIANCE          # ni l'administrador pot escurcar la retencio:
  retencio_dies: 35         # es el que converteix "immutable" en alguna cosa real
politica:
  - efecte: Deny
    accio: [s3:DeleteObject, s3:DeleteObjectVersion, s3:PutBucketVersioning]
    principal: "*"          # NINGU no esborra, ni tan sols amb credencials valides
  - efecte: Allow
    accio: [s3:PutObject]
    principal: "arn:aws:iam::COMPTE-PRODUCCIO:role/nimbus-backup"
    condicio: { StringEquals: { "s3:x-amz-server-side-encryption": "aws:kms" } }
replicacio: { desti: regio-secundaria, compte: COMPTE-COPIES }

El mode COMPLIANCE és la diferència entre una còpia i una esperança. En mode governance, un administrador pot aixecar la retenció; en mode compliance, ningú no pot, ni el propietari del compte, fins que expiri. És el quart dígit de la regla 3-2-1-1-0 de 04-06 i és, literalment, el que hauria impedit l'esborrament del dia 20 a les 02:10.

I el setè control, ja conegut: les descàrregues se serveixen amb URL signades de 120 segons (03-07), generades després de comprovar l'autorització a l'aplicació (05-05). Mai no hi ha un enllaç permanent ni un objecte llegible sense credencial.


  1. Xarxa i dades: subxarxes privades, xifratge i còpies aïllades

Reprenent el disseny de 05-04 amb la mirada posada als serveis gestionats:

  • La base de dades viu en una subxarxa privada sense ruta a Internet, ni d'entrada ni de sortida. No és «un port tancat»: és que no existeix camí.
  • Punts d'enllaç privats (VPC endpoints) per parlar amb l'emmagatzematge d'objectes i amb el gestor de secrets. El trànsit no surt a Internet, i —el més valuós— permet la condició aws:SourceVpce de l'apartat 3, que anul·la el valor d'una credencial robada.
  • Xifratge en repòs i en trànsit per omissió a tots els serveis, amb claus gestionades per Nimbus i rotació amb kid (03-06). El xifratge del proveïdor protegeix davant del robatori físic del disc; el xifratge amb clau pròpia protegeix a més davant d'errors d'accés lògic.
  • Bloqueig del servei de metadades o exigència de la seva versió amb sessió (IMDSv2), que és la mitigació estructural del SSRF de 05-05: sense ella, un SSRF a l'API lliura les credencials del rol de la instància.
  • Les còpies viuen en un altre compte, amb credencials diferents. És la lliçó més cara de 02-06: les còpies de Nimbus eren al mateix compte que producció, i qui va comprometre el compte les va esborrar juntament amb tota la resta. Còpies en un altre compte significa que l'atacant necessita comprometre dos comptes independents, amb dos conjunts de credencials i dos proveïdors d'identitat. El cost afegit és d'uns pocs euros al mes.

  1. Registre i auditoria del núvol

El registre d'activitat del proveïdor (CloudTrail o equivalent) respon a qui va cridar quina API, quan, des d'on i amb quin resultat. És la font més important d'un entorn cloud i cal configurar-la bé:

  • Actiu a totes les regions, no només a la que es fa servir. Una tècnica habitual consisteix a operar en una regió que ningú no mira.
  • Enviat a un bucket d'un altre compte, amb les mateixes propietats de l'apartat 4: immutable i només escriptura. Els logs es protegeixen igual que les còpies.
  • Validació d'integritat activada, per poder demostrar que no es van manipular.
  • Complementat amb els registres d'accés al bucket, els del balancejador i els de flux de la VPC (05-04).

Les alertes mínimes, que connecten directament amb el catàleg de 05-02:

Alerta Esdeveniment Severitat Per què
Ús del compte arrel Qualsevol acció amb la identitat arrel S1 No s'hauria de fer servir mai en el dia a dia
Canvi de política o de rol PutRolePolicy, AttachUserPolicy S1 (D-07) És l'escalada de privilegis al núvol
Canvi a la configuració del bucket PutBucketPolicy, PutPublicAccessBlock S1 (D-06) És com un bucket es torna públic
Desactivació de registre StopLogging, DeleteTrail S1 (D-08) Només té un motiu: esborrar el rastre
Esborrament de còpies o instantànies DeleteBackup, DeleteDBSnapshot S1 (D-10) El dia 20 de 02-06
Accés des de regió o país inusual Crides des de fora de la llista esperada S2 (D-02) Credencial compromesa
MFA desactivat en un compte DeactivateMFADevice S2 Preparació d'un accés posterior

Les cinc primeres són S1 perquè cap no té explicació benigna freqüent. Són, a més, baratíssimes de muntar: són consultes sobre un registre que ja existeix.


  1. Postura automatitzada: CSPM i infraestructura com a codi

CSPM (Cloud Security Posture Management) és avaluar de forma contínua la configuració del compte contra un conjunt de bones pràctiques. prowler i ScoutSuite són lliures i suficients.

prowler aws --compliance cis_2.0_aws --severity critical high \
        --output-formats html csv json --output-directory /var/log/prowler
Provider: aws   Account: 4711-nimbus-prod   Checks: 312   Duration: 6m
FAIL 14 · PASS 271 · MANUAL 27

CRITICAL  s3_bucket_public_access
  nimbus-web-assets  ->  Bucket accessible publicament (ACL: AllUsers READ)
CRITICAL  iam_root_mfa_enabled
  El compte arrel NO te MFA habilitat
HIGH      iam_user_accesskey_unused_45_days
  usuari 'deploy-legacy': clau d'acces creada 2023-02-11, sense usar 402 dies
HIGH      rds_instance_backup_enabled
  nimbus-preprod-db: copies automatiques DESACTIVADES
HIGH      cloudtrail_multi_region_enabled
  Trail 'principal' nomes cobreix eu-west-1
MEDIUM    s3_bucket_object_lock_enabled
  nimbus-backups-prod: sense bloqueig d'objectes

Lectura comentada, amb el criteri de priorització de 05-01. iam_root_mfa_enabled és el primer, malgrat no ser el que més soroll fa: sense MFA a l'arrel, tots els altres controls són opcionals per a qui aconsegueixi aquella credencial, i activar-lo són cinc minuts. El bucket públic va immediatament després, i la primera pregunta no és com tancar-lo sinó què conté i des de quan està així: si té dades personals, això ja no és una troballa de configuració, és una possible bretxa (04-05, 06-03). La clau d'accés sense usar 402 dies és la troballa més silenciosa i una de les més perilloses: una credencial permanent, oblidada, que ningú no trobaria a faltar si algú la fes servir; s'elimina, no es rota. I les còpies desactivades a preproducció tornen a assenyalar A-22.

Desplaçar el control a l'esquerra. El CSPM detecta l'error després que arribi a producció. checkov i tfsec el detecten al pull request, sobre el codi d'infraestructura, abans que existeixi:

# .github/workflows/iac.yml
- uses: bridgecrewio/checkov-action@master
  with:
    directory: infra/
    framework: terraform
    soft_fail: false          # BLOQUEJA: un bucket public no arriba mai a produccio
    skip_check: CKV_AWS_18    # excepcio amb justificacio i caducitat (04-02)
    output_format: sarif

La combinació correcta és checkov bloquejant al CI i prowler setmanal sobre el compte, perquè no tot es desplega per codi: sempre hi ha alguna cosa feta a mà a la consola web, i això només ho veu el CSPM.


  1. Contenidors: què aïlla i què no

Aïlla raonablement No aïlla
Processos, sistema de fitxers, xarxa i noms de host (per namespaces) El kernel: és el mateix que el de l'amfitrió. Una vulnerabilitat del kernel afecta tot
Consum de CPU i memòria (per cgroups) El contenidor privilegiat o amb capacitats de més, que és equivalent a root a l'amfitrió
Dependències entre aplicacions El socket de Docker muntat a dins: és control total de l'amfitrió

La frase que cal interioritzar: un contenidor és aïllament de processos, no una frontera de seguretat com la d'una màquina virtual. Si necessites separar càrregues de confiança molt diferent, la frontera correcta és la màquina virtual o el compte separat.

# ABANS — el Dockerfile de l'API a 01-04, amb sis problemes greus
FROM python:3.11                      # imatge completa: ~1 GB i centenars de CVE
WORKDIR /app
COPY . .                              # copia TOT: .git, .env, claus, tests
RUN pip install -r requirements.txt   # sense hashes: s'installa el que hi hagi avui
ENV DATABASE_URL=postgresql://nimbus_api:Tr4mo...@db:5432/nimbus   # SECRET
EXPOSE 8000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0"]   # s'executa com a ROOT
# DESPRES — multi-stage, minima, sense secrets i sense root
FROM python:3.11-slim@sha256:1c8f9a...  AS build
# Fixar per DIGEST i no per etiqueta: `3.11-slim` canvia de contingut sense avisar,
# aixi que l'etiqueta no garanteix que construeixis dues vegades el mateix.
WORKDIR /app
COPY requirements.txt .
RUN pip install --require-hashes --prefix=/instalat -r requirements.txt
# --require-hashes: si una versio va ser republicada amb un altre contingut, FALLA
# la construccio en lloc d'installar-la en silenci (04-04).

FROM gcr.io/distroless/python3-debian12@sha256:9d2e4b...
# Distroless: sense shell, sense gestor de paquets, sense utilitats. Redueix les CVE
# al voltant del 90 % i, sobretot, deixa l'atacant sense eines si hi entra.
COPY --from=build /instalat /usr/local
COPY --chown=nonroot:nonroot app/ /app/app/
# Nomes es copia el codi de l'aplicacio, gracies tambe a .dockerignore:
# .git, .env, tests i credencials no entren mai en cap capa.
USER nonroot                          # el proces NO es root dins del contenidor
WORKDIR /app
EXPOSE 8000
ENTRYPOINT ["python", "-m", "uvicorn", "app.main:app", "--host", "0.0.0.0"]
# Sense ENV amb secrets: la credencial s'injecta a l'arrencada des del gestor
# (05-05). Un secret en una capa roman a la imatge encara que s'esborri despres.

L'últim comentari mereix èmfasi perquè és l'error més comú i el menys evident: esborrar un fitxer en una capa posterior no l'elimina de la imatge. Continua sent a la capa anterior i es recupera amb una ordre. Per això trivy --scanners secret (05-01) forma part del pipeline.


  1. Execució segura i signatura d'imatges

Construir bé la imatge és la meitat; l'altra meitat és com s'executa.

# docker-compose.prod.yml / equivalent a l'orquestrador
services:
  api:
    image: registry.nimbus.example/api@sha256:6f1b...   # per DIGEST, no per :latest
    read_only: true               # sistema de fitxers de nomes lectura: impedeix
    tmpfs: [/tmp]                 # escriure binaris o persistir; /tmp en memoria
    cap_drop: ["ALL"]             # es treuen TOTES les capacitats del kernel
    cap_add: []                   # i no se'n retorna cap: l'API no les necessita
    security_opt:
      - no-new-privileges:true    # cap proces fill no pot guanyar privilegis
      - apparmor=docker-default   # perfil de control d'acces obligatori (05-06)
    user: "10001:10001"           # usuari sense privilegis, explicit
    mem_limit: 512m               # limits: un contenidor no tomba el vei
    pids_limit: 200               # ni esgota la taula de processos de l'amfitrio

read_only més cap_drop: ALL més no-new-privileges és la combinació que més eleva el cost d'un atac, i no costa res: la majoria de les aplicacions web funcionen tal qual, i les que no, només necessiten declarar les seves rutes d'escriptura com a volums.

Signatura d'artefactes amb cosign (reprenent 03-07), que respon a la pregunta «aquesta imatge és la que vam construir nosaltres?»:

# Signar al CI, sense claus per custodiar (identitat del propi pipeline)
cosign sign --yes registry.nimbus.example/api@sha256:6f1b...

# Verificar ABANS de desplegar; si falla, el desplegament s'atura
cosign verify registry.nimbus.example/api@sha256:6f1b... \
  --certificate-identity-regexp "https://github.com/nimbus/.*" \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

Sense verificació al desplegament, la signatura és decorativa. La cadena completa queda així, i és la integritat de la cadena de subministrament de 04-04 portada a la pràctica:

flowchart LR
    PR["Pull request\ncodi + infra"] --> CK["checkov / tfsec\nBLOQUEJA config insegura"]
    CK --> BU["Build multi-stage\ndistroless, sense root"]
    BU --> TR["trivy\nvuln + secrets\nBLOQUEJA sobre llindar"]
    TR --> CS["cosign sign\nidentitat del pipeline"]
    CS --> RG["Registre\nimatge per digest"]
    RG --> VE["cosign verify\nal desplegament"]
    VE -->|"signatura valida"| PROD["Produccio\nread_only, cap_drop ALL"]
    VE -->|"sense signatura"| STOP["Desplegament aturat"]
    PROD --> FA["Falco\ndeteccio en execucio"]

  1. Orquestració i detecció en temps d'execució

Nimbus encara no fa servir Kubernetes, i convé dir amb claredat que Kubernetes és un àmbit de seguretat propi, no un detall de desplegament. Si arriba, aquestes són les sis peces mínimes: espais de noms per entorn i per criticitat, amb quotes; RBAC amb comptes de servei propis per aplicació i sense fer servir el compte per omissió; polítiques de xarxa, perquè per omissió tots els pods parlen amb tots —és l'error més freqüent i l'equivalent a la xarxa plana de 05-04—; estàndards de seguretat de pods en nivell restricted, que imposa el de l'apartat 9; gestió de secrets amb un proveïdor extern, perquè els secrets natius van codificats en base64 i no xifrats; i kube-bench, que avalua el clúster contra el benchmark CIS igual que lynis avalua un servidor.

Detecció en temps d'execució amb Falco. L'escaneig d'imatges mira el que hi ha; Falco mira el que passa, observant les crides al sistema:

- rule: Shell oberta dins d'un contenidor de produccio
  desc: >
    Un contenidor de l'API no hauria d'executar MAI una shell. Com que la imatge
    es distroless, aixo nomes pot significar un compromis o un desplegament mal
    construit: en tots dos casos cal assabentar-se'n.
  condition: >
    spawned_process and container
    and container.image.repository = "registry.nimbus.example/api"
    and proc.name in (bash, sh, dash, zsh)
  output: "Shell en contenidor (usuari=%user.name proces=%proc.cmdline
           contenidor=%container.name imatge=%container.image.repository)"
  priority: CRITICAL
  tags: [container, mitre_execution]

Què val la pena detectar en temps d'execució, sense generar soroll: shell dins d'un contenidor, escriptura en rutes del sistema (/etc, /usr/bin) quan el sistema de fitxers hauria de ser de només lectura, connexió sortint a una destinació inesperada, lectura de fitxers sensibles com /etc/shadow o les credencials de la instància, i muntatge del socket de Docker. Totes van al mateix canal de 05-02 i comparteixen les seves regles de qualitat d'alerta.


  1. Què ha de fer Nimbus primer, amb el seu pressupost

Prioritat Acció Cost Esforç Risc que redueix
1 MFA a l'arrel i federació amb el proveïdor d'identitat 0 € 2 h Compromís total d'A-05
2 Bloqueig d'accés públic a tots els buckets, i verificat 0 € 2 h R-04, la fuita de 02-06
3 Còpies en compte separat amb bloqueig d'objectes en mode compliance ~15 €/mes 6 h R-02, el dia 20
4 Eliminar claus d'accés de llarga durada; rols efímers 0 € 8 h R-06
5 Registre d'activitat multiregió a compte separat + les 5 alertes S1 ~10 €/mes 8 h Els 20 dies de ceguesa
6 prowler setmanal i revisió de les troballes 0 € 4 h + 1 h/mes Deriva de configuració
7 checkov bloquejant al CI d'infraestructura 0 € 4 h Que l'error arribi a producció
8 Dockerfile distroless, sense root i sense secrets, amb trivy 0 € 12 h Superfície de la imatge
9 Punts d'enllaç privats i condició SourceVpce ~20 €/mes 6 h Valor d'una credencial robada
10 Falco amb cinc regles i cosign al desplegament 0 € 16 h Compromís en execució

El total suma uns 540 €/any i unes 70 hores. És menys del 3 % del pressupost de 18.000 €/any i el 16 % de les 440 hores de la Lucía, i cobreix els tres riscos pitjor puntuats del registre de 04-01. És, amb diferència, la millor relació cost/impacte de tot el mòdul 5, i la raó és la mateixa amb què va començar la lliçó: al núvol, gairebé tot el que falla és una casella, i les caselles són gratis.


Errors Comuns i Consells

  • Creure que el proveïdor et protegeix de les teves pròpies configuracions. No t'avisa quan publiques un bucket: és una acció legítima del client.
  • Fer servir claus d'accés de llarga durada. Acaben en un repositori, en un xat o en un portàtil. Rols efímers i identitat d'instància.
  • Concedir Action: "*" «temporalment». No hi ha res més permanent que un permís temporal que funciona.
  • Deixar les còpies al mateix compte que producció. És el que va convertir l'incident de 02-06 en una catàstrofe.
  • Confiar que un contenidor aïlla com una màquina virtual. Comparteix kernel; amb capacitats de més o el socket de Docker muntat, és l'amfitrió sencer.
  • Etiquetes en lloc de digests. :latest no és reproduïble: escaneges una imatge i en desplegues una altra.
  • Secrets a ENV del Dockerfile. Queden a la capa encara que els esborris després.
  • Consell: comença per les dues primeres files de la taula del §11. Quatre hores, cost zero, i cobreixen el pitjor escenari possible.
  • Consell: verifica, no configuris. Un curl que retorni 403 val més que una captura de la consola web, i és l'evidència que demana 04-03.
  • Consell: checkov al CI abans que prowler al compte. És més barat impedir l'error que descobrir-lo, encara que necessitaràs tots dos.

Exercicis

Exercici 1 — Interpretar un informe de CSPM

Sobre la sortida de prowler del §7, i sabent que nimbus-web-assets serveix les imatges públiques del web de màrqueting:

  1. Ordena les sis troballes per prioritat real, justificant cada posició.
  2. Canvia la teva avaluació del bucket públic en saber per a què es fa servir? Què comprovaries abans de decidir?
  3. Escriu la correcció concreta de les tres primeres i indica com verificaries cadascuna.

Exercici 2 — Revisar un desplegament de contenidor

L'Iván proposa aquest servei per a producció. Identifica tots els problemes i reescriu-lo.

services:
  api:
    image: nimbus/api:latest
    privileged: true
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /:/host
    environment:
      DATABASE_URL: "postgresql://nimbus_api:Tr4mo...@db:5432/nimbus"
    ports: ["8000:8000"]

Exercici 3 — Dissenyar l'aïllament de les còpies

La Marta pregunta, després de llegir el post mortem de 02-06: «com garantim que això no pot tornar a passar?». Dissenya l'esquema de còpies de Nimbus de manera que un atacant amb control total del compte de producció no les pugui destruir, i indica com ho demostraries.


Solucions

Exercici 1

(1) Ordre per prioritat real:

Ordre Troballa Justificació
1 Arrel sense MFA És la clau mestra d'A-05, del qual depenen gairebé tots els actius (01-04). Una sola contrasenya separa un atacant del control total. S'arregla en 5 minuts
2 Bucket públic Exposició actual, amb impacte que depèn del contingut (vegeu el punt 2)
3 Clau d'accés sense usar 402 dies La troballa més silenciosa: credencial permanent, oblidada i sense propietari. Si algú la fa servir, ningú no la trobaria a faltar. No es rota: s'elimina
4 CloudTrail només en una regió No és exposició, és ceguesa parcial, i precisament a les regions que ningú no mira, que és on opera un atacant informat
5 nimbus-backups-prod sense bloqueig d'objectes És la fallada del dia 20 de 02-06 sense corregir del tot. Puja al lloc 1 si es confirma que les còpies segueixen al compte de producció
6 Còpies desactivades a nimbus-preprod-db Preproducció tolera pèrdua... llevat que contingui dades reals, que és el dubte obert d'A-22. Resoldre aquesta classificació és més urgent que activar la còpia

(2) Sí que canvia, però menys del que sembla. Que un bucket d'imatges de màrqueting sigui llegible públicament pot ser exactament el que es pretén, i en aquest cas la troballa és un fals positiu que es documenta com a excepció (04-02). Abans de decidir cal comprovar quatre coses: quins objectes conté realment —els buckets de «recursos web» acumulen amb enorme freqüència exportacions, còpies de seguretat puntuals i PDF de clients que algú hi va deixar—; si a més de lectura pública té escriptura pública, que seria crític perquè permetria a qualsevol alterar el contingut servit sota el domini de Nimbus; des de quan està així i què diuen els registres d'accés; i si hi ha una manera millor d'aconseguir el mateix, que sí que n'hi ha: CDN al davant amb el bucket privat, cosa que dona control, memòria cau i registre sense exposició directa. La regla general: un bucket públic és acceptable només si és un bucket dedicat, el contingut del qual està íntegrament destinat a ser públic i així consta per escrit.

(3) Correccions i verificació:

  • Arrel sense MFA: activar MFA amb una clau física, guardar la credencial i el segon factor de reserva en custòdia física amb accés de dues persones, i crear una alerta S1 davant de qualsevol ús de l'arrel (§6). Verificació: prowler torna a executar iam_root_mfa_enabled amb resultat PASS, i una prova d'accés demana el segon factor.
  • Bucket públic: si el contingut ha de ser públic, moure'l a un bucket dedicat darrere d'una CDN i deixar l'original privat; si no, aplicar el bloqueig d'accés públic del §4. En tots dos casos, inventariar el contingut abans. Verificació: curl sobre un objecte conegut retornant 403 i put-public-access-block confirmat.
  • Clau sense usar: eliminar-la, no desactivar-la —una clau desactivada es reactiva—; comprovar abans al registre d'activitat que cap procés no la va fer servir en 402 dies, i cercar si apareix a l'historial del repositori amb gitleaks (05-01), perquè una clau oblidada sol estar-ho per haver estat incrustada en algun lloc. Verificació: la clau no apareix al llistat i no hi ha errors d'autenticació nous en 48 hores.

Exercici 2

Problemes, de major a menor gravetat:

# Problema Conseqüència
1 /var/run/docker.sock muntat És control total de l'amfitrió. Qui entri al contenidor pot crear un altre contenidor privilegiat i sortir-ne. Equival a donar root a la màquina
2 privileged: true Desactiva pràcticament tot l'aïllament: totes les capacitats i accés als dispositius
3 /:/host El sistema de fitxers complet de l'amfitrió, muntat i escrivible des del contenidor
4 Credencial a environment Secret en clar, visible amb docker inspect, als logs de l'orquestrador i a l'historial de desplegament. És R-06
5 image: nimbus/api:latest No reproduïble: s'escaneja una imatge i se'n desplega una altra. I no es verifica signatura
6 ports: ["8000:8000"] Publicat a totes les interfícies de l'amfitrió, saltant-se el balancejador; és el patró del tauler de cues de 05-03
7 Absències: sense read_only, sense cap_drop, sense no-new-privileges, sense user, sense límits de recursos El contenidor pot escriure binaris, escalar privilegis i esgotar l'amfitrió
services:
  api:
    image: registry.nimbus.example/api@sha256:6f1b...   # digest + signatura verificada
    read_only: true
    tmpfs: [/tmp]
    cap_drop: ["ALL"]
    security_opt: [no-new-privileges:true, apparmor=docker-default]
    user: "10001:10001"
    mem_limit: 512m
    pids_limit: 200
    ports: ["127.0.0.1:8000:8000"]     # nomes local; el balancejador fa de front
    secrets: [db_url]                  # injectat a l'arrencada des del gestor
    # sense docker.sock, sense volums de l'amfitrio, sense privileged

Exercici 3

El requisit reformulat: que la destrucció de les còpies exigeixi credencials que el compte de producció no posseeix i una acció que cap credencial no pot realitzar. Quatre capes, cadascuna resolent una fallada diferent:

  1. Compte separat, amb el seu propi proveïdor d'identitat i el seu propi MFA. Comprometre producció no dona cap accés al compte de còpies. És la capa que faltava a 02-06, on tot vivia junt.
  2. Flux d'escriptura en un sol sentit i de mínim privilegi. El rol nimbus-backup de producció té únicament PutObject sobre el bucket de còpies: no pot llistar, no pot llegir i no pot esborrar. Que no pugui llegir és important i se sol oblidar: impedeix que un atacant a producció s'endugui també l'històric complet.
  3. Bloqueig d'objectes en mode COMPLIANCE amb 35 dies de retenció. Aquí hi ha el nucli de la resposta a la Marta: ni tan sols un administrador del compte de còpies amb MFA pot escurçar la retenció ni esborrar un objecte abans que expiri. No és una qüestió de permisos, que sempre es poden canviar; és una propietat de l'emmagatzematge.
  4. Replicació a una segona regió i, per al conjunt crític, una còpia addicional en emmagatzematge fred amb credencials diferents de tot l'anterior.

Es complementa amb detecció: l'alerta D-10 de 05-02 davant de qualsevol intent d'esborrament o de canvi de retenció, i l'alerta de silenci —si el procés de còpia deixa d'escriure durant 24 hores, algú se n'ha d'assabentar—, perquè la forma sigil·losa de destruir còpies no és esborrar-les, sinó impedir que es creïn i esperar que l'històric caduqui.

Com es demostra, que és el que la Marta ha d'exigir i no una explicació: (a) intent real d'esborrament des del compte de còpies amb credencials d'administrador, que ha de fallar amb AccessDenied, amb la sortida guardada com a evidència; (b) prova de restauració cronometrada de 04-06, executada des del compte de còpies, que verifica hash, compara files i mesura l'RTO real; (c) simulacre de compromís: revocar totes les credencials de producció i comprovar que les còpies segueixen sent accessibles i restaurables; i (d) revisió trimestral que el bloqueig d'objectes segueix actiu, inclosa al --check --diff de la infraestructura com a codi (05-06). La resposta correcta a la pregunta de la Marta no és «hem configurat això»: és «ho hem intentat destruir i no hem pogut, i aquí hi ha la sortida de consola amb data».


Conclusió

Has tancat el pla tècnic del curs allà on avui es trenquen la majoria de les empreses. Saps per què el núvol canvia el model d'amenaça —l'error de configuració substitueix l'exploit com a causa dominant— i les tres raons de fons: tot és una API, la velocitat multiplica l'error i l'abast és públic per omissió. D'aquí la inversió de prioritats: revisar la configuració reteix més que buscar vulnerabilitats. Apliques el model de responsabilitat compartida servei a servei amb la pregunta que l'ordena —«si això falla, a qui truques?»— i amb les dues conclusions que importen: com més gestionat el servei, menys tasques i més crítiques; i el proveïdor no t'avisa mai quan ho fas malament.

Domines la identitat com a nou perímetre: MFA a l'arrel, fi de les claus de llarga durada, rols assumibles amb credencials efímeres, federació amb el proveïdor d'identitat i revisió de permisos excessius; amb la política mínima que no concedeix Delete, acota el prefix i afegeix una denegació explícita per punt d'enllaç de la VPC que anul·la el valor d'una credencial robada. Has configurat el bucket A-02 d'una vegada: bloqueig d'accés públic, xifratge amb clau pròpia, versionat, registre d'accessos i verificació amb un curl que ha de retornar 403; i les còpies A-03 en compte separat amb bloqueig d'objectes en mode COMPLIANCE, que és el que converteix «immutable» en alguna cosa real i el que hauria impedit l'esborrament del dia 20. Saps muntar subxarxes privades, punts d'enllaç privats, xifratge per omissió, bloqueig del servei de metadades com a mitigació estructural del SSRF, i còpies que exigeixen comprometre dos comptes independents.

Saps configurar el registre d'activitat multiregió, immutable, en un altre compte i amb validació d'integritat, i les set alertes mínimes de les quals cinc són S1 perquè cap no té explicació benigna. Manegues CSPM amb prowler —llegint el seu informe amb el criteri de 05-01, començant pel MFA de l'arrel i preguntant què conté el bucket públic abans de tancar-lo— i checkov bloquejant al CI perquè l'error no arribi a producció, amb la conclusió que calen tots dos. Entens què aïlla i què no un contenidor, i tens el Dockerfile abans i després: multi-stage, distroless, fixat per digest, --require-hashes, sense secrets en capes i sense root; amb l'advertiment que esborrar un fitxer en una capa posterior no l'elimina de la imatge. Executes amb read_only, cap_drop: ALL, no-new-privileges i límits, signes amb cosign i verifiques abans de desplegar, perquè sense verificació la signatura és decorativa. I coneixes l'enquadrament de Kubernetes com a àmbit propi i Falco per detectar el que passa en execució. Tot això prioritzat en una taula que suma uns 540 € i 70 hores i cobreix els tres riscos pitjor puntuats del registre: al núvol, gairebé tot el que falla és una casella, i les caselles són gratis.

Amb això, el Mòdul 5 està complet. Nimbus ja sap trobar el que té exposat i prioritzar-ho (05-01), veure l'atacant moure's amb dotze deteccions que haurien tallat l'incident de 02-06 el dia 0 (05-02), posar-se a prova amb un pentest autoritzat i aprofitar-ne l'informe (05-03), segmentar la seva xarxa i verificar que la segmentació funciona de debò (05-04), defensar el seu propi codi amb autorització centralitzada i un CI que diu que no (05-05), endurir els seus sistemes amb una línia base automatitzada i verificada setmanalment (05-06) i tancar el seu núvol i els seus contenidors (05-07). Han caigut, un a un, tots els problemes que arrossegàvem des d'01-04: el PostgreSQL exposat, el Redis sense autenticació, l'SSH obert, el python -m http.server i l'accés permanent de la consultora.

I aquí apareix el límit de tot l'anterior. Res d'això no es manté sol. Les eines troben i corregeixen, però l'escaneig mensual deixa d'executar-se quan la Lucía té una mala setmana; la línia base es degrada si ningú no mira el --check --diff; la CSP s'omple d'excepcions; el security.txt caduca; i el pròxim empleat que entri no en sabrà res de tot això llevat que algú l'hi ensenyi. A més, haver fet la feina no basta: cal poder demostrar-ho —davant d'un client que exigeix garanties, davant d'una auditoria, davant de l'Agència Espanyola de Protecció de Dades si un dia cal notificar una bretxa—. Al Mòdul 6: Bones Pràctiques i Normatives passem de l'execució al que la sosté en el temps: bones pràctiques que converteixen decisions puntuals en hàbits (06-01), normatives i estàndards com ISO 27001, NIS2 i ENS (06-02), la protecció de dades i el RGPD aplicats de debò a un SaaS que tracta dades de salut (06-03), compliment i auditoria amb l'evidència que aquest mòdul ha anat generant (06-04), formació i sensibilització, perquè les persones continuen sent el vector principal (06-05), i l'ètica i la divulgació responsable que 05-03 va deixar pendents (06-06). Deixem de preguntar si està protegit i comencem a preguntar si es pot demostrar i si durarà.

Curs de Fonaments de Seguretat Informàtica

Mòdul 1: Introducció a la Seguretat Informàtica

Mòdul 2: Ciberseguretat

Mòdul 3: Criptografia

Mòdul 4: Gestió de Riscos i Mesures de Protecció

Mòdul 5: Eines i Tècniques de Seguretat

Mòdul 6: Bones Pràctiques i Normatives

Mòdul 7: Projecte Final

© Copyright 2026. Tots els drets reservats