Introducció
La VPN de Xarxa arriba a la teva màquina, i hi arriba bé.
Té, però, una característica que descarta la meitat del que vols fer amb un servidor: l'altra persona també hi ha de ser.
Vols ensenyar la teva aplicació web a un company? Necessita el túnel. Vols passar una URL a un professor? Necessita el túnel. Vols que un servei extern enviï un webhook a la teva màquina? Ja has perdut abans de començar, perquè un webhook no pot instal·lar WireGuard.
El bastió és l'altra porta.
El servidor web del mateix Isard — aquell on inicies la sessió, a internet, amb un nom real i un certificat real — reenviarà les connexions fins al teu escriptori.
No cal instal·lar res a l'altra banda. Ni túnel, ni configuració, ni client.
architecture-beta
service bastion(internet)[Bastion]
service server(server)[VM]
bastion:R -- L:server
El preu és que no hi arriben tots els ports, com passa amb la VPN.
N'hi ha tres d'exposats, i són els tres que importen:
22/TCP |
SSH |
80/TCP |
HTTP |
443/TCP |
HTTPS |
Com activar-lo
El bastió va per escriptori i està desactivat per defecte.
Obre el formulari d'edició de l'escriptori i busca la secció bastió:

Hi fas dues coses: l'actives i hi registres la clau pública amb què et connectaràs.
Obtén la teva tal com t'ensenyava SSH:
> gc .\.ssh\id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFJgYeQKuRlSp6BOSaVriPqJ5IKakDpHLfP4csIN8Ft/ david@elite
Enganxa-la, desa, i obtindràs un UUID:
e6a0307a-f48f-46e2-9fed-87e34a2d4f61
I aquí ve la pregunta evident: què n'ha de fer ningú, d'això?
L'UUID és l'adreça
L'escriptori no té cap nom públic, així que el bastió n'hi dona un — i és l'UUID.
Prem el botó del bastió a la vista d'escriptoris:

T'hi mostra l'UUID i una URL per a cada protocol activat:

La forma és sempre la mateixa:
e6a0307a-f48f-46e2-9fed-87e34a2d4f61.bastion.elmeuescriptori.cat
Aquest nom es resol a internet, des de qualsevol lloc, sense VPN.
http:// i https:// arriben als ports 80 i 443 de l'escriptori.
L'SSH és l'excepció, i val la pena llegir-ho dues vegades: va al servidor d'Isard, port 443, i l'UUID fa de nom d'usuari SSH.
No és cap error de la interfície. Hi ha un sol port obert per als escriptoris de tota una plataforma, de manera que allò que identifica la teva màquina ha de viatjar dins de la connexió i no pas a l'adreça — i el camp del nom d'usuari és on hi cap.

isard ssh
Tot l'anterior és una sola ordre:
$ isard ssh box-1
Matched: 'box-1'
✓ Key registered with the bastion
✓ Desktop is running
isard@box-1:~$
No has escrit cap UUID, no has obert el formulari d'edició, no has enganxat cap clau.
Això és el que ha fet, per ordre:
- Ha resolt el nom —
box-1, o una grafia prou semblant. - Ha trobat la teva clau privada —
--identitysi n'has passat una, després~/.ssh/id_ed25519i després~/.ssh/id_rsa. Si no en tens cap, en genera una d'ed25519 en lloc de fallar. - Ha registrat la clau pública corresponent al bastió de l'escriptori, cosa que també l'activa. Fer-ho dues vegades no fa mal — ho comprova abans d'escriure.
- Ha arrencat l'escriptori si estava aturat, i ha esperat.
- S'ha connectat al servidor d'Isard pel port 443, amb l'UUID del bastió com a nom d'usuari.
El pas 2 és el que convé saber: no et cal cap clau per començar.
$ isard ssh box-1
No SSH key found. Generating ~/.ssh/id_ed25519...
✓ Key generated
✓ Key registered with the bastion
isard@box-1:~$
La màquina ha d'estar escoltant
El bastió reenvia una connexió al port 22 de la teva màquina.
Si no hi escolta res, això és el que obtens:
$ isard ssh box-1
✓ Key registered with the bastion
✗ connect: connection refused
Llegeix-ho amb atenció, perquè és el que falla més sovint i sembla un problema de permisos.
connection refused vol dir que el bastió hi ha arribat. Ha arribat a la teva màquina i no hi ha trobat ningú al port 22.
Una plantilla Server porta un servidor SSH. Una plantilla Desktop normalment no, i una màquina que has instal·lat tu només en porta si vas marcar la casella durant la instal·lació.
En un escriptori Linux, des del visor:
$ sudo apt install -y openssh-server
$ sudo systemctl enable ssh --now
Això és la lliçó de SSH, i aquesta pàgina no la repeteix.
Una màquina nua, en una línia
A un escriptori que has instal·lat tu li falta més que sshd.
No hi ha servidor SSH, potser no hi ha cap compte que coincideixi amb el que fa servir el bastió per entrar, i no hi ha agent SPICE — així que el porta-retalls tampoc no funciona, i això és el que fa mal, perquè no pots enganxar l'ordre que ho arreglaria.
Per això hi ha una ordre prou curta per escriure-la a mà. Al visor del mateix escriptori:
$ curl -fsSL https://isard.xtec.dev/guest.sh | sudo sh -s isard mypassword
==> installing openssh-server
==> creating user 'isard'
==> installing spice-vdagent
==> done
Instal·la i activa el servidor SSH, crea el compte amb sudo sense contrasenya, i instal·la spice-vdagent i qemu-guest-agent.
Funciona tant amb apt com amb dnf, i executar-lo dues vegades és segur — se salta el que ja hi és.
En un escriptori Windows la mateixa feina és una línia de PowerShell, en una finestra d'administrador:
> iex (irm https://isard.xtec.dev/guest.ps1)
Això instal·la el servidor OpenSSH, obre el port 22 al tallafoc, posa PowerShell com a shell de l'SSH i instal·la les spice-guest-tools.
Reinicia després, perquè el porta-retalls no funciona fins que ho fas:
> Restart-Computer
Les credencials que et mostra una sola vegada
La primera vegada que fas isard ssh a un escriptori concret, s'atura i et mostra una cosa:
$ isard ssh box-1
Guest credentials for 'box-1':
user : isard
password : pi****us
Are these correct? [Y/n]:
La meitat de la contrasenya, i una pregunta.
No és la clau amb què et connectes — és el compte amb què el bastió entra a la màquina, i es guarda a la fitxa del mateix escriptori a la plataforma.
Si no coincideix amb cap compte real de dins de la màquina, el bastió no s'autentica enlloc i obtens un error sobre els mètodes provats en lloc d'una shell.
Respon Y i ja no t'ho torna a preguntar. L'identificador de l'escriptori va a ~/.config/isard/desktop-creds.json, que només guarda identificadors i res més — cap contrasenya, només el conjunt de màquines que ja has confirmat.
Respon n i te'n demana de noves, i les envia a l'escriptori:
$ isard ssh box-1 --password 'nova-contrasenya'
⠹ Stopping 'box-1' to update credentials...
✓ Credentials updated
⠹ Waiting for 'box-1' to start...
isard@box-1:~$
Fixa't en el reinici que hi ha al mig. Les credencials de la màquina, igual que authorized_keys, s'apliquen en arrencar — així que canviar-les costa una aturada i una arrencada, i isard ssh --password fa totes dues coses per tu en lloc de deixar-te esbrinar per què no ha canviat res.
Publicar alguna cosa
Els ports 80 i 443 són el motiu pel qual el bastió és més que un SSH còmode.
Instal·la un servidor web:
$ isard ssh box-1 -- 'sudo apt update && sudo apt install -y nginx'
Escriu-hi alguna cosa reconeixible:
$ isard ssh box-1 -- 'echo "<h1>Hola des de box-1</h1>" | sudo tee /var/www/html/index.html'
<h1>Hola des de box-1</h1>
I obre la URL HTTP del bastió en qualsevol navegador, des de qualsevol màquina, sense VPN:
http://e6a0307a-f48f-46e2-9fed-87e34a2d4f61.bastion.elmeuescriptori.cat/
És una URL que pots enviar a algú.
ExerciciPublica una pàgina
Serveix una pàgina des de box-1 i obre-la des d'un navegador que no sigui a la VPN.
Mostra la solució
$ isard ssh box-1 -- 'sudo apt update && sudo apt install -y nginx'
$ isard ssh box-1 -- 'echo "<h1>box-1</h1>" | sudo tee /var/www/html/index.html'
<h1>box-1</h1>
$ isard vpn down
✓ VPN is down
Després, la URL HTTP del bastió, des del botó del bastió de la plataforma.
Desactivar primer la VPN és la gràcia de l'exercici. Amb el túnel actiu no pots saber quina de les dues rutes t'ha respost.
Executar coses sense una shell
Tots els exemples d'abans fan servir la forma de CLI:
$ isard ssh box-1 -- 'sudo apt install -y nginx'
L'ordre que hi ha després de -- s'executa a la màquina i la sessió no és interactiva.
Això és el que converteix el bastió en un destí de compilació i no en un lloc que visites.
Copia-hi un projecte i executa'n les proves:
$ tar czf - src tests | isard ssh box-1 -- 'tar xzf - -C /home/isard/work'
$ isard ssh box-1 -- 'cd work && uv run pytest -q'
........................ [100%]
24 passed in 1.83s
El codi de sortida és el de les proves, així que funciona com a pas d'un script:
$ isard ssh box-1 -- 'cd work && uv run pytest -q' && echo "green"
VPN o bastió
Tots dos arriben a la màquina. No són intercanviables.
| VPN | bastió | |
|---|---|---|
| ports | tots | 22, 80, 443 |
| l'altra persona necessita | el túnel i la teva configuració | un enllaç |
| configuració per escriptori | marcar una casella en crear-lo | activar-lo, registrar una clau |
| configuració a la teva màquina | isard vpn up, necessita sudo |
res |
| serveix per | treballar a la màquina | ensenyar el que hi funciona |
A la pràctica fas servir tots dos, i en tots dos casos el que escrius és isard ssh.
Exercicis
ExerciciDes de zero
Crea una màquina Ubuntu Desktop nova anomenada bare i obtén-hi una shell SSH a través del bastió.
Mostra la solució
$ isard create bare --template ubuntu-24-04-desktop
✓ Desktop 'bare' created successfully!
$ isard start bare --wait
✓ Desktop 'bare' is running
$ isard ssh bare
✓ Key registered with the bastion
✗ connect: connection refused
Una plantilla Desktop no porta servidor SSH, així que aquesta és la primera resposta esperada.
Obre el visor i instal·la'n un:
$ isard view bare
A la màquina:
$ sudo apt install -y openssh-server
$ sudo systemctl enable ssh --now
Després, des del teu terminal:
$ isard ssh bare
isard@bare:~$
Si en canvi obtens Permission denied (publickey), la clau es va registrar quan la màquina ja estava en marxa. isard stop bare && isard start bare i torna-ho a provar.
ExerciciLlegeix els dos errors
Digues què vol dir cadascun d'aquests errors i què el soluciona:
connect: connection refusedPermission denied (publickey)
Mostra la solució
-
El bastió ha arribat a la màquina i no hi havia res escoltant al port 22. Instal·la i activa un servidor SSH dins de la màquina.
-
El bastió ha arribat a sshd i la teva clau encara no era a
authorized_keys. Gairebé sempre és perquè la clau es va registrar després que la màquina arrenqués — atura-la i torna-la a arrencar.
Val la pena distingir-los perquè tots dos semblen l'SSH no funciona i cap dels dos se soluciona generant una clau nova, que és el que tothom prova primer.
ExerciciUna ordre, tres màquines
Amb box-1, box-2 i box-3 en marxa, esbrina la versió del nucli de cadascuna sense obrir cap shell.
Mostra la solució
$ for n in 1 2 3; do
> printf '%s: ' "box-$n"
> isard ssh box-$n -- 'uname -r'
> done
box-1: 6.8.0-51-generic
box-2: 6.8.0-51-generic
box-3: 6.8.0-51-generic
El printf i la sortida de l'ordre queden ben intercalats perquè tot el que isard diu sobre la cerca i l'arrencada va a stderr, no a stdout.
ExerciciQuina ruta ha respost
box-1 té una interfície WireGuard i el bastió activat, i el seu servidor web respon per totes dues bandes.
Com demostraries quina ha fet servir una petició concreta?
Mostra la solució
Treu-ne una.
$ isard vpn down
✓ VPN is down
$ curl -s -o /dev/null -w '%{http_code}\n' http://10.2.76.37
000
$ curl -s -o /dev/null -w '%{http_code}\n' \
http://e6a0307a-f48f-46e2-9fed-87e34a2d4f61.bastion.elmeuescriptori.cat/
200
000 vol dir que curl no ha pogut ni connectar-se, que és la resposta correcta per a una adreça privada d'una xarxa on ja no ets.
L'hàbit general val més que l'exercici: quan hi ha dues coses que podrien estar responent, apaga'n una.