SSH
Introducció
Section titled “Introducció”SSH vol dir Secure Shell, i et permet connectar-te a una altra màquina mitjançant un shell remot.
Un cop t’has connectat, totes les ordres que escrius en el terminal s’envien al servidor remot i s’executen en aquella màquina (no en la teva).
Aquesta activitat presuposa que ja coneixes el que són les claus públiques assimètriques que s’explica a {% link “/security/cryptography” %}.
Entorn de treball
Section titled “Entorn de treball”A continuació has de crear un client i un servidor.
Servidor
Section titled “Servidor”Ves a https://elmeuescriptori.gestioeducativa.gencat.cat.
Crea una màquina “Ubuntu 24.04 Server v1.0 amb el nom server
.
Arrenca la màquina.
Client
Section titled “Client”Arrenca una màquina virtual Linux amb {% link “/windows/wsl/” %}.
> connect-wsl client -new
Perquè el client pugui accedir al servidor necessita poder connectar-se a la xarxa del servidor:
La màquina virtual en aquest cas “server” té una interície {% link “/network/wireguard/” %}.
Aquesta interfície està vinculada a una xarxa del sistema que assigna una adreça IP fixa a la màquina virtual “server” i permet connectarse desde una màquina que està fora d’Isard mitjançat una xarxa privada virtual (VPN).
Ves a https://elmeuescriptori.gestioeducativa.gencat.cat.
Accedeix al menú desplegable de l’usuari i selecciona l’opció VPN, que descarregarà el fitxer isard-vpn.conf
a l’equip amfitrió.
{% image “vpn.png” %}
Instal.la i configura wireguard a la màquina client:
$ sudo apt update && sudo apt install -y wireguard$ sudo cp /mnt/c/Users/david/Downloads/isard-vpn.conf /etc/wireguard/wg0.conf$ sudo wg-quick up wg0
Verifica que s’ha creat la interfície wg0
:
$ ip addr | grep wg03: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000 inet 10.0.29.109/32 scope global wg0...
Verifica que la mtu
la interfície eth0
és igual al de la interfície enp1s0
(1500) de la màquina servidor.
$ ip addr | grep eth02: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 inet 172.22.152.27/20 brd 172.22.159.255 scope global eth0
Observació. wg0
és una interfície virtual que crea un tunel a través de la interfície eth0
.
Si no és el cas, modifica la mtu de la interficie eth0
:
$ sudo ip li set mtu 1500 dev eth0
Mira quina és la IP de la màquina remota:
> get-isardNom Estat IP--- ----- --server Started 10.2.53.164
Prova que el tunel funciona fent un ping a la màquina virtual.
Important! Fes servir la IP de la teva màquina.
client$ ping -c 1 10.2.53.164PING 10.2.53.164 (10.2.53.164) 56(84) bytes of data.64 bytes from 10.2.53.164: icmp_seq=1 ttl=63 time=45.0 ms
--- 10.2.53.164 ping statistics ---1 packets transmitted, 1 received, 0% packet loss, time 0msrtt min/avg/max/mdev = 45.002/45.002/45.002/0.000 ms
Conecta’t amb ssh
a la màquina virtual amb l’usuari de la màquina d’Isard:
ssh usuari_remot@ip_remota
client$ ssh isard@10.2.53.164The authenticity of host '10.2.53.164 (10.2.53.164)' can't be established.ED25519 key fingerprint is SHA256:d2ftziPI68LJO/16FBh7W6LFvak2XUoVaZkXY7VA6d0.This key is not known by any other names.Are you sure you want to continue connecting (yes/no/[fingerprint])?
El primer cop que et conectes a la màquina servidor, et pregunten si confies que aquesta és la màquina a la que et vols connectar.
El servidor proporciona una clau publica assimètrica de tipus ED255519 que identifica al servidor.
I se suposa que tu … 😒
Fes com fa tothom, digues que si, i endavant ..
Are you sure you want to continue connecting (yes/no/[fingerprint])? yesWarning: Permanently added '10.2.53.164' (ED25519) to the list of known hosts.isard@10.2.53.164's password:
Et demanen la contrasenya de l’usuari_remot isard
:
Welcome to Ubuntu 24.04 LTS (GNU/Linux 6.8.0-36-generic x86_64)
* Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/pro
System information as of dom 13 oct 2024 09:13:50 UTC
System load: 0.02 Processes: 166 Usage of /: 7.3% of 87.04GB Users logged in: 0 Memory usage: 3% IPv4 address for enp1s0: 192.168.120.182 Swap usage: 0%server$
I ja estas dins de la màquina servidor!
Activitat: server-desktop
Section titled “Activitat: server-desktop”Ves a https://elmeuescriptori.gestioeducativa.gencat.cat.
Crea una màquina “Ubuntu Mate Desktop 24.04 LTS v1.1” amb el nom server-desktop
.
Arrenca la màquina.
La connexió SSH s’implementa mitjançant un model client-servidor.
Per tant, la màquina remota ha d’executar un servidor SSH.
Obre un visor a la màquina server-desktop
.
> connect-isard server-desktop
Instal.la un servidor SSH:
server-desktop$ sudo apt install -y openssh-serverserver-desktop$ sudo systemctl enable ssh --now
{% image “ssh-server.png” %}
Connecta’t per ssh a la màquina server-desktop
.
{% sol %} Miro quina és la IP de la màquina des d’un terminal de powershell
> get-isardNom Estat IP--- ----- --server Started 10.2.53.164server-desktop Started 10.2.21.48
Ara em connecto per SSH des de la màquina client
:
client$ ssh isard@10.2.21.48...Ara ja puc connectar-me a qualsevol de les dues màquines remotes (server i server-desktop)
{% endsol %}
Activitat: hosts
Section titled “Activitat: hosts”Modifica el fitxer /etc/hosts
de la màquina client
per tal que resolgui les IPs de server
i server-desktop
:
{% sol %}
client$ printf "10.2.53.164\tserver\n10.2.21.48\tdesktop\n" | sudo tee -a /etc/hosts > /dev/nullclient$ more /etc/hosts127.0.0.1 localhost127.0.1.1 client. client10.2.53.164 server10.2.21.48 server-desktop
{% endsol %}
Verifica que et pots connectar a la màquina server
amb el seu nom:
{% sol %}
client$ ssh -v isard@server
{% endsol %}
Si mires el fitxer
Claus assimètriques
Section titled “Claus assimètriques”Enlloc de contrasenya, el més habitual és utilitzar claus assimètriques per autenticar usuaris als servidors.
Clau ed25519
Section titled “Clau ed25519”Les claus ed25519
són claus assimètriques de curva elíptica.
Genera una parell de claus de tipus ed25519
SSH (privada i pública) en la màquina client.
La ID de la clau (-C "box@client"
) pot ser la que vulguis: és perquè et sigui més fàcil identificar la clau en el fitxer authorized_keys
!
Quan et preguntin la contrasenya, apreta “enter” directament:
client$ ssh-keygen -t ed25519 -C "box@client"Generating public/private ed25519 key pair.Enter file in which to save the key (/home/box/.ssh/id_ed25519):Enter passphrase (empty for no passphrase):Enter same passphrase again:Your identification has been saved in /home/box/.ssh/id_ed25519Your public key has been saved in /home/box/.ssh/id_ed25519.pubThe key fingerprint is:SHA256:BYNx9n5iURFUDsB9h8tDLIO3tfMOZ8U07zX1Z/gCw+A box@clientThe key's randomart image is:+--[ED25519 256]--+| .o=..=*=.. || .o ++.=o*.+|| .++ O.B=|| oE.= B.O|| S + .o B=|| . o o *|| * || .|| |+----[SHA256]-----+
Pots veure el contingut de la teva clau pública:
client$ cat ~/.ssh/id_ed25519.pubssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPfc8GctAnRJpVUhKmewqabRNuJNBQQrGl94froIGclk box@client
Clau RSA
Section titled “Clau RSA”Alguns cops et pots trobar que el servidor no admet claus assimètriques ed25519
i has d’utlitzar les antigues RSA
.
Les claus RSA
són claus assimètriques que utilitzen factorització d’enters:
client$ ssh-keygen -t rsa -C "box@client"Generating public/private rsa key pair.Enter file in which to save the key (/home/box/.ssh/id_rsa):Enter passphrase (empty for no passphrase):Enter same passphrase again:Your identification has been saved in /home/box/.ssh/id_rsaYour public key has been saved in /home/box/.ssh/id_rsa.pubThe key fingerprint is:SHA256:sJiAYYhGA+ffguKfVSu5z4si8DSTXN1c3gtcUaBKd9A box@clientThe key's randomart image is:+---[RSA 3072]----+|B+. ..o+. ||+*. .oE ||o o ..o.+oo. || +.+.+oo+.. ||...o= o.S . . ||o.* .o . . ||.+ o + . || .o.o = || .o.o.+. |+----[SHA256]-----+
Si mires el contingut de la clau rsa
pots veure que la clau és molt més gran:
client$ cat ~/.ssh/id_rsa.pubssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC/4kPhxXrwzbBATmhZ5ZKhYeck94z3xYK5/Nv/VRfZfgP43/HSi75hl7bjNjw+qYD4EsKpA8820WdNgFjRgz29vSunqfNjZXhI+pQzGQ7HhcqiKAmAhRp9RxA9IauaBKlAuYm7yJn2W3bQsfFaBpvlP0jm+IWqBn6xE8HE/uEp/843tSCDaARPOxc/6iEefgsD61I+C5bvDlcxLQ0raVlEc7pUUH+lmvx0NoRop3rXFJr7p/Qt7wGEyRPPaV+IELykWXVftwCSWwJSvdhg+al8PcGIAV19qnYnPDEBSFKZIY1EDeo39R5oY0Hmx2AUH1yMLn589i7zdhaUjAOL1Cdq9lEsWsG2odc0aw4meKAWU4cAFBfR4GU3heUOfEzXk4tBlviYPaw1MEUo4y0IP25IWO5OOTdTR8b84med5m7d4uHub76nzO5Ex8P/S/n//3REjsAUYqcRvwWlOC4rnWSCULp2Puawto7qUJeVFJhkQPZJQJkOwGsqqMxDtc/UDK0= box@client
Clau pública
Section titled “Clau pública”Connecta’t per ssh a la màquina server
.
client$ ssh -v isard@server
Afegeix el contingut de la clau pública id_ed25519.pub
de la màquina client
al fitxer authorized_keys
de la màquina server
:
server$ echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPfc8GctAnRJpVUhKmewqabRNuJNBQQrGl94froIGclk box@client" >> ~/.ssh/authorized_keys
Surt de la màquina server
.
Connecta’t de nou per ssh a la màquina server
.
Aquest cop no et demanen la contrasenya:
client$ ssh -v isard@serverserver$
Com funciona?
- El
client
diu al servidor que utilitzarà la clau públicassh-ed25519 AAAA...clk box@client
. - El
server
verifica que aquesta clau està en el fitxerauthorized_keys
. - El
server
genera un text aleatori, el xifra amb la clau pública declient
i l’envia alclient
. - El
client
desxifra el text, el combina amb un identificador de sessió que han negocaiat prèviament i genera un hash MD5. - El
client
envia el hash alserver
. - Com que el
server
té el text original i l’identificador de sessió, genera el hash i verifica que el que li ha enviat elclient
és igual.
Missatge de benvinguda
Section titled “Missatge de benvinguda”Cada cop que crees una sessió, l’usuari root
executa els scripts que estan a la carpeta /etc/update-motd.d
.
motd
vol dir “Message of the day” i és el que apareix cada cop que et conectes a les màquines remotes.
Connecta’t a la màquina server
i elimina el permís d’execució dels scripts que estan a la carpeta /etc/update-motd.d
server$ sudo chmod -x /etc/update-motd.d/*
Usuari
Section titled “Usuari”Si el nom d’usuari de la màquina client és diferent al servidor remot, has de passar el nom de l’usuari remot.
El motiu és que una clau no està associada a cap usuari en concret: una mateixa clau pública la pot utilizar més d’un usuari a la màquina server
.
El servidor el que fa es buscar la clau pública en el fitxer ~/.ssh/authorized_keys
del home de l’usuari.
Crea un nou usuari sasha
a server
:
{% sol %}
server$ sudo adduser sasha
{% endsol %}
Afegeix la clau pública ed25519 de client
al fitxer ~/.ssh/authorized_keys
de sasha
:
{% sol %}
sever$ sudo su sashaserver$ cdserver$ mkdir .sshecho "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPfc8GctAnRJpVUhKmewqabRNuJNBQQrGl94froIGclk box@client" >> ~/.ssh/authorized_keys
{% endsol %}
Surt de la màquina server
.
Connecta’t a la màquina server
amb l’usuari sasha
:
{% sol %}
client$ ssh -v sasha@serverserver$ $ pwd/home/sasha
{% endsol %}
Claus diferents
Section titled “Claus diferents”Si vols utilitzar una clau específica per un usuari remot ho pots fer.
client$ ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_toto -C "toto@server"
Crea l’usuari toto
a la màquina server
.
A continuació copia la clau ~/.ssh/id_ed25519_toto.pub
a server
:
Com que ets pots autenticar amb contrasenya pots utilizar ssh-copy-id
:
client $ ssh-copy-id -i .ssh/id_ed25519_toto.pub toto@server/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: ".ssh/id_ed25519_toto.pub"/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keystoto@server's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'toto@server'"and check to make sure that only the key(s) you wanted were added.
Si intentes accedir a server
amb l’usuari toto
pots veure que el sistema de clau no funciona:
$ ssh -v toto@servertoto@server's password:
El motiu és que ssh està utilitzant la clau id_ed25519
, no la clau id_ed25519_toto
.
Has de indicar a l’ordre ssh
que utitlizi la clau de toto
:
client$ ssh -i .ssh/id_ed25519_toto toto@serverserver$ pwd/home/toto
ssh-config
Section titled “ssh-config”Analitzem a la màquina server-desktop la configuració de l’arxiu de configuració global per al client. Alguns exemples incloent la configuració del port, l’ús de claus privades, temps d’espera, etc.
/etc/ssh/ssh_config
Host *# ForwardAgent no# ForwardX11 no# ForwardX11Trusted yes# PasswordAuthentication yes# HostbasedAuthentication no# GSSAPIAuthentication no# GSSAPIDelegateCredentials no# GSSAPIKeyExchange no# GSSAPITrustDNS no# BatchMode no# CheckHostIP no# AddressFamily any# ConnectTimeout 0# StrictHostKeyChecking ask# IdentityFile ~/.ssh/id_rsa# IdentityFile ~/.ssh/id_dsa# IdentityFile ~/.ssh/id_ecdsa# IdentityFile ~/.ssh/id_ed25519# Port 22# etc
TODO
scp
(“secure copy”) et permet copiar fitxers i directoris de manera segura entre dos màquines.
L’ordre scp
utilitza ssh
: per tant, primer verifica que ssh
funciona.
Copiar un fitxer local a un sistema remot
Section titled “Copiar un fitxer local a un sistema remot”Baixa “Don Quijote” a la màquina client
:
client$ wget -q https://www.gutenberg.org/cache/epub/2000/pg2000.txt -O don-quijote.txt
Copia don-quijote.txt
a `server:
client$ scp don-quijote,txt isard@server:/home/isarddon-quijote.txt 100% 2174KB 5.9MB/s 00:00
Molt ràpid, menys d’1 segon. S’haurà copiat ? 🤔
$ ssh isard@server 'ls -l'total 2176-rw-r--r-- 1 isard isard 2225845 oct 13 15:01 don-quijote.txt
Doncs si!
Has vist que puc executar directament una ordre en el servidor remot 😃
scp
funciona com cp
excepte que abans del path puc posar el servidor.
Per exemple puc copiar un fitxer dins la mateixa màquina com si fos cp
:
client$ scp don-quijote.txt don-quijote.txt.copyclient:~$ lsdon-quijote.txt don-quijote.txt.copy
Si vols pots copiar el fitxer amb un altre nom:
client$ scp don-quijote.txt isard@server:/home/isard/don-quixote.txtdon-quijote.txt 100% 2174KB 4.2MB/s 00:00client:~$ ssh isard@server 'ls -l'total 4352-rw-r--r-- 1 isard isard 2225845 oct 13 15:01 don-quijote-rw-r--r-- 1 isard isard 2225845 oct 13 15:10 don-quixote.txt
I com passa amb cp
els permissos de fitxers es respecten.
L’usuari isard
no pot copiar un fitxer a una carpeta de l’usuari sasha
en la màquina server
:
$ scp don-quijote.txt isard@server:/home/sashascp: dest open "/home/sasha/don-quijote.txt": Permission deniedscp: failed to upload file don-quijote.txt to /home/sasha
Si no especifiques la ruta de destí, per defecte es copia a la carpeta “home” de l’usuari:
client$ scp don-quijote.txt sasha@server:don-quijote.txt 100% 2174KB 5.7MB/s 00:00client:~$ ssh sasha@server 'ls -l'total 2176-rw-r--r-- 1 sasha sasha 2225845 oct 13 15:14 don-quijote.txt
Fixa’t que el destí és sasha@server:
… els dos punts finals són molt importants.
Si no els poses, scp
pensa que el destí és un fitxer local (típic error d’examen) 😮💨
client$ scp don-quijote.txt sasha@serverclient:~$ ls -ltotal 6528-rw-r--r-- 1 box box 2225845 Oct 1 18:42 don-quijote.txt-rw-r--r-- 1 box box 2225845 Oct 13 17:08 don-quijote.txt.copy-rw-r--r-- 1 box box 2225845 Oct 13 17:17 sasha@server
També pots copiar un directori de manera recursiva amb el flag -r
(igual que amb cp
):
$ scp -r /usr/bin isard@server:truncate 100% 39KB 335.8KB/s 00:00dbus-monitor 100% 26KB 562.2KB/s 00:00pkttyagent 100% 22KB 576.6KB/s 00:00dh_bash-completion 100% 4527 105.9KB/s 00:00perl5.38-x86_64-linux-gnu 100% 14KB 361.7KB/s 00:00gp-archive 100% 159KB 1.3MB/s 00:00lzgrep 100% 10KB 241.0KB/s 00:00readelf 100% 771KB 1.7MB/s 00:00loadunimap 100% 34KB 858.4KB/s 00:00uname 100% 35KB 870.5KB/s 00:00localectl 0% 0 0.0KB/s --:-- ETA^Cbox@client:~$
Copiar un fitxer remot a un sistema local
Section titled “Copiar un fitxer remot a un sistema local”És el mateix que abans, però ara al fitxer origen li hem de dir de quina màquina.
client$ rm *client $ scp isard@server:don-quijote.txt .don-quijote.txt 100% 2174KB 3.8MB/s 00:00client$ ls -ltotal 2176-rw-r--r-- 1 box box 2225845 Oct 13 17:27 don-quijote.txt
Copiar un fitxer entre dos sistemes remots
Section titled “Copiar un fitxer entre dos sistemes remots”Copia la clau id_ed25519
a la màquina desktop
:
{% sol %}
$ ssh-copy-id -i .ssh/id_ed25519.pub isard@desktop
{% endsol %}
Borra el fitxer don-quijote.txt
de la màquina local.
Copia don-quijote.txt
de server
a desktop
:
{% sol %}
client$ scp isard@server:don-quijote.txt isard@desktop:don-quijote.txt 100% 2174KB 3.1MB/s 00:00client:~$ ssh isard@desktop 'ls -l'total 2216drwxr-xr-x 2 isard isard 4096 ago 5 12:37 Desktopdrwxr-xr-x 2 isard isard 4096 jul 3 21:56 Documents-rw-r--r-- 1 isard isard 2225845 oct 13 17:34 don-quijote.txt...
{% endsol %}
Opcions
Section titled “Opcions”TODO
scp ofereix una sèrie d’opcions que controlen tots els aspectes del seu comportament.
- L’opció -p conserva els temps de modificació i accés dels fitxers.
- L’opció -q suprimeix el mesurador de progrés i els missatges sense error.
- L’opció -C obliga a scp a comprimir les dades a mesura que s’envien a la màquina de destinació.
Servidor SSH
Section titled “Servidor SSH”Python
Section titled “Python”Crea un projecte ssh
a la màquina client amb {% link “/python/poetry/” %}
$ sudo apt install -y python3-poetry$ $ poetry new ssh --name appCreated package app in ssh$ code ssh
Entra dins la carpeta ssh
i instal.la la llibreria paramiko
:
$ poetry add paramiko
Executar una ordre
Section titled “Executar una ordre”Crea l’script app/main.py
:
import paramiko
try: client = paramiko.client.SSHClient() # Let know Paramiko that you validate your trust with the machine for the first time you try to connect to the server. client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect("server", username="isard")
stdin, stdout, _ = client.exec_command("ls -l") print(stdout.read().decode()) stdin.close()
finally: client.close()
Executa l’script:
$ poetry run python3 app/main.pytotal 4368drwxr-xr-x 2 isard isard 4096 oct 13 15:21 bin-rw-r--r-- 1 isard isard 2225845 oct 13 15:01 don-quijote.txt-rw-r--r-- 1 isard isard 2225845 oct 13 15:10 don-quixote.txt
Transferir un fitxer
Section titled “Transferir un fitxer”Baixa el llibre “Frankestein”:
$ wget -q https://www.gutenberg.org/cache/epub/84/pg84.txt -O frankestein.txt
Modifica el fitxer app/main.py
:
import paramiko
try: client = paramiko.client.SSHClient() # Let know Paramiko that you validate your trust with the machine for the first time you try to connect to the server. client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect("server", username="isard")
ftp_client = client.open_sftp() ftp_client.put("frankestein.txt", "frankestein.txt") ftp_client.close()
finally: client.close()
Transfereix el llibre:
$ poetry run python3 app/main.py$ ssh isard@server 'ls -l | grep fran'-rw-rw-r-- 1 isard isard 448937 oct 13 16:04 frankestein.txt
El contingut d'aquest lloc web té llicència CC BY-NC-ND 4.0.
©2022-2025 xtec.dev