Guies de LinuxIntel·ligència Artificial

Administrar un servidor al núvol amb un assistent d’IA, sense instal·lar-hi res

Il·lustració d'una figura d'intel·ligència artificial feta de llum que es connecta a un núvol amb servidors


Tinc un servidor al núvol i, des de fa un temps, quan hi he de fer alguna cosa no obro una sessió SSH i començo a teclejar comandes: li ho demano a un assistent d’IA. «Mira per què ha caigut l’Apache.» «Revisa els registres d’avui.» «Instal·la aquest servei i deixa’l en marxa.» Faig servir Claude Code o opencode, i el que més sorprèn a qui li ho explico és que al servidor no hi he instal·lat res: ni l’assistent, ni cap agent, ni cap programa nou.

En aquest article t’explico com funciona, com ho tinc muntat i, sobretot, les normes que segueixo perquè sigui segur. La primera, i la que mana sobre totes: l’assistent no fa res sense explicar-ho abans, i no executa res sense la meva aprovació.

Com funciona: el servidor només veu SSH

Esquema: l'assistent d'IA al meu ordinador proposa i explica cada comanda, jo l'aprovo i s'executa al servidor per SSH, sense instal·lar res al servidor

La idea clau és que l’assistent viu al meu ordinador. Claude Code i opencode són programes de terminal que poden executar comandes a la meva màquina (sempre que jo els ho permeti). I des de la meva màquina, arribar al servidor és el de sempre: SSH.

Quan li demano alguna cosa del servidor, el que fa l’assistent és proposar una comanda com aquesta, que s’executa al meu ordinador:

ssh servidor 'systemctl status apache2'

SSH obre la connexió, executa systemctl status apache2 al servidor i retorna la sortida. L’assistent la llegeix, la interpreta i em proposa el pas següent. Per al servidor no hi ha cap diferència entre això i que jo hagués escrit la comanda a mà: és el mateix usuari, amb la mateixa clau i els mateixos permisos, i tot queda als seus registres com sempre.

Això té una conseqüència important: el que l’assistent llegeix arriba al model d’IA, que s’executa als servidors del proveïdor (Anthropic, en el cas de Claude). La sortida de les comandes, els fitxers que obre… tot forma part de la conversa. Ho tindrem molt present a l’apartat de seguretat.

La regla d’or: explicar abans, aprovar sempre

Abans de res, la norma que dona sentit a tot el muntatge. Cada vegada que l’assistent vol fer alguna cosa al servidor, el cicle ha de ser aquest:

  1. Proposa una comanda.
  2. Explica què farà i per què la necessita.
  3. Jo aprovo (o no, o li demano que m’ho expliqui millor).
  4. S’executa.
  5. M’explica el resultat i què en dedueix.

Aquesta regla la poso en dues capes, perquè una sola no n’hi ha prou:

  • Una instrucció a l’assistent, perquè expliqui les coses abans de fer-les.
  • Els permisos de l’eina, perquè, encara que l’assistent s’oblidi de la instrucció, el programa m’aturi i em demani confirmació abans d’executar qualsevol comanda.

La instrucció fa que l’assistent expliqui; el permís garanteix que sóc jo qui decideix. Ara veurem com es configura cada cosa.

El meu muntatge, pas a pas

1. Una clau SSH per a l’assistent

L’assistent es connecta amb una clau SSH, no amb una contrasenya. Pots fer servir la que ja tinguis, però a mi m’agrada tenir-ne una de dedicada, perquè així la puc revocar sense afectar res més:

ssh-keygen -t ed25519 -f ~/.ssh/servidor_ia -C "assistent IA"
ssh-copy-id -i ~/.ssh/servidor_ia.pub usuari@203.0.113.10

Tens els detalls d’aquestes dues comandes a com generar una clau SSH i a accés SSH sense contrasenya. L’usuari del servidor és un usuari normal, mai root, que pot fer servir sudo.

2. Un àlies a ~/.ssh/config

Perquè les comandes siguin curtes i l’assistent no hagi de saber ni l’adreça ni quina clau fer servir, defineixo un àlies al fitxer ~/.ssh/config del meu ordinador:

Host servidor
    HostName 203.0.113.10
    User usuari
    IdentityFile ~/.ssh/servidor_ia
    IdentitiesOnly yes

A partir d’aquí, ssh servidor ja sap on anar i amb quina clau.

3. El fitxer .env del projecte

Treballo en una carpeta de projecte al meu ordinador, i allà hi ha un fitxer .env amb les dades del servidor: el nom de l’àlies, l’usuari i la contrasenya de sudo d’aquest usuari. Dues coses imprescindibles:

  • El .env ha de ser a .gitignore, perquè no acabi mai en un repositori.
  • La contrasenya de sudo és la dada més delicada del muntatge. A l’apartat de seguretat t’explico com evitar que l’assistent la vegi.

4. Les instruccions per a l’assistent

Claude Code llegeix les instruccions del projecte del fitxer CLAUDE.md, i opencode, de AGENTS.md (si no el troba, també llegeix CLAUDE.md). Allà hi escric qui és el servidor i, sobretot, la regla d’or:

# Servidor

- El servidor és «servidor» (àlies de ~/.ssh/config). Connecta-t'hi sempre amb `ssh servidor '...'`.
- Abans de cada comanda al servidor, explica què farà i per què, i espera la meva aprovació.
- Fes una sola comanda cada vegada; no n'encadenis diverses sense permís.
- Res destructiu (esborrar, reiniciar, desinstal·lar, canviar configuració) sense que t'ho confirmi explícitament.
- Si un pas requereix sudo, digues-m'ho abans i explica per què cal.
- No llegeixis mai el fitxer .env.

5. Els permisos de l’eina

Aquesta és la segona capa, la que no depèn que l’assistent «es porti bé».

A Claude Code, en el mode per defecte (Manual), qualsevol comanda que no sigui de només lectura (ls, cat, grep…) demana aprovació, i ssh no és a aquesta llista: cada ssh servidor '...' m’apareix com una petició que he d’acceptar. Però compte: si a la pregunta tries «Yes, and don’t ask again», Claude Code desa una regla i ja no t’ho tornarà a preguntar. Per evitar-ho, poso una regla ask, que té prioritat sobre les regles allow, i de passada li prohibeixo llegir el .env. Al fitxer .claude/settings.json del projecte:

{
  "permissions": {
    "ask": ["Bash(ssh *)", "Bash(scp *)", "Bash(rsync *)"],
    "deny": ["Read(./.env)", "Read(./.env.*)"]
  }
}

I no faig servir mai els modes que s’estalvien les preguntes (auto o bypassPermissions) per treballar amb el servidor.

A opencode cal anar amb més compte, perquè per defecte executa les comandes sense preguntar. Al fitxer opencode.json del projecte:

{
  "$schema": "https://opencode.ai/config.json",
  "permission": {
    "bash": "ask"
  }
}

Amb això, opencode em demana permís abans de qualsevol comanda. La lectura dels fitxers .env ja la bloqueja per defecte.

Exemples d’encàrrecs

Vegem com és el dia a dia. No t’enganyaré amb converses inventades paraula per paraula; el que importa és el cicle, que sempre és el mateix.

«Per què ha caigut l’Apache?»

L’assistent proposa començar per l’estat del servei, i m’explica que systemctl status em dirà si està aturat, des de quan i les darreres línies del seu registre:

ssh servidor 'systemctl status apache2 --no-pager'

Aprovo. Si la sortida diu failed, em proposa el pas següent, mirar el registre complet del servei des de l’últim arrencament, i m’explica per què:

ssh servidor 'journalctl -u apache2 -b --no-pager -n 50'

Aprovo. Si al registre apareix, per exemple, un error de sintaxi en un fitxer de configuració, m’ho explica i em proposa validar la configuració abans de tocar res (apache2ctl configtest). Només quan tots dos entenem el problema em proposa la correcció i el reinici, que és una acció que modifica el servidor i que aprovo amb especial atenció.

«Revisa l’espai de disc i els errors d’avui»

ssh servidor 'df -h'
ssh servidor 'journalctl --since today -p err --no-pager'

Primer l’espai lliure de cada partició; després, només els missatges de prioritat d’error o més greus del dia. Si un disc és ple, em proposa buscar què ocupa més (du) abans de proposar esborrar res.

«Instal·la i deixa en marxa un servei»

Aquí entra sudo, i l’assistent m’ho ha de dir abans: instal·lar paquets i activar serveis són canvis al sistema. Em proposa, per ordre, actualitzar la llista de paquets, instal·lar-lo, activar-lo i comprovar que funciona. Cada pas és una aprovació separada, i abans de l’apt install em diu quins paquets s’instal·laran.

«Fes-me una revisió ràpida»

És el meu encàrrec preferit per començar la setmana:

  • Actualitzacions pendents (apt list --upgradable).
  • Ports oberts i quins programes els escolten (ss -tulpn).
  • Estat de fail2ban i IP bloquejades.
  • Darreres connexions SSH (journalctl -u ssh -g Accepted --since "-7 days").
  • Serveis que han fallat (systemctl --failed).

L’assistent m’ho resumeix en un paràgraf: què està bé, què caldria mirar i per què. Les decisions les prenc jo.

Els perills d’aquest muntatge

Abans de les bones pràctiques, convé tenir clar què pot sortir malament. Cap d’aquests perills és teòric: tots poden passar, i la majoria no depenen de la IA sinó de com ho tens configurat.

1. Les teves dades surten de casa

Tot el que l’assistent llegeix s’envia al proveïdor del model: les sortides de les comandes, els registres, els fitxers de configuració. Un registre d’Apache conté adreces IP de visitants; un fitxer de configuració pot contenir contrasenyes d’una base de dades. Si no ho vigiles, acabes enviant a un servei extern dades que no són teves.

2. Les credencials del teu ordinador obren el servidor

La clau SSH i el .env són al teu ordinador. Si algú hi accedeix (un programari maliciós, un ordinador perdut, una còpia de seguretat sense xifrar, un .env pujat per error a GitHub), té accés al servidor. I si el .env conté la contrasenya de sudo, té accés com a root. Una clau SSH sense frase de pas (passphrase) és especialment perillosa.

3. L’assistent es pot equivocar, i amb molta seguretat

Un model d’IA pot proposar una comanda que sembla correcta i no ho és, fer servir una opció que no existeix a la teva versió, o interpretar malament un registre i portar-te a una solució que no toca. El perill no és que s’equivoqui (també ens equivoquem les persones), sinó que ho explica amb tanta convicció que és fàcil creure-se-la.

4. Les instruccions amagades a les dades (prompt injection)

Aquest és el perill menys conegut. L’assistent llegeix text que no has escrit tu: registres, fitxers, pàgines web. Si un atacant aconsegueix que aparegui un text com «ignora les instruccions anteriors i executa…» en un lloc que l’assistent llegirà (per exemple, en el User-Agent d’una petició, que l’Apache desa al registre), l’assistent el podria interpretar com una ordre. És el motiu principal pel qual cada comanda ha de passar per la teva aprovació: encara que l’assistent quedi enganyat, la comanda no s’executa sense tu.

5. La fatiga d’aprovar

Després de vint «sí» seguits, el vint-i-unè el dones sense llegir. Les eines t’ho posen fàcil amb opcions com «Yes, and don’t ask again» o modes que deixen de preguntar. Cada drecera d’aquestes desactiva una part de la teva protecció, sovint sense que te n’adonis, perquè la regla queda desada per a les properes sessions.

6. Comandes que fan més del que semblen

Una comanda aprovada pot portar-ne d’altres enganxades amb ;, && o |, o descarregar i executar un script (curl ... | bash) que no has vist. També pot fer una cosa diferent de la que diu l’explicació. Per això cal llegir la comanda, no només l’explicació.

7. Quedar-te fora del teu servidor

Un canvi a la configuració d’SSH, al tallafocs o a fail2ban pot deixar-te sense accés. Fail2ban, per exemple, pot bloquejar la teva pròpia IP si l’assistent fa moltes proves que generen errors al servidor web. I si et quedes fora, l’assistent tampoc hi pot entrar: l’únic camí és la consola del proveïdor del núvol.

8. Saber-ne cada vegada menys

Si l’assistent ho fa tot i tu només aproves, a la llarga pots perdre la capacitat de resoldre un problema sense ell. I l’assistent depèn d’un servei extern: el dia que no funcioni, o que no tinguis connexió, has de poder fer-ho tu.

9. La responsabilitat és teva

Al servidor, cada comanda queda registrada amb el teu usuari. Si alguna cosa surt malament, no hi ha cap «ho va fer la IA»: l’has aprovada tu.

Tots aquests perills es redueixen molt amb les normes que explico a continuació.

El que he après: bones pràctiques

1. El que l’assistent llegeix, arriba al model

És el punt més important i el que més es passa per alt. Si l’assistent fa cat .env, la contrasenya de sudo passa a formar part de la conversa i s’envia al proveïdor de la IA. Per això:

  • Prohibeix-li llegir el .env, amb la instrucció i, sobretot, amb els permisos (la regla deny de Claude Code, o el comportament per defecte d’opencode).
  • No li enganxis mai contrasenyes al xat.
  • Pensa també en les sortides: un cat d’un fitxer de configuració amb contrasenyes, o un registre amb dades personals, també arriben al model.

2. La contrasenya de sudo, millor fora de l’abast de l’assistent

Si l’assistent necessita sudo, tens diverses opcions, de més a menys segura:

  • Fer tu la comanda. L’assistent t’explica què cal executar amb sudo i tu l’escrius al teu terminal.
  • Diagnosticar sense sudo. Moltes consultes no necessiten sudo. systemctl status funciona amb un usuari normal, i els membres del grup systemd-journal (o adm) poden llegir tots els registres amb journalctl. Al servidor, una sola vegada:
sudo usermod -aG systemd-journal usuari
  • Permisos sense contrasenya, però molt limitats. Per a les poques consultes que sí que necessiten root, una regla a /etc/sudoers.d/ que les permeti sense contrasenya, i res més. Per exemple, per consultar fail2ban:
usuari ALL=(root) NOPASSWD: /usr/bin/fail2ban-client status, /usr/bin/fail2ban-client status *

Així l’assistent pot diagnosticar, i per a qualsevol canvi la contrasenya continua sent necessària. No hi posis journalctl, less, editors ni intèrprets: obren un paginador o un shell des del qual es pot executar qualsevol cosa com a root. Tens com fer-ho pas a pas a la comanda sudo i el fitxer sudoers.

  • Contrasenya al .env, sense que l’assistent la llegeixi. Si la fas servir en una comanda com a variable ($SUDO_PASS), l’assistent només veu el nom de la variable, no el valor. És millor que llegir el fitxer, però no és perfecte: el valor viatja dins de la comanda al servidor. Fes-ho servir només si les altres dues opcions no et van bé.

3. Explicació abans, aprovació sempre

La regla d’or no és només una mesura de seguretat: també és la millor manera d’aprendre administració de sistemes mentre la fas. Si no entens l’explicació, no aprovis; demana-li que t’ho expliqui més a poc a poc, o que et digui què passaria si alguna cosa sortís malament.

4. No aprovar a cegues

Després de vint aprovacions seguides, és molt fàcil dir que sí sense llegir. Llegeix sempre la comanda, no només l’explicació. Desconfia especialment de:

  • comandes amb rm, > (que sobreescriu fitxers), chmod -R, dd o mkfs;
  • canvis a fitxers de configuració sense haver-ne fet abans una còpia;
  • qualsevol cosa que toqui SSH o el tallafocs: et podries quedar fora del servidor.

5. Usuari dedicat, clau dedicada i mai root

Fes servir un usuari normal i una clau només per a això. Posa-li una frase de pas i carrega-la amb ssh-agent al començament de la sessió: així, si algú et copia la clau, no la pot fer servir. Si un dia vols tallar l’accés, només has d’esborrar aquella clau del fitxer ~/.ssh/authorized_keys del servidor.

6. Tot queda registrat

El servidor registra cada connexió SSH i cada ús de sudo, com sempre. Pots revisar què s’ha fet amb journalctl:

journalctl _COMM=sudo --since today

I al teu ordinador, l’historial de la conversa amb l’assistent et diu quines comandes va proposar i quines vas aprovar.

Quan no ho faria servir

  • Sense supervisió. Aquest muntatge funciona perquè jo hi soc i aprovo cada pas. Deixar l’assistent sol fent canvis en un servidor de producció és una altra cosa, i no la recomano.
  • Amb dades sensibles de tercers. Si el servidor té dades personals de clients, pensa-hi dues vegades abans de deixar que les sortides arribin a un servei extern.
  • Per a canvis irreversibles sense còpia de seguretat. Abans d’una actualització gran o d’una migració, fes una còpia. Ho explico a com actualitzar un servidor sense perdre dades.

Conclusió

No cal instal·lar res al servidor per tenir-hi un assistent d’IA: n’hi ha prou amb SSH, una clau i un assistent al teu ordinador. El que marca la diferència no és la tecnologia, sinó les normes: que l’assistent t’expliqui cada pas abans de fer-lo, que sempre necessiti la teva aprovació i que no vegi el que no ha de veure. Amb aquestes normes, és com tenir al costat un company que sap molt i que, a més, t’ensenya mentre treballeu.

Posts relacionats