La lliçó anterior va acabar assenyalant dos deutes que arrossegues des del Mòdul 5, i tots dos són criptogràfics. El primer: db_password està escrita en clar dins de /etc/tramontana/app.conf, i ja has vist que qualsevol fallada de permisos converteix això en una fuita de credencials que cap vigilància no evita. El segon: el trànsit de reserves —amb els noms dels hostes que tanta cura has posat a protegir dins de les còpies— viatja sense xifrar pel port 8080. Aquesta lliçó resol totes dues, perquè són el mateix problema vist des de dos angles: guardar un secret i demostrar una identitat.
Són dues parts clarament separades. A la primera aprendràs a treure un secret d'un fitxer de configuració i a gestionar-lo amb les eines que el sistema ja et dona: permisos estrictes, EnvironmentFile i LoadCredential de systemd, GPG, pass i LUKS. A la segona, què és realment un certificat, com es genera, es llegeix i es verifica, com se n'obté un de gratuït i renovat automàticament de Let's Encrypt, i com vigilar-ne la caducitat — que és la fallada més ximple i més freqüent de producció.
Avís d'abast. Aquí s'obté, s'instal·la i es verifica el material criptogràfic de reserves.tramontana.example. El servidor web que el servirà —Nginx com a servidor intermediari invers davant de l'aplicació del port 8080— es munta al projecte 08-01. És deliberat: el xifratge en trànsit es prepara i es prova ara perquè al Mòdul 8 sigui un detall de configuració i no un tema nou.
Advertiment de compliment. El xifratge de dades personals, en trànsit i en repòs, no és una millora opcional: el RGPD l'exigeix com a mesura tècnica apropiada (art. 32). reserves.csv conté noms d'hostes. En un entorn real, el disseny de la gestió de claus i de la seva custòdia l'ha de revisar el responsable de seguretat, i les decisions sobre dades personals el responsable de protecció de dades.
Contingut
- Què és un secret i on no va mai
- El mínim decent: permisos, EnvironmentFile i LoadCredential
- Xifratge en repòs de secrets: GPG i pass
- Xifratge de disc amb LUKS
- Gestors centralitzats de secrets
- Rotació de credencials
- Què garanteix TLS i què conté un certificat
- Generar, llegir i verificar material criptogràfic amb OpenSSL
- Let's Encrypt i la renovació automàtica
- Bones pràctiques de TLS, custòdia de la clau i vigilància de la caducitat
Què és un secret i on no va mai
Un secret és una dada el valor de la qual depèn que només la conegui qui ha de fer-ho: una contrasenya, una clau d'API, un testimoni, una clau privada, la frase de pas d'un dipòsit de còpies. Es distingeix d'una dada sensible qualsevol perquè el seu compromís no és un problema de privacitat sinó de control: qui el té pot actuar en nom teu.
La primera regla és negativa, i convé entendre el perquè de cada punt perquè cadascun correspon a una fuita real i freqüent:
| On NO va un secret | Per què |
|---|---|
| Al codi font | Acaba al dipòsit, i a git l'historial és permanent: esborrar la línia no esborra el commit |
| A la línia d'ordres | Qualsevol usuari del sistema la veu amb ps aux mentre el procés corre |
| En una variable d'entorn d'un procés | Llegible a /proc/<pid>/environ pel seu propietari i per root; i s'hereta als processos fills |
| Als registres | Un set -x o un log "connectant amb $PASS" l'escriu al journal, que es conserva 30 dies |
| En una còpia de seguretat sense xifrar | És l'incident que ja vas viure: la còpia amb permisos 644 |
| En un fitxer de configuració llegible | És l'estat actual d'app.conf, i és el que es corregeix en aquesta lliçó |
Els dos primers mereixen una demostració, perquè la gent els subestima:
# Un secret a la linia d ordres es public mentre el proces viu
$ ps aux | grep -m1 'psql'
luis 3417 0.0 0.1 ... psql -h 10.0.2.15 -U tramontana --password=Zx9K2pQ
# I l entorn d un proces es llegible pel seu propietari
$ sudo tr '\0' '\n' < /proc/1284/environ | grep -i pass
TRAMONTANA_DB_PASSWORD=Zx9K2pQSobre el segon cas convé ser precís, perquè hi ha un matís que sovint es malinterpreta: /proc/<pid>/environ té permisos 0400 i només el poden llegir el propietari del procés i root. Això fa que les variables d'entorn siguin molt millors que la línia d'ordres, però no les converteix en un bon lloc: s'hereten a tot procés fill, apareixen en abocaments de memòria i en traces d'error de molts entorns de treball, i qualsevol escalada a root les exposa totes de cop.
El mínim decent: permisos, EnvironmentFile i LoadCredential
No cal infraestructura per millorar substancialment. Amb el que ja saps de permisos (02-07), usuaris de servei (05-01) i unitats de systemd (05-05), hi ha tres nivells, cadascun millor que l'anterior.
Nivell 1: fitxer de secrets amb permisos estrictes
La idea és separar el secret de la configuració: app.conf deixa de contenir la contrasenya i passa a ser un fitxer llegible pel grup, mentre el secret viu en un fitxer a part amb permisos mínims.
# El fitxer de secrets: propietat de l usuari del servei, nomes ell pot llegir-lo
$ sudo install -o svc-tramontana -g svc-tramontana -m 600 /dev/null \
/etc/tramontana/secrets.env
$ sudo tee /etc/tramontana/secrets.env >/dev/null <<'EOF'
TRAMONTANA_DB_PASSWORD=Zx9K2pQ7vLm4RtWn
EOF
$ sudo ls -l /etc/tramontana/
total 8
-rw-r----- 1 root tramontana 312 ago 18 12:04 app.conf
-rw------- 1 svc-tramontana svc-tramontana 42 ago 18 12:06 secrets.envI la unitat el carrega a l'entorn del servei, sense que aparegui mai a la línia d'ordres:
# /etc/systemd/system/tramontana.service.d/override.conf
[Service]
EnvironmentFile=/etc/tramontana/secrets.envRecorda la convenció del curs: app.conf està chattr +i, així que per editar-lo cal treure l'atribut, canviar, i tornar-lo a posar — amb la seva còpia prèvia:
$ sudo cp -p /etc/tramontana/app.conf /etc/tramontana/app.conf.bak-$(date +%F)
$ sudo chattr -i /etc/tramontana/app.conf
$ sudo sed -i.bak-$(date +%F) '/^db_password/d' /etc/tramontana/app.conf
$ sudo chattr +i /etc/tramontana/app.conf
$ sudo diff -u /etc/tramontana/app.conf.bak-$(date +%F) /etc/tramontana/app.conf
--- /etc/tramontana/app.conf.bak-2026-08-18
+++ /etc/tramontana/app.conf
@@ -3,7 +3,6 @@
db_name=tramontana_reserves
-db_password=Zx9K2pQ7vLm4RtWn
max_connexions=200Això ja tanca l'exposició de l'últim exercici de 06-04: un chmod 644 accidental sobre app.conf ja no filtra res. Però el secret continua en clar al disc i a l'entorn del procés.
Nivell 2: LoadCredential
Ubuntu 24.04 porta la mecànica de credencials de systemd, que és clarament superior: el secret es lliura al servei en un fitxer dins d'un tmpfs privat accessible només per aquell servei, no s'hereta als fills i no apareix a l'entorn.
# /etc/systemd/system/tramontana.service.d/override.conf
[Service]
LoadCredential=db_password:/etc/tramontana/secrets/db_password$ sudo install -d -o root -g root -m 700 /etc/tramontana/secrets
$ printf '%s' 'Zx9K2pQ7vLm4RtWn' | sudo tee /etc/tramontana/secrets/db_password >/dev/null
$ sudo chmod 600 /etc/tramontana/secrets/db_passwordEl servei rep la ruta a la variable CREDENTIALS_DIRECTORY i llegeix el fitxer:
# Dins del servei, el secret es a:
# ${CREDENTIALS_DIRECTORY}/db_password
$ systemd-run --property=LoadCredential=prova:/etc/tramontana/secrets/db_password \
--pty bash -c 'ls -l "$CREDENTIALS_DIRECTORY"; cat "$CREDENTIALS_DIRECTORY/prova"'
total 0
-r--r----- 1 root root 16 ago 18 12:22 prova
Zx9K2pQ7vLm4RtWnLa diferència amb EnvironmentFile en una taula, perquè decideix l'elecció:
EnvironmentFile= |
LoadCredential= |
|
|---|---|---|
Visible a /proc/<pid>/environ |
Sí | No |
| S'hereta als processos fills | Sí | No |
Apareix a systemctl show |
Sí (el nom del fitxer) | Només la ruta d'origen |
Funciona amb ProtectSystem=strict |
Sí | Sí, i el tmpfs és privat |
| Compatible amb qualsevol aplicació | Sí, gairebé totes llegeixen de l'entorn | Requereix que l'aplicació llegeixi d'un fitxer |
Nivell 3: systemd-creds, secret xifrat al disc
El pas que tanca el cercle: systemd-creds xifra el secret amb una clau derivada del sistema (i del TPM si existeix), de manera que el fitxer al disc ja no conté el secret en clar.
$ printf '%s' 'Zx9K2pQ7vLm4RtWn' \
| sudo systemd-creds encrypt --name=db_password - /etc/tramontana/secrets/db_password.cred
$ sudo cat /etc/tramontana/secrets/db_password.cred | head -c 80
-----BEGIN CREDENTIAL-----
CqiVzUCu5c1TF4TBTdxr4hK+3XPqmn9lBTJmMWk0YjMwNzY2MzQ0ZTk...# /etc/systemd/system/tramontana.service.d/override.conf
[Service]
LoadCredentialEncrypted=db_password:/etc/tramontana/secrets/db_password.cred$ sudo systemctl daemon-reload && sudo systemctl restart tramontana.service
$ sudo systemctl status tramontana.service --no-pager | head -5
● tramontana.service - Tramontana Reserves
Loaded: loaded (/etc/systemd/system/tramontana.service; enabled)
Active: active (running) since Tue 2026-08-18 12:31:08 CEST; 4s ago
Main PID: 4102 (tramontana)
# Verificacio: el secret ja no es a l entorn del proces
$ sudo tr '\0' '\n' < /proc/4102/environ | grep -ci pass
0Aquell 0 és el resultat que buscaves. El tercer incident obert queda tancat: la contrasenya ja no està en clar en cap fitxer de configuració, no és a l'entorn del procés, no és llegible per cap usuari del sistema, i —conseqüència important— tampoc no viatja en clar dins de la còpia de restic, perquè el que es copia és el fitxer xifrat.
Una limitació honesta: la clau de xifratge de systemd-creds està lligada a la màquina (/var/lib/systemd/credential.secret). Això és exactament el que vols davant de la fuita d'un fitxer, però significa que el fitxer .cred no es pot restaurar en un servidor reconstruït. El secret original ha d'estar també en un lloc del qual el puguis recuperar: això és la secció següent, i és el que ha de constar al manual d'operació de 05-08.
Xifratge en repòs de secrets: GPG i pass
Necessites un lloc on el secret original visqui xifrat, recuperable per una persona autoritzada, amb historial de canvis i fora del servidor. La resposta clàssica a Linux és GPG, i pass construïda al damunt.
GPG en dos modes
# Simetric: una frase de pas, sense claus. Simple i suficient per a un fitxer puntual
$ gpg -c --cipher-algo AES256 manual-credencials.txt
$ ls manual-credencials.txt.gpg
$ gpg -d manual-credencials.txt.gpg > /dev/shm/recuperat.txt
# Asimetric: xifrat per a destinataris concrets, sense compartir cap frase de pas
$ gpg --quick-generate-key "operador (Tramontana) <[email protected]>" ed25519 cert 2y
$ gpg -e -r [email protected] -r [email protected] secrets.txt
$ gpg -d secrets.txt.gpgLa diferència pràctica és de gestió: el mode simètric obliga a transmetre la frase de pas per un altre canal i a canviar-la quan algú deixa l'equip; l'asimètric permet xifrar per a diverses persones i revocar l'accés d'una sense tornar a xifrar per a les altres. En un equip, sempre asimètric.
Fixa't en el > /dev/shm/recuperat.txt del desxifratge: /dev/shm és memòria, no disc. Escriure un secret desxifrat al sistema de fitxers deixa restes recuperables fins i tot després d'esborrar-lo.
pass: el gestor construït sobre GPG
pass guarda cada secret en un fitxer xifrat amb GPG dins d'un dipòsit git. És simple, auditable i no depèn de cap servei.
$ sudo apt install pass
$ pass init [email protected]
mkdir: created directory '/home/operador/.password-store/'
Password store initialized for [email protected]
$ pass git init
$ pass insert tramontana/produccio/db_password
Enter password for tramontana/produccio/db_password:
Retype password for tramontana/produccio/db_password:
[master 8f2c1a4] Add given password for tramontana/produccio/db_password to store.
$ pass insert -m tramontana/produccio/restic
# (-m permet diverses linies: contrasenya, diposit, notes)
$ pass ls
Password Store
└── tramontana
└── produccio
├── db_password
└── restic
$ pass tramontana/produccio/db_password
Zx9K2pQ7vLm4RtWn
$ pass -c tramontana/produccio/db_password
Copied tramontana/produccio/db_password to clipboard. Will clear in 45 seconds.Tres detalls que el fan apte per a producció:
-
Historial complet amb git.
pass git log --onelinemostra cada alta, canvi i baixa, amb data i autor. És la traçabilitat de la rotació. -
Els fitxers estan xifrats, així que el dipòsit es pot sincronitzar a un remot sense exposar res:
pass git remote add origin ...ipass git push. Això resol el «fora del servidor». -
Composició amb scripts.
passescriu a stdout, així que encaixa amb el del Mòdul 4:# Generar el fitxer .cred des de pass, sense que el secret toqui el disc en clar $ pass tramontana/produccio/db_password \\ | sudo systemd-creds encrypt --name=db_password - \\ /etc/tramontana/secrets/db_password.credAquella canonada és la resposta al problema de recuperabilitat de l'apartat anterior:
passés la font de veritat,systemd-credsla còpia operativa lligada a la màquina, i reconstruir el servidor consisteix a tornar a executar aquesta línia.
I l'advertiment obvi: la clau GPG privada i la seva frase de pas són ara la clau mestra. La seva còpia de seguretat (gpg --export-secret-keys, xifrada, en un mitjà físic separat) i la seva custòdia són part del manual d'operació, i la seva pèrdua equival a perdre tots els secrets.
Xifratge de disc amb LUKS
Els secrets ja estan xifrats, però /srv/tramontana/backups conté reserves.csv amb noms d'hostes. Si algú s'endú el disc —o la imatge de la VM, o el disc d'un servidor retirat sense esborrar—, els permisos del sistema de fitxers no protegeixen res: es munten en una altra màquina i es llegeix tot.
LUKS és l'estàndard de xifratge de bloc a Linux. Xifra el dispositiu complet, per sota del sistema de fitxers.
# Sobre un dispositiu NOU o el contingut del qual puguis perdre: luksFormat DESTRUEIX les dades
$ sudo cryptsetup luksFormat --type luks2 /dev/vg-dades/lv-backups
WARNING!
========
This will overwrite data on /dev/vg-dades/lv-backups irrevocably.
Are you sure? (Type 'yes' in capital letters): YES
Enter passphrase for /dev/vg-dades/lv-backups:
$ sudo cryptsetup luksOpen /dev/vg-dades/lv-backups backups-xifrat
$ sudo mkfs.ext4 -L backups /dev/mapper/backups-xifrat
$ sudo mount /dev/mapper/backups-xifrat /srv/tramontana/backups
$ sudo cryptsetup luksDump /dev/vg-dades/lv-backups | head -8
LUKS header information
Version: 2
Epoch: 3
Metadata area: 16384 [bytes]
Keyslots:
0: luks2
Key: 512 bits
Cipher: aes-xts-plain64I aquí hi ha el problema real, que cal plantejar sense adorns: un volum LUKS necessita una frase de pas per obrir-se, i un servidor ha d'arrencar tot sol a les 3 de la matinada. Les opcions, amb el seu compromís:
| Opció | Com | Cost |
|---|---|---|
| Frase de pas manual | Algú la teclegi en cada arrencada | Protecció màxima; el servidor no arrenca sense intervenció |
| Fitxer de clau al disc arrel | /etc/crypttab amb keyfile |
Automàtic; protegeix només contra el robatori del disc de dades, no de l'arrel |
| TPM | systemd-cryptenrol --tpm2-device=auto |
Automàtic i lligat al maquinari; requereix TPM i una configuració acurada |
| Desbloqueig remot en l'arrencada | dropbear-initramfs |
Automàtic amb supervisió; més peces per mantenir |
Per al laboratori, l'opció del fitxer de clau amb nofail és raonable, i és important entendre exactament què protegeix:
# /etc/crypttab
# nom dispositiu (per UUID) clau opcions
backups-xifrat UUID=8f4c2a19-7d3e-4b1a-9c85-2e6f0a4d7b31 /etc/luks/backups.key luks,nofail$ sudo install -d -m 700 /etc/luks
$ sudo dd if=/dev/urandom of=/etc/luks/backups.key bs=512 count=1
$ sudo chmod 400 /etc/luks/backups.key
$ sudo cryptsetup luksAddKey /dev/vg-dades/lv-backups /etc/luks/backups.key# /etc/fstab (la linia de backups passa a apuntar al dispositiu desbloquejat)
/dev/mapper/backups-xifrat /srv/tramontana/backups ext4 defaults,noatime,nodev,nosuid,nofail 0 2# La xarxa de seguretat obligatoria abans de reiniciar, com a 05-04
$ sudo systemctl daemon-reload && sudo mount -a && findmnt /srv/tramontana/backupsQuè protegeix i què no protegeix, dit amb precisió: protegeix contra el robatori o la retirada del disc de dades, contra l'accés a la imatge de la VM aturada, i contra la recuperació de dades d'un disc llençat. No protegeix contra un atacant que compromet el servidor en marxa, perquè per a ell el volum està muntat i llegible com per a qualsevol. És xifratge en repòs, no xifratge en ús, i presentar-ho com una altra cosa davant de la Marta seria enganyar-la.
Fixa't a més en la composició amb l'anterior: restic ja xifra el seu dipòsit amb la seva pròpia contrasenya —que ara viu a pass—, així que les còpies tenen dues capes independents. I per a la destinació externa de la regla 3-2-1, el xifratge de restic és el que de debò importa, perquè el mitjà remot no el controles tu.
Gestors centralitzats de secrets
Tot l'anterior és correcte per a una màquina. Quan n'hi ha diverses, apareix un problema nou: distribuir i rotar secrets en N servidors sense copiar-los a mà.
| Solució | Model | Quan compensa |
|---|---|---|
pass + git |
Fitxers GPG en un dipòsit | 1-5 màquines, un equip petit, sense dependències |
sops + age |
Xifra només els valors d'un YAML/JSON, versionable a git | Configuració com a codi; encaixa molt bé amb Ansible (07-06) |
| HashiCorp Vault | Servei amb API, polítiques, auditoria i secrets dinàmics de vida curta | Desenes de màquines, diversos equips, requisits d'auditoria |
| Secrets Manager del núvol (AWS/GCP/Azure) | Servei gestionat integrat amb IAM | Infraestructura ja en aquell proveïdor |
El salt de rendibilitat té un llindar bastant identificable: quan rotar una credencial deixa de ser una tasca de cinc minuts. Amb un servidor, rotar és canviar pass, regenerar el .cred i reiniciar el servei. Amb vint, sense un gestor central, és una operació manual propensa a deixar màquines a mitges — que és el pitjor dels mons, perquè tens el cost de la rotació sense la garantia.
sops mereix una menció concreta perquè serà rellevant a 07-06: permet tenir a git un fitxer de variables d'Ansible en què les claus són llegibles i els valors estan xifrats, de manera que el diff d'un canvi de configuració continua sent revisable sense exposar els secrets.
L'altre avantatge de Vault que no tenen les altres són els secrets dinàmics: en lloc d'una contrasenya de base de dades fixa, genera credencials amb validesa d'una hora, específiques de cada procés. Un secret que caduca sol no necessita rotació, i una fuita té una finestra d'explotació mínima. És el model cap al qual tendeix la indústria.
Rotació de credencials
Rotar és canviar un secret per un altre de nou. És obligatori perquè la probabilitat que un secret estigui compromès només creix amb el temps: cada còpia, cada registre, cada persona que el va veure, cada màquina on va estar. Rotar limita la finestra d'explotació d'una fuita que potser ja va passar i no ho saps.
Quan rotar, en ordre d'urgència:
- Immediatament, davant de qualsevol sospita d'exposició. És el que vas fer amb
db_passwordquan va aparèixer a la còpia amb permisos 644, i el que faria el desenllaç B de l'últim exercici de 06-04. - Quan algú amb accés deixa l'equip. No és desconfiança: és que el control sobre qui coneix el secret s'ha perdut.
- Periòdicament, amb un termini escrit. Per a una credencial de servei com aquesta, entre 90 dies i un any és l'habitual, segons l'exposició.
El procediment sense tallar el servei és la part amb contingut tècnic, i depèn d'una propietat del sistema de destinació: que accepti dues credencials vàlides alhora. PostgreSQL no ho fa amb el mateix compte, així que el patró és de dos usuaris:
# 1. Crear la credencial nova al costat de la vella (totes dues valides)
$ sudo -u postgres psql -c \
"CREATE ROLE tramontana_app2 LOGIN PASSWORD 'nova-clau-generada';"
$ sudo -u postgres psql -c \
"GRANT ALL PRIVILEGES ON DATABASE tramontana_reserves TO tramontana_app2;"
# 2. Guardar-la a la font de veritat, amb historial
$ pass insert tramontana/produccio/db_password
$ pass git log --oneline -1
a3f1c88 Add given password for tramontana/produccio/db_password to store.
# 3. Actualitzar la copia operativa i aplicar
$ pass tramontana/produccio/db_password \
| sudo systemd-creds encrypt --name=db_password - \
/etc/tramontana/secrets/db_password.cred
$ sudo systemctl restart tramontana.service
# 4. VERIFICAR abans de retirar la vella
$ ~/scripts/revisio_salut.sh; echo "estat: $?"
estat: 0
# 5. Nomes ara, retirar la credencial antiga
$ sudo -u postgres psql -c "DROP ROLE tramontana_app;"L'ordre és el que importa: crear, aplicar, verificar, retirar. Invertir els dos últims passos deixa el servei caigut fins que algú se n'adoni, i a les 3 de la matinada això són hores. És la mateixa disciplina de «mesurar abans i després» que vas aplicar a 05-07.
Una generació de contrasenyes decent, per no cedir a la temptació d'inventar-les:
$ pass generate -n tramontana/produccio/db_password 32
$ openssl rand -base64 24 # alternativa sense pass
Kj8mQ2vX9pLnR4tW7cYbF3sZ6dHaQuè garanteix TLS i què conté un certificat
Segona meitat de la lliçó. TLS (Transport Layer Security, el successor d'SSL) dona tres garanties, i convé separar-les perquè la tercera és la que gairebé tothom oblida:
| Garantia | Què significa | Sense ella |
|---|---|---|
| Confidencialitat | Ningú del camí no pot llegir el contingut | Qui sigui a la xarxa veu les dades dels hostes |
| Integritat | Ningú no pot modificar el contingut sense que es detecti | Es pot alterar una reserva en trànsit |
| Autenticació | Estàs parlant amb qui creus | Xifres perfectament... amb l'atacant |
La tercera és la raó que existeixin els certificats. El xifratge sense autenticació és inútil davant d'un intermediari: si un atacant s'hi interposa, negocia una connexió xifrada amb tu i una altra amb el servidor real, ho llegeix tot. És el mateix raonament de l'avís d'empremta d'SSH a 06-02.
I el que TLS no garanteix: que el servidor sigui honest, que l'aplicació sigui segura, que les dades estiguin xifrades en repòs, ni que qui es connecta sigui qui diu (per a això cal autenticar el client).
La cadena de confiança
El problema a resoldre és d'arrencada: com confiar en la clau pública d'un servidor que no havies vist mai. La solució és delegar en un tercer en qui ja confies.
graph TD
R["CA arrel<br/>(al magatzem del sistema<br/>i del navegador)"] -->|signa| I["CA intermedia<br/>(p. ex. Let's Encrypt E6)"]
I -->|signa| H["Certificat fulla<br/>reserves.tramontana.example"]
H -.->|conte| K["Clau publica del servidor"]
S["Clau privada<br/>(mai surt del servidor)"] -.->|parella de| K
La verificació consisteix a comprovar, cap amunt, que cada certificat està signat pel següent, fins a arribar a una arrel que ja és al magatzem local (/etc/ssl/certs/, del paquet ca-certificates). L'autoritat de certificació arrel signa poc i viu molt protegida; les intermèdies fan la feina del dia a dia i es poden revocar sense invalidar l'arrel.
Què hi ha dins d'un certificat
Un certificat és la clau pública del servidor més un conjunt d'afirmacions, tot signat per l'autoritat de certificació:
| Camp | Contingut | Nota |
|---|---|---|
| Subject | A qui identifica | El CN està obsolet per a noms d'amfitrió |
| SAN (Subject Alternative Name) | Els noms vàlids | És el camp que es valida avui |
| Issuer | Qui el va signar | Enllaça amb la cadena |
| Not Before / Not After | Finestra de validesa | La causa de la fallada més comuna |
| Public Key | Clau pública i algorisme | ECDSA P-256 o RSA 2048+ |
| Key Usage / Extended Key Usage | Per a què es pot fer servir | serverAuth, clientAuth |
El punt sobre el SAN és pràctic, no anecdòtic: des de fa anys els navegadors i les biblioteques TLS ignoren el CN i validen exclusivament contra el SAN. Un certificat amb CN=reserves.tramontana.example i sense SAN és rebutjat. És una font clàssica d'hores perdudes en generar certificats a mà.
L'encaixada de mans de TLS 1.3, en cinc línies i sense entrar en criptografia:
- El client envia els algorismes que admet i la seva aportació a l'intercanvi de claus.
- El servidor tria, envia la seva i el seu certificat.
- El client verifica el certificat contra el seu magatzem d'autoritats de certificació i comprova que el nom és al SAN.
- Tots dos deriven la mateixa clau de sessió sense haver-la transmès mai.
- A partir d'aquí, tot va xifrat amb aquella clau. Un sol viatge d'anada i tornada.
Generar, llegir i verificar material criptogràfic amb OpenSSL
openssl és la navalla suïssa de l'àrea. Quatre operacions cobreixen el 90 % de la feina.
Generar una clau privada i una petició de signatura
# Clau privada ECDSA P-256: mes curta i rapida que RSA, amb seguretat equivalent a RSA 3072
$ openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 \
-out reserves.key
$ chmod 600 reserves.key
# CSR amb el SAN correctament posat (la part que s oblida)
$ openssl req -new -key reserves.key -out reserves.csr \
-subj "/CN=reserves.tramontana.example/O=Tramontana S.L./C=ES" \
-addext "subjectAltName=DNS:reserves.tramontana.example,DNS:www.reserves.tramontana.example"
$ openssl req -in reserves.csr -noout -text | grep -A2 'Alternative'
X509v3 Subject Alternative Name:
DNS:reserves.tramontana.example, DNS:www.reserves.tramontana.exampleLa CSR (Certificate Signing Request) conté la clau pública i els noms sol·licitats, i va signada amb la clau privada per demostrar que la posseeixes. La clau privada no surt mai del servidor.
Autosignat per a proves
$ openssl x509 -req -in reserves.csr -signkey reserves.key -days 365 \
-copy_extensions copyext -out reserves-autosignat.crtAquell -copy_extensions copyext és imprescindible: sense ell, el SAN de la CSR no es copia al certificat i n'obtens un d'inservible. És l'error més freqüent en generar certificats de prova a mà.
Un autosignat serveix per provar la configuració del servidor, i només per a això: cap autoritat de certificació no el respatlla, així que tot client avisarà. Mai en producció.
Llegir i verificar
$ openssl x509 -in /etc/letsencrypt/live/reserves.tramontana.example/cert.pem \
-noout -text | grep -A1 -E 'Issuer:|Not Before|Not After|Alternative'
Issuer: C = US, O = Let's Encrypt, CN = E6
Not Before: Aug 18 09:12:41 2026 GMT
Not After : Nov 16 09:12:40 2026 GMT
X509v3 Subject Alternative Name:
DNS:reserves.tramontana.example
# Verificar la cadena completa contra el magatzem del sistema
$ openssl verify -untrusted /etc/letsencrypt/live/reserves.tramontana.example/chain.pem \
/etc/letsencrypt/live/reserves.tramontana.example/cert.pem
/etc/letsencrypt/live/reserves.tramontana.example/cert.pem: OK
# Comprovar que la clau privada correspon al certificat (els moduls han de coincidir)
$ openssl pkey -in privkey.pem -pubout -outform DER | sha256sum
$ openssl x509 -in cert.pem -pubkey -noout -outform DER | sha256sumAquella última comprovació resol una fallada desconcertant i freqüent: el servidor no arrenca o rebutja les connexions perquè la clau i el certificat no són parella, típicament després de regenerar-ne una i oblidar l'altra. Si les dues sumes coincideixen, són parella.
I la inspecció d'un servidor en marxa:
$ openssl s_client -connect reserves.tramontana.example:443 \
-servername reserves.tramontana.example </dev/null 2>/dev/null \
| openssl x509 -noout -dates -subject
notBefore=Aug 18 09:12:41 2026 GMT
notAfter=Nov 16 09:12:40 2026 GMT
subject=CN = reserves.tramontana.exampleEl -servername és obligatori quan hi ha diversos llocs a la mateixa IP: és l'extensió SNI, que indica quin certificat vols. Sense ell rebràs el certificat per defecte i creuràs que hi ha un problema on no n'hi ha.
Let's Encrypt i la renovació automàtica
Let's Encrypt és una autoritat de certificació gratuïta i automatitzada. El seu protocol, ACME, funciona sobre una idea simple: per demostrar que controles un domini, l'autoritat de certificació et demana que facis una cosa que només el seu titular podria fer.
| Desafiament | Què exigeix | Quan fer-lo servir |
|---|---|---|
| HTTP-01 | Servir un fitxer a http://domini/.well-known/acme-challenge/<token> |
Per defecte; necessita el port 80 accessible des d'Internet |
| DNS-01 | Publicar un registre TXT _acme-challenge.domini |
Quan el 80 no és accessible, i obligatori per a comodins |
| TLS-ALPN-01 | Respondre al 443 amb una extensió ALPN | Quan el 80 està tancat però el 443 no |
El DNS-01 és imprescindible en dos casos: certificats comodí (*.tramontana.example) i servidors que no exposen el port 80 — i requereix que el proveïdor de DNS tingui API, o fer-ho a mà en cada renovació, que no és viable.
I aquí s'aplica l'avís d'abast del principi: Nginx es munta a 08-01, així que ara es fa servir el mode --standalone, en què certbot aixeca el seu propi servidor temporal al port 80. Recorda que a 06-03 vas deixar el 443 obert però el 80 no: cal obrir-lo abans.
$ sudo ufw allow 80/tcp comment 'ACME HTTP-01'
$ sudo certbot certonly --standalone \
-d reserves.tramontana.example \
--email [email protected] \
--agree-tos --no-eff-email
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/reserves.tramontana.example/fullchain.pem
Key is saved at: /etc/letsencrypt/live/reserves.tramontana.example/privkey.pem
This certificate expires on 2026-11-16.Els quatre fitxers que genera, perquè cada servidor en demana un de diferent:
| Fitxer | Contingut | Qui el fa servir |
|---|---|---|
privkey.pem |
Clau privada | Sempre; permisos estrictes |
cert.pem |
Només el certificat fulla | Configuracions antigues |
chain.pem |
Només les intermèdies | Grapat OCSP |
fullchain.pem |
Fulla + intermèdies | L'habitual: Nginx, Apache modern |
Servir cert.pem en lloc de fullchain.pem és un error clàssic: funciona al navegador d'escriptori, que sol tenir la intermèdia a la memòria cau, i falla en clients mòbils i a curl. Es detecta amb openssl s_client mirant si la cadena està completa.
La renovació, i per què provar-la
Els certificats de Let's Encrypt duren 90 dies. Això obliga a automatitzar, que és intencionat: una renovació automatitzada i provada falla menys que una d'anual feta a mà.
$ systemctl list-timers certbot.timer --no-pager
NEXT LEFT LAST PASSED UNIT ACTIVATES
Tue 2026-08-18 22:47:19 CEST 10h left - - certbot.timer certbot.service
# La prova, que fa TOT el proces real contra l entorn de proves de la CA
$ sudo certbot renew --dry-run
Simulating renewal of an existing certificate for reserves.tramontana.example
Congratulations, all simulated renewals succeeded.--dry-run és la línia més important d'aquesta secció. La renovació falla, típicament, pel port 80 tancat per una regla nova del tallafocs, per un servei ocupant aquell port, o per un --deploy-hook trencat. I falla en silenci, 60 dies després que introduïssis el canvi, quan ja ningú no recorda haver-lo fet. Provar en sec després de cada canvi de xarxa o de tallafocs és la disciplina que evita aquell escenari.
El ganxo de desplegament és el que recarrega el servei després de renovar:
$ sudo tee /etc/letsencrypt/renewal-hooks/deploy/10-recarregar >/dev/null <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
systemctl is-active --quiet nginx && systemctl reload nginx
logger -t certbot -p local0.notice "certificat renovat i servei recarregat"
EOF
$ sudo chmod 700 /etc/letsencrypt/renewal-hooks/deploy/10-recarregarUn certificat renovat que el servei no ha recarregat no serveix: el procés continua presentant el vell fins que es reiniciï. És una altra fallada silenciosa clàssica.
Sobre mTLS (autenticació mútua), breument: el servidor exigeix també un certificat de client. És excel·lent per a la comunicació entre serveis —molt millor que una clau d'API— i desaconsellable per a persones, pel cost de distribuir i renovar certificats a cada dispositiu.
Bones pràctiques de TLS, custòdia de la clau i vigilància de la caducitat
Configuració
Els criteris vigents, que s'aplicaran a 08-01 en configurar Nginx:
- Només TLS 1.2 i TLS 1.3. SSL 3.0, TLS 1.0 i 1.1 estan retirats per vulnerabilitats conegudes i cap client actual no els necessita.
- Suites amb confidencialitat persistent (ECDHE), perquè el compromís futur de la clau privada no permeti desxifrar trànsit capturat en el passat.
- HSTS, la capçalera
Strict-Transport-Security, que diu al navegador que faci servir HTTPS sempre per a aquest domini. Compte: és difícil de revertir, així que primer ambmax-agecurt. - No inventis la llista de suites. Fes servir el generador de
ssl-config.mozilla.orgi el seu perfil intermediate, que és l'equilibri raonable entre seguretat i compatibilitat, i revisa'l periòdicament.
Custòdia de la clau privada
$ sudo ls -l /etc/letsencrypt/live/reserves.tramontana.example/privkey.pem
-rw-r----- 1 root ssl-cert 241 ago 18 11:12 privkey.pem640 root:ssl-cert és el patró: root escriu, el grup ssl-cert llegeix, ningú més. El procés que necessita la clau s'afegeix a aquell grup — mai no es fa la clau llegible per tothom.
Si la clau privada es filtra, no n'hi ha prou de generar-ne una de nova: cal revocar l'anterior, perquè continua sent vàlida fins a la seva caducitat i permetria a qui la tingui suplantar el teu servei:
$ sudo certbot revoke --cert-path /etc/letsencrypt/live/reserves.tramontana.example/cert.pem \
--reason keyCompromise
$ sudo certbot certonly --standalone -d reserves.tramontana.example --force-renewalAmb honestedat sobre la seva eficàcia: la revocació depèn que el client la comprovi, i molts no ho fan o fallen de manera permissiva. És necessària però no suficient; el pla de resposta ha d'assumir que la clau filtrada continua sent utilitzable un temps.
Vigilar la caducitat
La fallada més ximple i més freqüent de producció és un certificat caducat. Passa fins i tot amb renovació automàtica, perquè l'automatització també es trenca. La mesura és un control independent que no confiï en el mecanisme de renovació, en la línia de comprovar_copia.sh de 05-08:
$ cat ~/scripts/revisar_certificat.sh
#!/usr/bin/env bash
# revisar_certificat.sh - Avisa si un certificat TLS caduca aviat.
# Us: revisar_certificat.sh [-d dies] [-H host] [-p port]
# Sortida: 0 correcte | 1 avis (caduca aviat) | 2 critic (caducat o inabastable)
set -euo pipefail
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=lib/comuns.sh
source "${SCRIPT_DIR}/lib/comuns.sh"
readonly ETIQUETA_LOG="revisar-certificat"
main() {
local dies_avis="${TRAMONTANA_CERT_DIES:-20}"
local host="${TRAMONTANA_CERT_HOST:-reserves.tramontana.example}"
local port="${TRAMONTANA_CERT_PORT:-443}"
while getopts ":d:H:p:h" opcio; do
case "$opcio" in
d) dies_avis="$OPTARG" ;;
H) host="$OPTARG" ;;
p) port="$OPTARG" ;;
h) sed -n '2,4s/^# \?//p' "$0"; return 0 ;;
*) morir 64 "opcio no valida: -$OPTARG" ;;
esac
done
requereix_comanda openssl
es_numero "$dies_avis" || morir 64 "els dies han de ser un numero: $dies_avis"
local fi_text
if ! fi_text="$(timeout 10 openssl s_client -connect "${host}:${port}" \
-servername "$host" </dev/null 2>/dev/null \
| openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)"; then
error "no s ha pogut obtenir el certificat de ${host}:${port}"
return 2
fi
[[ -n "$fi_text" ]] || { error "resposta buida de ${host}:${port}"; return 2; }
local fi_epoch ara_epoch dies_restants
fi_epoch="$(date -d "$fi_text" +%s)"
ara_epoch="$(date +%s)"
dies_restants=$(( (fi_epoch - ara_epoch) / 86400 ))
if (( dies_restants < 0 )); then
error "CADUCAT fa $(( -dies_restants )) dies: $host"
return 2
fi
if (( dies_restants <= dies_avis )); then
error "caduca en ${dies_restants} dies (llindar ${dies_avis}): $host"
return 1
fi
log "certificat de $host correcte, caduca en ${dies_restants} dies"
return 0
}
main "$@"$ chmod +x ~/scripts/revisar_certificat.sh
$ shellcheck ~/scripts/revisar_certificat.sh && echo "sense avisos"
sense avisos
$ ~/scripts/revisar_certificat.sh; echo "estat: $?"
certificat de reserves.tramontana.example correcte, caduca en 90 dies
estat: 0Els 20 dies de llindar no són arbitraris: amb certificats de 90 dies, certbot renova als 60, així que queden 30 dies de marge. Un avís als 20 significa que la renovació automàtica ha fallat dues vegades i encara hi ha gairebé tres setmanes per arreglar-ho amb calma.
I com que l'script retorna 0/1/2 igual que revisio_salut.sh, s'integra sense fricció amb la comprovació general i amb el monitoratge.
Errors Comuns i Consells
- Generar un certificat sense SAN. El
CNja no es valida. Sense-addext "subjectAltName=..."a la CSR i sense-copy_extensions copyexten autosignar, obtens un certificat que tot client rebutja. - Servir
cert.pemen lloc defullchain.pem. Funciona al teu navegador —té la intermèdia a la memòria cau— i falla en mòbils i acurl. Verifica sempre ambopenssl s_clientdes d'una altra màquina. - No provar la renovació en sec.
certbot renew --dry-rundesprés de cada canvi de tallafocs o de servidor web. Si no, te n'assabentes 60 dies després, quan el certificat caduca de debò. - Oblidar el ganxo de desplegament. Un certificat renovat que el servei no ha recarregat no serveix de res: el procés continua presentant el vell.
- Passar un secret per la línia d'ordres.
--password=Xés visible apsper a tot el sistema. Fes servir un fitxer, l'entrada estàndard o el mecanisme de credencials del programa. - Desxifrar un secret a un fitxer al disc. Deixa restes recuperables. Fes servir
/dev/shm, una canonada, opass -camb porta-retalls temporal. - Creure que LUKS protegeix un servidor en marxa. Protegeix el disc robat o llençat, no el sistema compromès, on el volum ja està muntat. Dir-ho malament en un informe és pitjor que no posar-ho.
- Rotar retirant la credencial antiga abans de verificar la nova. Crear, aplicar, verificar, retirar. Aquell ordre, sempre.
- Perdre la clau GPG de
passsense còpia. És la clau mestra de tots els teus secrets. La seva còpia xifrada i la seva custòdia són part del manual d'operació, no un detall. - Consell de mètode. Anota al manual d'operació, per a cada secret: on és la font de veritat, qui el pot recuperar, quan es va rotar per última vegada i cada quant toca. Un inventari de secrets sense dates és un inventari que ningú no manté.
Exercicis
Exercici 1
restic necessita la seva contrasenya de dipòsit per executar la còpia nocturna sense intervenció humana. Avui és en un fitxer 600 propietat de root llegit per copia_tramontana.sh. Redissenya la solució fent servir pass com a font de veritat i el mecanisme de credencials de systemd, i explica el problema de recuperabilitat que apareix i com el resols.
Exercici 2
Reps aquest avís i l'has de diagnosticar:
$ ~/scripts/revisar_certificat.sh
[2026-11-10 08:00:03] ERROR revisar-certificat: caduca en 6 dies (llindar 20): reserves.tramontana.examplecertbot.timer està actiu i certbot renew no ha donat cap error visible al journal. Enumera les causes possibles en ordre de probabilitat, amb l'ordre que confirma o descarta cadascuna.
Exercici 3
La Marta et demana per escrit «que el xifratge protegeixi les dades dels hostes». Redacta l'informe amb les tres capes de xifratge que has muntat —secrets amb systemd-creds i pass, disc amb LUKS, trànsit amb TLS—, indicant per a cadascuna què protegeix i què no protegeix, i quin risc sobre les dades d'hostes continua obert malgrat les tres.
Solucions
Solució 1
# 1. La font de veritat, amb historial i sincronitzable fora del servidor
$ pass insert -m tramontana/produccio/restic
Enter contents of tramontana/produccio/restic and press Ctrl+D when finished:
<contrasenya-del-diposit>
diposit: /srv/tramontana/backups/restic
rotada: 2026-08-18
# 2. La copia operativa, xifrada i lligada a la maquina
$ pass tramontana/produccio/restic | head -1 \
| sudo systemd-creds encrypt --name=restic_pass - \
/etc/tramontana/secrets/restic_pass.cred
$ sudo chmod 600 /etc/tramontana/secrets/restic_pass.cred# /etc/systemd/system/tramontana-copia.service.d/override.conf
[Service]
LoadCredentialEncrypted=restic_pass:/etc/tramontana/secrets/restic_pass.credI a l'script, restic llegeix la contrasenya d'un fitxer, que és just el que la credencial li lliura:
# A copia_tramontana.sh
readonly RESTIC_PASSWORD_FILE="${CREDENTIALS_DIRECTORY:?aquest script s executa via systemd}/restic_pass"
export RESTIC_PASSWORD_FILE
restic -r "$TRAMONTANA_REPO" backup /home/operador/dades /etc/tramontanaTres decisions que convé justificar:
RESTIC_PASSWORD_FILEen lloc deRESTIC_PASSWORD: la contrasenya no passa per l'entorn, només la ruta al fitxer.${CREDENTIALS_DIRECTORY:?...}amb missatge: si l'script s'executa a mà en lloc de per systemd, falla immediatament i amb un missatge clar, en comptes d'intentar copiar sense credencial. És l'expansió de 04-02 aplicada a una cosa real.- La credencial la munta systemd en un
tmpfsprivat del servei: ni elluis, ni elbecari, ni el mateixsvc-tramontanades d'un altre procés no la poden llegir.
El problema de recuperabilitat, que és el fons de l'exercici: el fitxer .cred està xifrat amb una clau derivada d'aquesta màquina (/var/lib/systemd/credential.secret). Si el servidor es perd —l'escenari (c) de restauració de 05-08, o una reinstal·lació després d'un compromís—, aquell fitxer és indesxifrable. I sense la contrasenya de restic no hi ha manera de llegir les còpies: tindries les còpies i no les podries restaurar, que és el pitjor dels fracassos possibles.
Es resol en dos fronts:
passés la font de veritat, i viu fora. El dipòsit depassse sincronitza a un remot (pass git push), i la clau GPG privada té còpia xifrada en un mitjà físic separat. Reconstruir el servidor és: instal·lar, restaurarpass, i tornar a executar la canonada del pas 2.- El manual d'operació ho documenta explícitament, amb aquella canonada escrita literalment i la ubicació de la clau GPG. El manual d'operació ja és fora del servidor per la disciplina de 05-08.
La regla general que se n'extreu: un secret lligat a la màquina no pot ser mai l'única còpia. La credencial de systemd és una memòria cau operativa; la font de veritat és en un altre lloc i és recuperable per una persona autoritzada.
Solució 2
Que certbot renew no donés error és la pista principal: cal distingir «va renovar i alguna cosa posterior va fallar» de «no va renovar i ningú no se'n va assabentar». La primera comprovació separa les dues branques:
$ sudo openssl x509 -in /etc/letsencrypt/live/reserves.tramontana.example/cert.pem \
-noout -enddateBranca A — el certificat al disc és nou (caduca en ~90 dies). La renovació va funcionar; el problema és després.
- El servei no es va recarregar (el més probable). El procés continua a memòria amb el certificat vell:
Si la marca d'arrencada del servei és anterior a la renovació, és això. S'arregla recarregant, i es corregeix d'arrel revisant el ganxo de desplegament.$ ls -l /etc/letsencrypt/renewal-hooks/deploy/ $ sudo journalctl -u certbot --since "40 days ago" | grep -iE 'hook|deploy|reload' $ systemctl show nginx -p ActiveEnterTimestamp - El servidor apunta al fitxer equivocat: a un
cert.pemcopiat a una altra ruta en el seu dia, en lloc de a l'enllaç delive/quecertbotactualitza.$ grep -rE 'ssl_certificate' /etc/nginx/ - Estàs mirant un altre certificat: sense
-servername,openssl s_clientretorna el lloc per defecte. El mateix script el passa, però comprova-ho si ho has provat a mà.
Branca B — el certificat al disc també caduca en 6 dies. No s'ha renovat res. certbot renew no falla sorollosament quan el desafiament no es pot completar en una execució no interactiva, així que cal provocar l'error:
Causes en ordre de probabilitat:
- El port 80 està tancat. És la causa número u, perquè qualsevol revisió del tallafocs s'endú per davant aquella regla «que no semblava necessària»:
$ sudo ufw status verbose | grep -E '^80|http' $ sudo nft list ruleset | grep -E 'dport 80|dport { .*80' - Un altre procés ocupa el 80 i
--standaloneno pot aixecar el seu servidor:$ sudo ss -tulpn | grep ':80 ' - El temporitzador no s'executa de debò, encara que estigui
active:
Un$ systemctl list-timers certbot.timer --no-pager $ sudo journalctl -u certbot.service --since "70 days ago" | tail -20LASTbuit amb el temporitzador actiu significa que mai no s'ha disparat. - DNS: el nom ja no resol a aquesta màquina, així que el desafiament HTTP-01 arriba a un altre lloc:
$ dig +short reserves.tramontana.example $ getent hosts reserves.tramontana.example - Límit de peticions de l'autoritat de certificació, si hi va haver molts intents fallits. La sortida de
--dry-runho diu, i es distingeix perquè fa servir l'entorn de proves i no consumeix quota.
La lliçó de mètode: l'avís va arribar amb 6 dies de marge perquè el llindar era 20 i el control és independent del mecanisme de renovació. Si la vigilància hagués consistit a confiar en certbot, te n'hauries assabentat amb el servei caigut. Per això els controls de verificació no han de compartir mecanisme amb allò que verifiquen.
Solució 3
Informe per a Marta Vidal — Xifratge de les dades d'hostes a
srv-tramontana18 d'agost de 2026S'han implantat tres capes de xifratge. Cadascuna cobreix un risc diferent i cap no substitueix les altres. Detallo què protegeix i què no protegeix cadascuna, i el risc que continua obert.
Capa 1 — Secrets (systemd-creds + pass) La contrasenya de la base de dades i la del dipòsit de còpies ja no estan en clar en cap fitxer de configuració ni a l'entorn de cap procés. Estan xifrades al disc i systemd les lliura al servei en un espai privat a memòria. La font de veritat és en un gestor amb historial, fora del servidor. Protegeix: la fuita de credencials per un error de permisos, per una còpia mal feta, per un registre o per la lectura de l'entorn d'un procés. Tanca l'incident obert des de la còpia amb permisos 644. No protegeix: contra un atacant amb privilegis de root a la màquina en marxa, que pot llegir la credencial de la mateixa manera que el servei.
Capa 2 — Disc de còpies (LUKS) El volum
/srv/tramontana/backupsestà xifrat a nivell de bloc. A més, el dipòsit deresticté el seu propi xifratge, així que les còpies tenen dues capes independents. Protegeix: el robatori o la pèrdua física del disc, l'accés a la imatge de la màquina apagada, i la recuperació de dades d'un disc retirat sense esborrat segur. No protegeix: contra un atacant que compromet el servidor en marxa. Per a ell, el volum està muntat i llegible. És xifratge en repòs, no en ús.Capa 3 — Trànsit (TLS) El material criptogràfic de
reserves.tramontana.exampleestà emès per Let's Encrypt, verificat, amb renovació automàtica provada i vigilància independent de la caducitat amb avís a 20 dies. Protegeix: la lectura i la modificació de les dades de reserva pel seu camí per la xarxa, i la suplantació del servei. No protegeix: les dades un cop arriben al servidor, ni la seguretat de la mateixa aplicació.Risc obert, i és important que hi consti Les dades d'hostes viatgen avui sense xifrar: l'aplicació escolta en HTTP al port 8080. El certificat està a punt i verificat, però el component que el presentarà —el servidor intermediari invers davant de l'aplicació— està previst a la fase següent del projecte. Fins que es desplegui, el xifratge en trànsit no està en vigor, encara que el material estigui preparat. Mitigació provisional: el 8080 no és accessible des d'Internet, així que l'exposició es limita a la xarxa interna.
Risc residual comú a les tres capes Cap capa no protegeix contra el compromís del servidor en marxa amb privilegis de root. Contra aquell escenari actuen els controls de la fase anterior: detecció de canvis amb AIDE, auditoria d'accessos amb
auditd, i el procediment de resposta a incidents amb reconstrucció.Compliment. El xifratge de dades personals en trànsit i en repòs és una obligació del RGPD (art. 32), no una millora opcional, i el risc obert del punt anterior és rellevant a aquests efectes. Recomano que el disseny de la custòdia de claus i la decisió sobre el termini de desplegament del servidor intermediari invers els revisi el responsable de protecció de dades.
Conclusió
Els dos deutes criptogràfics del curs estan saldats, cadascun a la seva manera. La db_password ja no existeix com a text en cap fitxer de configuració: viu xifrada en un .cred que només systemd pot desxifrar i que només el servei pot llegir, amb pass com a font de veritat versionada i sincronitzada fora del servidor. El volum de còpies està xifrat amb LUKS, sabent amb precisió què protegeix això i què no. I el material de reserves.tramontana.example està emès, verificat amb openssl, amb renovació automàtica provada en sec i amb un control de caducitat independent que avisa amb vint dies de marge. El tercer incident obert queda tancat, i saps per què LoadCredentialEncrypted és millor que EnvironmentFile, per què el SAN mana sobre el CN, i per què l'ordre d'una rotació és crear, aplicar, verificar i retirar.
En queda un. El 18 d'agost a les 06:12, unattended-upgrades va aplicar la correcció d'un CVE de TLS sobre openssl i libssl3t64 — la biblioteca que sosté tot el que acabes de muntar a la segona meitat d'aquesta lliçó — i va deixar serveis en execució que continuen fent servir la versió antiga carregada a memòria. Un pedaç instal·lat que ningú no ha aplicat de debò és una vulnerabilitat amb paperassa. A la lliçó 06-06: Assegurant Sistemes Linux es tanca aquell incident amb needrestart i es fa una cosa més ambiciosa: reunir tot el que has après en un model d'amenaces explícit i una postura de seguretat coherent. Reduiràs la superfície d'atac, enfortiràs l'autenticació amb PAM —el deute que vas deixar pendent a 05-01—, escriuràs un perfil d'AppArmor per a l'aplicació, aplicaràs els sysctl d'enfortiment del nucli i els muntatges amb noexec, apujaràs la puntuació de systemd-analyze security amb criteri, i tancaràs amb una llista de comprovació d'enfortiment de srv-tramontana que digui amb honestedat què està fet, què s'ha decidit assumir i què excedeix l'abast d'un administrador.
Curs de Linux: De Principiant a Administrador de Sistemes
Mòdul 1: Introducció a Linux
- Què és Linux?
- Història de Linux
- Distribucions de Linux
- Instal·lant Linux
- Primer Contacte amb el Sistema
- Estructura del Sistema de Fitxers de Linux
Mòdul 2: Comandes Bàsiques de Linux
- Introducció a la Línia de Comandes
- Obtenir Ajuda i Documentació del Sistema
- Navegant pel Sistema de Fitxers
- Operacions amb Fitxers i Directoris
- Visualització i Edició de Fitxers
- Enllaços Durs i Simbòlics
- Permisos i Propietat dels Fitxers
Mòdul 3: Habilitats Avançades en la Línia de Comandes
- L'Entorn del Shell: Variables, Àlies i Historial
- Ús de Comodins i Expressions Regulars
- Cerca de Fitxers i Contingut: find, locate i grep
- Canonades i Redirecció
- Processament de Text: cut, sort, uniq, sed i awk
- Gestió de Processos
- Programació de Tasques amb Cron
- Comandes de Xarxa
Mòdul 4: Scripting en Shell
- Introducció al Scripting en Shell
- Variables i Tipus de Dades
- Entrada, Sortida i Arguments d'un Script
- Estructures de Control
- Funcions i Biblioteques
- Depuració i Gestió d'Errors
- Scripts de Producció: Bones Pràctiques
Mòdul 5: Administració del Sistema
- Gestió d'Usuaris i Grups
- sudo i Permisos Especials
- Gestió de Paquets
- Gestió de Discs
- systemd i la Gestió de Serveis
- Registres del Sistema: journald i syslog
- Monitoratge del Sistema i Optimització del Rendiment
- Còpies de Seguretat i Restauració
Mòdul 6: Xarxes i Seguretat
- Configuració de Xarxes
- SSH i Accés Remot
- Tallafocs i Seguretat Perimetral
- Sistemes de Detecció d'Intrusions
- Gestió de Secrets i Certificats TLS
- Assegurant Sistemes Linux
Mòdul 7: Temes Avançats
- El Procés d'Arrencada i la Recuperació del Sistema
- Diagnòstic Avançat: strace, perf i eBPF
- Optimització del Nucli de Linux
- Virtualització amb Linux
- Contenidors de Linux i Docker
- Automatització amb Ansible
- Alta Disponibilitat i Balanceig de Càrrega
