Ce este SSH?

Ce e ssh si de ce imi trebuie? Pe scurt: Ca sa nu fii hakuit cand povestesti/accesezi resurse la distanta. Dupa mine ssh ofera cel mai bun raport siguranta/comoditate!

Se poate accesa git si fara ssh? Cred ca da, dar cu siguranta vei tasta user/parola pana te saturi. Si exista riscul sa fii hakuit.

Ce e ssh? (mai lung)

E o metoda de a crea un “tunel” intre 2 puncte, tunel care garanteaza ca:

  • Te conectezi la masina la care vrei sa te conectezi (si nu la un hacker)
  • Masina la care te conectezi se asigura ca esti autorizat sa accesezi resursele
  • Nici un bit “secret” (aka parola sau cheie privata) nu pleaca de pe calculatorul tau
  • Poti “forwarda” un protocol nesecurizat prin acest tunel ssh
  • Se poate “forwarda indentitatea” de pe masina locala pe cea remote, FARA a fi necesara copierea cheii private
  • Multe alte tool-uri sunt facute sa functioneze cu ssh. Daca ai acces ssh, cu putina indemanare, poti lucra pe calculatorul de la distanta, ca si cum ai lucra local

Ask google ca sigur exista explicatii mai bune.

Cum functioneaza?

Ai o pereche de chei. Cheia publica si privata.

Cheia privata trebuie sa ramana intr-un loc sigur, pe calculator. Poate fi protejata cu o parola, in caz ca cineva iti acceseaza neautorizat laptopul (eg se fura laptopul). Cheia privata encripteaza traficul si valideaza faptul ca esti cine spui ca esti.

Cheia publica e well, publica! Ea se pune pe calculatorul destinatie, unde vrei sa te conectezi. Doar cheia privata poate fi folosita pentru a “deschide” cheia publica. Asa ca tu ca user, poti da la un coleg cheia publica. Peste un timp, cand vreti sa comunicati la distanta, colegul tau va sti ca esti tu, din cauza ca doar tu ai cheia privata. Nu poate interveni o tertza persoana intre voi ca sa spioneze sau sa altereze traficul. Conditia zero e ca transferul de cheie publica sa se faca pe un canal mai sigur (eg iti da personal cheia). Bun, scenarii un pic SF, dar sunt script-uri care “spioneaza” si altereaza exact acest schimb de chei.

Teoretic, cheia privata este accesata de un program special, care, e un fel de intermediar intre programele care vor sa acceseze resurse la distanta, si resursa respectiva. Alte soft-uri care vor sa comunice prin ssh (eg IDE-ul, git-scm, toate folosesc acest intermediar)

Pe scurt, trebuie sa:

  1. Generam o pereche de chei (o singura data)
  2. Punem cheia publica pe calculatorul de la distanta (o singura data, pe fiecare masina pe care vrem sa ne conectam)
  3. Ne conectam (well, de fiecare data cand vrem sa ne conectam)

Generarea de chei

Atat pe windows 10 cat si pe Linux exista OpenSSH. Pentru a testa ca aveti OpenSSH deschideti o consola si tastati:

ssh -V

Daca apare versiunea, exista OpenSSH pe calculator.

Daca apare o eroare, google: “How to install OpenSSH on xxx”. Pe windows 10, trebuie activat de la Features. Pe linux, sudo apt-get sau echivalent. Atentie, pe windows, va recomand sa puneti doar clientul, NU si serverul.

Primul pas, generarea cheii. Deschizi o consola (bash sau cmd) si dai:

ssh-keygen -t rsa -b 4096

Adica, fa-mi o cheie de tip RSA (cam cel mai comun), de 4096 biti lungime. Puteti specifica unde se salveaza cheia (id_rsa e bine), sa specificati o parola (passphrase) recomandat daca lucrati pe laptop, dar, poate fi adaugat si dupa.

Dureaza cateva secunde dupa care cheia e salvata. In folderul .ssh gasit in C:\users\username\ sau /home/username/ gasiti 2 fisiere: id_rsa si id_rsa.pub. Cel cu .pub e cheia publica.

RSA e un standard mai vechi deci mai bine suportat. Deocamdata nu am avut probleme cu el. Exista si standarde mai noi. Google: EdDSA si how to generate EdDSA key with OpenSSH.

Dupa ce o sa se faca un update la windows, veti putea “ingropa” cheia privata adanc in windows, cu ssh-agent. Deocamdata e dezactivat pentru ca exista ceva conflicte (distributia de pe Windows e mai veche). Pe Linux, rar am avut probleme, dar daca sunt, google it. Pe Linux am preferat sa encriptez toata partitia cu /home/ si atunci nu am mai avut stress cu parola pe cheia privata.

Alte optiuni ale lui ssh-keygen utile pentru a manipula chei

  • Cand generati cheia, puneti -f nume_fisier_cheie pentru a specifica numele fisierului
  • Optiunea -p permite modificarea parolei de la cheie: ssh-keygen -p -f cheie_test  va cere vechea parola si va seta o noua parola
  • Optiunea -c permite modificarea comentariului de la cheie: ssh-keygen -c -f cheie_test  va afisa vechiul comentariu si va seta unul nou.
  • Optiunea -C (Capital C) poate fi folosita cand se genereaza cheia, pentru a seta din start comentariul

Mai jos, un exemplu mai complet:

ssh-keygen -t rsa -b 4096 -C "Comentariu" -f nume_fisier_cheie

Punem cheile pe “calculatorul” de la distanta

Aici e nevoie de acces la masina respectiva. Ori acces fizic, ori va rezolva ‘admin-ul’ ori aveti o alta metoda de autentificare (ex user/parola), ori un portal web in care va autentificati.

Sunt doua cazuri, vreti sa accesati o masina (eg un calculator puternic partajat de mai multi) sau vreti sa accesati alt tip de resurse prin ssh (exemplu concret, acces la un repository git)

Pentru acces la git, trebuie sa intrati prin portalul web al serviciului, la setari si sa va salvati acolo cheia publica.

Pe un server/workstation

Pentru linux, trebuie sa “legati” cheia publica de contul unui utilizator existent. In directorul home al userului (fie /home/user/ sau C:\users\user) exista un director “ascuns” .ssh/.

Pentru a lega cheia publica de acest user, trebuie sa faceti copy/paste pe un rand nou, in fisierul ~/.ssh/authorized_keys. Daca nu exista, il creati.

Alternativ, folositi de pe calculatorul dvs comanda ssh-copy-id daca deja aveti acces cu user/parola (google it).

Pentru un server windows, puteti face acelasi lucru odata ce activati serverul de ssh (sshd). Inainte sa deschideti un server de ssh pe o masina expusa public, CITITI cu atentie niste documentatii si “best practices”.

Portalul Github:

Va logati pe github.com, dati click pe sageata de langa user (dreapta sus) si intrati la Settings.

Apoi, SSH and GPG Keys, si Add New. Copy paste la continutul fisierului id_rsa.pub

Gitlab (instanta gazduita de UTCN):

Va logati, dati click pe sageata de langa user (dreapta sus) si intrati la Settings.

Mergeti la SSH Keys si copy paste la continutul fisierului id_rsa.pub

Acces la resursa de la distanta

Aici e simplu, dati comanda:

ssh user@adresa

Adresa e adresa masinii pe care vreti sa o accesati. Atentie, user se refera la user-ul Linux sau Windows in a carui folder .ssh ati copiat cheia (unde ati facut append la authorized_keys) Ar trebui sa va deschida o consola (cmd sau bash) la calculatorul de la distanta.

Pentru a testa cheia legata de contul vostru de github, intr-o consola:

ssh -T git@github.com

Ar trebui sa va zica “Hi xxx! You’ve successfully authenticated, …”

Cam la fel si pe gitlab:

ssh -T git@gitlab.utcluj.ro

Optiuni ale protocolului

Conectarea la un port diferit de 22

Unele servere SSH sunt configurate sa asculte la alt port decat 22. Implicit, comanda ssh se va conecta la portul 22. Pentru a preciza alt port, folosim optiunea -p PORT. Exemplu:

ssh user@adresa -p 69420

Folosirea port forwarding

Un scenariu des intalnit este atunci cand avem acces la o masina puternica si vrem sa accesam un server de pe acea masina. De exemplu, serverul jupyter ce ne permite sa lucram in Python. Serverul va rula pe masina de la distanta (ce are probabil multe GPU-uri si RAM) dar codul si rezultatele executiei vrem sa le vedem local. Ar fi foarte comod daca am putea folosi browser-ul local ca sa ne conectam la acest server remote. Acest use case este acoperit perfect de port forwarding.

Optiunea pentru ssh este -L local_port:remote_addr:remote_port  unde:

  • local_port este portul local. Tot traficul pe acest port va fi trimis pe calculatorul remote.
  • remote_addr este de obicei 127.0.0.1. Pentru use-case-uri mai avansate, cautati pe google detalii.
  • remote_port este portul la care serverul remote asculta. Tot traficul de pe local_port va fi trimis aici.

Aveti mai jos o schema a conexiunii si a etapelor ce trebuie facute. Optiunile de ssh pot fi prescurtate folosint fisierul de config.

Folosirea fisierului config

Clientii de windows de obicei salveaza intern setarile. Puteti gasi relativ usor optiunile grafice care schimba portul de conectare sau activeaza port forwarding. Pe linux, avem optiunea de a “salva” toate aceste setari sub un nickname. Acest nickname este recunoscut atat de utilitarul ssh cat si de alte programe care pot comunica prin ssh. Exemplu, rsync.

Fie o comanda complexa de conectare:

ssh cristi@adresa.com -p 69420 -L 8000:127.0.0.1:8888

care incearca sa se conecteze la masina adresa.com, pe portul 69420 si realizeaza si un port forwarding de la portul local 8000 la portul remote 8888.

Putem crea/adauga in fisierul ~/.ssh/config urmatoarea setare:

Host server_puternic
    Hostname adresa.com
    User cristi
    Port 69420
    LocalForward 8000 127.0.0.1:8888

Mai sunt si alte optiuni (d.e. specificarea unei alte chei private) dar nu sunt folosite des.

Dupa ce am scris textul de mai sus in fisierul de configurare, putem executa comanda simpla:

ssh server_puternic

sau

rsync -azvP proiect/surse server_puternic/work/proiect/surse

Toate optiunile legate de cheie, port, etc. sunt preluate si aplicate automat.

Forwardarea identitatii (Agent Forwarding)

Un alt use case comun este urmatorul. Am setat un cont pe git, am adaugat cheile publice ale masinii locale, am conexiune cu masina remote (sau intr-un docker al masinii remote) si veau sa fac clone la repo, pe masina remote. Ar fi cateva optiuni “brute force”:

  • Copiez cheia privata pe masina remote: NU! Risc major de securitate
  • Generez o pereche de chei pe masina remote si le adaug in github. Foarte costisitor ca timp si risc de securitate (oricine de pe masina poate inspecta docker-ul si sa ia cheia de acolo)

Din fericire ssh vine cu un tool care “trimite” identitatea de pe masina locala, pe masina remote. Aduceti-va aminte ca de fapt, cheia privata nu pleaca. La autentificare, agentul demonstreaza cu o operatie matematica, faptul ca detine cheia privata corespunzatoare. Evident, comunicarea aceasta se poate face si prin tunelul existent. Tot ce trebuie sa facem e sa configuram agentul local.

Pentru linia de comanda exista optiunea -A iar pentru fiserul config se adauga ForwardAgent yes la setarile conexiunii.

Forwardarea doar a unei anumite chei

Se intampla ca pe calculatorul local sa avem mai multe chei. Cand ne conectam pe masina remote, selectarea cheii potrivite e simpla. Editam fisierul config si setam IdentityFile. Dar, optiunea -A, dupa cum ii zice si numele, face forward la agent! Nu doar la o cheie! Asta inseamna ca pe masina remote, vom avea accesibile toate cheile! Pentru a “selecta” o anumita cheie, folosim urmatorul truc:

  • Notam numele cheii folosite la conectare de pe calculatorul local. Adica, cheia specificata la IdentityFile.
  • Pe masina remote, in folderul .ssh cream manual un fisier .pub cu nume identic. 
  • Copiem in acel fisier de pe masina remote, continutul partii publice a perechii de chei care o vrem a fi forwardata. In acest fel, agentul ssh de pe masina remote, va prelua cheia respectiva si va interoga agentul local despre partea privata a cheii.

Pentru mai multe detalii cautati “Agent Forwarding” pe net.

Pastrarea executiei programelor dupa ce se inchide consola

Cand inchidem o consola sau o conexiune SSH, toate programele pornite in/de consola se vor opri automat. Pentru a evita acest lucru si a pastra deschis (ex facem o antrenare de lunga durata si vrem totusi sa inchidem laptop-ul) folositi tmux sau screen.  Personal imi place mai mult tmux. Acestea sunt niste servere care ruleaza la nivel de masina si ofera un “buffer” intre consola si sistem. Din consola curenta ma pot conecta la acest buffer si sa continui munca. Cand ma deconectez, buffer-ul se pastreaza in memoria masinii.

Pasi:

  • Ma conectez cu ssh
  • Rulez in consola, tmux new pentru a genera o noua sesiune
  • Faceti-va treaba
  • Dati CTRL-b, d adica tastele CTRL si b in acelasi timp, dupa care tasta d. Acest lucru va va deconecta de la sesiune. Ea va ramane activa in memorie. Acelasi efect este si daca inchideti efectiv fereastra de consola.
  • Iesiti cu exit din sesiunea de SSH. Programele pornite in cadrul sesiunii ruleaza in continuare. Dar atentie, inchizand SSH, pierdeti port forwarding si alte facilitati ce mergeau prin ssh.

Peste ceva timp, vreti sa reveniti sa vedeti cum a progresat calculul:

  • Va conectati cu ssh
  • Dati tmux a pentru a va conecta la sesiunea voastra
  • Cand terminati, dati disconnect de la sesiune si apoi exit la ssh.
  • Daca vreti sa inchideti sesiunea de tmux, dati exit pana iesiti din sesiune.

Desi nu tine de ssh, combinatia e folosita foarte des. Explorati optiunile de la tmux (se poate crea un fisier de configurare) pentru a vedea tot felul de facilitati foarte interesante. De ex mai multi oameni conectati la aceeasi consola (remote pair programming) sau ferestre de consola multiple, vizibile in acelasi timp pe ecran. 

Daca nu aveti instalat un astfel de tool pe masina, cereti administratorului sa instaleze.

Alte tool-uri

Ecosistemul este foarte mare. Va enumar cateva care va sunt utile(google them)

  • ssh-copy-id ca sa puneti cheia publica, pe o masina la care deja aveti acces cu user/parola
  • ssh-keygen pentru alte optiuni (eg adaugare/scoatere passphrase)
  • ssh-agent pentru setari avansate de securitate
  • rsync pentru transfer de fisiere foarte usor intre calculatoare (probabil doar Linux)
  • Bitvise Tunellier, un client Windows, de SSH.
  • WinScp pentru transfer GUI de fisiere, peste ssh.
  • Putty, nerecomandat de mine, dar alternativa pentru soft-urile care nu stiu lucra cu OpenSSH
  • sshd pentru serverul de ssh, cand vreti sa configurati voi masina la care va conectati
  • ssh: optiuni pentru specificarea portului, debug-ul conexiunii, key forwarding, port forwarding, etc.

Ceva nu a mers bine

Google sau imi scrieti. Exista TONE de documentatie si explicatii.