Laborator 8. Securizarea unui server

Cunoștințe și abilități ce vor fi dobândite

  • Cunoștințe generale legate de securizarea rețelei
  • Avantajele și dezavantajele formelor de transfer securizat (criptat) și nesecurizat (în clar)
  • Folosirea utilitarului iptables pentru configurarea unui firewall pe Linux
  • Folosirea protocolului SSH și a utilitarelor aferente pentru conectarea la distanță și transferul securizat de fișiere

Pregătire infrastructură de laborator

  • Vom rula o masină virtuală în cloud-ul facultății
  • Pentru a porni o astfel de masină urmăriți tutorialul de la această adresă
  • FOLOSIȚI IMAGINEA RL_2018 (cea de 2019 nu merge :D );
  • Pentru a pregăti configurația de laborator, pe mașina virtuală (stația host) folosiți comenzile următoare din contul utilizatorului root de pe stația host (puteți da copy/paste la comenzi în terminal):
    root@host:~# wget https://raw.githubusercontent.com/RL-UPB/rl-lab-prepare/master/rl-lab-08-prepare
    root@host:~# chmod +x rl-lab-08-prepare
    root@host:~# ./rl-lab-08-prepare

    Comanda durează circa 20 de secunde. Lasați-o să ruleze complet.

  • Deschideți trei noi tab-uri în terminal (folosiți combinația de taste Ctrl+Shift+t), și conectați-vă, din nou, la mașina virtuală folosind comanda ssh de mai sus.
    • De pe cele trei noi tab-uri, conectați-vă la cele trei containere (red, green și blue) folosind comanda
      root@host:~# go <nume-container>

      și autentificați-vă ca utilizatorul root cu parola student.

Detalii rulare masina virtuala VMware local

Detalii rulare masina virtuala VMware local

  • Deschideți VMware și porniți mașina virtuală RL_lab.
  • Dorim să folosim terminalul sistemului fizic și să lucrăm peste SSH cu mașina virtuală VMware (denumită și host). În acest fel vom putea folosi copy-paste în terminal sau alte facilități. Pentru aceasta urmați pașii de mai jos:
    • Autentificați-vă în mașina virtuală folosind contul root cu parola student.
    • Aflați adresa IP a mașinii virtuale de pe interfața eth0:
      root@host:~# ifconfig eth0
    • De pe sistemul fizic, deschideți un terminal și realizați o sesiune SSH folosind:
      student@mjolnir:~$ ssh root@$ADRESA_IP_MV

      unde $ADRESA_IP_MV este adresa IP a mașinii virtuale așa cum ați obținut-o mai sus.

Pentru a vedea cum accesați stațiile red, green și blue (containere LXC configurate peste mașina virtuală VMware - stația host) urmăriți pașii de aici.

Conturile de acces la mașina virtuală (stația host) sunt (username:parola):

  • root:student
  • student:student

Topologie

Exerciții

Pentru a primi întregul punctaj va trebui ca la finalul laboratorului să ștergeți mașina virtuală pornită și să îi arătați asistentului listarea instanțelor din OpenStack.

1. [5p] Trafic criptat și necriptat

Traficul generat de servicii se clasifică în trafic criptat și trafic în clar. Traficul în clar (necriptat) poate fi interpretat și înțeles dacă este capturat. Traficul criptat nu poate fi interpretat în absența cheii de criptare; doar transmițătorul și receptorul cunosc cheia pentru a putea comunica.

Ne propunem să analizăm, din punctul de vedere al criptării traficului, următoarele protocoale/servicii:

  • telnet (port TCP 23)
  • SSH (port TCP 22)
  • FTP (port TCP 21)

Vom folosi dsniff, un utilitar cu ajutorul căruia putem captura în clar pachetele care trec printr-un anumit server, pentru a afișa datele transmise (username, parolă, comenzi). Vom folosi topologia de laborator și ne vom conecta de la stația red la stația green prin intermediul stației host.

Pentru a porni procesul de captură, autentificați-vă ca root pe stația host și rulați comanda

root@host:~# dsniff -i veth-green

Pentru comunicație prin telnet, rulați pe stația red comanda

root@red:~# telnet green

În urma rulării comenzii ați realizat o conexiune telnet de la stația red la stația green prin intermediul stației host. La prompt-ul generat de comandă folosiți username-ul student și parola student; după aceea rulați comanda ls și apoi comanda exit pentru a închide conexiunea. Observați pe stația host captura credențialelor (username și parolă) transmise prin telnet între stațiile red și green ⇒ traficul telnet între cele două stații a fost trafic în clar și a fost capturat pe stația host.

dsniff capturează traficul de rețea și afișează credențialele doar la încheierea conexiunilor. Trebuie folosite comenzi de tipul exit pentru a închide conexiunea și pentru ca dsniff să afișeze credențialele.

Pentru comunicație prin FTP, rulați pe stația red comanda

root@red:~# ftp green

În urma rulării comenzii ați realizat o conexiune FTP de la stația red la stația green prin intermediul stației host. La prompt-ul generat de comandă folosiți username-ul student și parola student; după aceea rulați comanda ls și apoi comanda quit pentru a închide conexiunea. Observați pe stația host captura credențialelor (username și parolă) transmise prin FTP între stațiile red și green ⇒ traficul FTP între cele două stații a fost trafic în clar și a fost capturat pe stația host.

Pentru comunicație prin SSH, rulați pe stația red comanda

root@red:~# ssh -l student green

În urma rulării comenzii ați realizat o conexiune SSH de la stația red la stația green prin intermediul stației host. În sesiunea de shell deschisă la distanță, rulați comanda ls și apoi comanda exit pentru a închide conexiunea. Observați că pe stația host dsniff nu afișează informații despre credențialele (username și parolă) transmise între stațiile red și green ⇒ traficul SSH între cele două stații a fost trafic criptat și nu a putut fi capturat pe stația host.

Pe stația host, pentru a opri comanda dsniff folosiți combinația de taste Ctrl+c.

Traficul telnet și FTP este trafic necriptat (în clar), în timp ce traficul SSH este trafic criptat.

2. [5p] Blocare servicii necriptate

După cum ați observat la punctul anterior, traficul pentru protocoalele telnet și FTP este trafic în clar, necriptat, putându-se afla cu ușurință credențialele unui anumit cont și comenzile rulate.

Ne propunem să blocăm accesul de la stația red către stația green pentru aceste servicii, configurând ruterul dintre cele două stații, adică stația host. Practic vom configura pe stația host opțiuni de firewall cu ajutorul utilitarului iptables.

Prezentare scurtă iptables (dați click)

Prezentare scurtă iptables (dați click)

iptables este un utilitar Linux care oferă și rol de firewall software. iptables folosește suportul nucleului pentru a intercepta pachete de rețea în diverse puncte ale trecerii acestora prin nucleu și a efectua acțiuni asupra acestora. Astfel de acțiuni sunt:

  • acceptarea pachetului (ACCEPT)
  • respingerea pachetului (REJECT)
  • aruncarea pachetului (DROP), similar cu respingerea dar nu se transmite nici o notificare de respingere către cel care a transmis pachetul inițial

O diagramă a drumului urmat de un pachet de rețea în nucleu este aici.

Comanda iptables înseamnă lucrul cu reguli de filtrare de la nivelul nucleului. În mod obișnuit se va preciza:

  • tipul de operație pe regulă (adăugare, ștergere, înlocuire, inserare)
  • punctul din nucleul în care trebuie să se găsească pachetul pentru a se aplica regula
  • regula în sine

De exemplu, comanda de mai jos are semnificația descrisă în continuare:

iptables -A FORWARD -d green -p tcp --dport telnet -j REJECT
  • -A: se adaugă regulă (este vorba de append, se adaugă la finalul listei de reguli);
  • FORWARD: regula se aplică pachetelor care vor fi rutate; alte variante sunt INPUT (pachetele primite direct de sistem) și OUTPUT (pachetele care pleacă de la sistem);
  • -d green: sunt selectate pachetele care au ca destinație adresa stației green;
  • -p tcp: pachetele selectate sunt pachete TCP;
  • --dport telnet: portul TCP destinație este portul specific protocolului telnet (adică portul 23, identificat din fișierul /etc/services)
  • -j REJECT: pachetul este respins

În tabela de filtrare aferentă iptables vom avea, așadar, o listă de reguli care sunt parcurse secvențial. Partea -A FORWARD identifică lanțul de reguli, partea -d green -p tcp --dport telnet este partea de match (ce pachete fac match pe regulă), iar partea -j REJECT este partea de acțiune (ce face regula cu pachetul).

Autentificați-vă prin SSH ca root pe stația host. Pentru a bloca accesul la serviciul telnet (port 23) destinat stației green, rulați pe stația host comanda de mai jos. Comanda adaugă regula iptables corespunzătoare.

root@host:~# iptables -A FORWARD -d green -p tcp --dport telnet -j REJECT

Pentru a verifica adăugarea regulii de mai sus, rulați pe stația host comanda

root@host:~# iptables -L FORWARD
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
REJECT     tcp  --  anywhere             green                tcp dpt:telnet reject-with icmp-port-unreachable

Pentru a afișa informații și despre pachetele prelucrate și interfețele folosite, rulați pe stația host comanda

root@host:~# iptables -L FORWARD -v
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 REJECT     tcp  --  any    any     anywhere             green                tcp dpt:telnet reject-with icmp-port-unreachable

Pentru a afișa informații în format numeric (pentru nume de stații și nume de porturi), rulați pe stația host comanda

root@host:~# iptables -L FORWARD -v -n
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 REJECT     tcp  --  *      *       0.0.0.0/0            192.168.2.2          tcp dpt:23 reject-with icmp-port-unreachable

De acum înainte recomandăm folosirea acestor opțiuni (-v -n) pentru listarea regulilor iptables.

Pentru a verifica blocarea traficului telnet către green, rulați pe stația red comanda

telnet green

Vă apare un mesaj de forma

Trying 192.168.2.2...
telnet: Unable to connect to remote host: Connection refused

semnificând faptul că se încearcă realizarea conexiunii dar conexiunea este respinsă

Pentru a vedea că regula de blocare a funcționat, rulați din nou pe stația host comanda

root@host:~# iptables -L FORWARD -v -n
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    2   120 REJECT     tcp  --  *      *       0.0.0.0/0            192.168.2.2          tcp dpt:23 reject-with icmp-port-unreachable

Observați, în output-ul comenzii, că există acum valori diferite de 0 în coloana pkts și bytes, semn că au fost pachete prelucrate de această regulă, deci blocate.

Pentru a verifica funcționarea în continuare a altor conexiuni (diferite de telnet) de la red la green, rulați pe stația red comenzile

ftp green
ssh -l student green

Dorim să blocăm și celălalt serviciu necriptat, FTP. Adăugați o regulă iptables similară pentru a bloca, pe stația host, traficul FTP destinat stației green. După adăugarea regulii folosiți iptables -L FORWARD -n -v pentru a valida adăugarea regulii.

Pentru această regulă puteți transmite argumentul 21 opțiunii --dport sau chiar numele ftp. Asocierea între port (număr) și protocol (nume) se găsește în fișierul /etc/services.

De pe stația red verificați blocarea traficului FTP către stația green folosind comanda

ftp green
Rezolvare
root@host:~# iptables -A FORWARD -d green -p tcp --dport ftp -j DROP
root@host:~# iptables -L FORWARD -n -v
Chain FORWARD (policy ACCEPT 94 packets, 10307 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    2   120 DROP       tcp  --  *      *       0.0.0.0/0            192.168.2.2          tcp dpt:23
    0     0 DROP       tcp  --  *      *       0.0.0.0/0            192.168.2.2          tcp dpt:21
 
root@red:~# ftp green
^C
 
root@host:~# iptables -L FORWARD -n -v
Chain FORWARD (policy ACCEPT 94 packets, 10307 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    2   120 DROP       tcp  --  *      *       0.0.0.0/0            192.168.2.2          tcp dpt:23
    2   120 DROP       tcp  --  *      *       0.0.0.0/0            192.168.2.2          tcp dpt:21

3. [5p] Blocare SSH

Ne propunem ca stația green să nu fie acesibilă nici prin SSH. Pentru aceasta adăugați pe stația host o regulă iptables care va bloca traficul aferent serviciului SSH (portul 22).

Rezolvare
root@host:~# iptables -A FORWARD -d green -p tcp --dport ssh -j DROP

Verificați adăugarea regulii iptables și apoi verificați de pe stația red blocarea traficului SSH către stația green.

Rezolvare
root@host:~# iptables -L FORWARD -n -v
Chain FORWARD (policy ACCEPT 94 packets, 10307 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    2   120 DROP       tcp  --  *      *       0.0.0.0/0            192.168.2.2          tcp dpt:23
    0   120 DROP       tcp  --  *      *       0.0.0.0/0            192.168.2.2          tcp dpt:21
    0     0 DROP       tcp  --  *      *       0.0.0.0/0            192.168.2.2          tcp dpt:22
 
root@red:~# ssh green
^C
 
root@host:~# iptables -L FORWARD -n -v
Chain FORWARD (policy ACCEPT 94 packets, 10307 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    2   120 DROP       tcp  --  *      *       0.0.0.0/0            192.168.2.2          tcp dpt:23
    2   120 DROP       tcp  --  *      *       0.0.0.0/0            192.168.2.2          tcp dpt:21
    3   180 DROP       tcp  --  *      *       0.0.0.0/0            192.168.2.2          tcp dpt:22

4. [5p] Ștergere regulă FTP

Dorim să permitem accessul FTP către stația green. Pentru aceasta pe stația host trebuie ștearsă regula iptables care blochează traficul FTP.

Pe stația host ștergeți regula iptables aferentă. Pentru a șterge o regulă folosiți comanda iptables cu opțiunea -D (delete) urmată de restul argumentelor; practic, comanda este identică celei de adăugare, doar că folosiți opțiunea -D în locul opțiunii -A.

Rezolvare
root@host:~# iptables -D FORWARD -d green -p tcp --dport ftp -j DROP

Listați regulile iptables pentru a verifica ștergerea regulii care bloca traficul FTP.

Rezolvare
root@host:~# iptables -L FORWARD -n -v
Chain FORWARD (policy ACCEPT 35 packets, 2147 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    2   120 DROP       tcp  --  *      *       0.0.0.0/0            192.168.2.2          tcp dpt:23 reject-with icmp-port-unreachable
    2   120 DROP       tcp  --  *      *       0.0.0.0/0            192.168.2.2          tcp dpt:22 reject-with icmp-port-unreachable

După ștergerea regulii verificați realizarea conexiunii prin FTP de la stația red la stația green. Verificați că nu se pot realiza conexiuni prin telnet sau SSH de la stația red la stația green.

Rezolvare
root@red:~# ftp green
Connected to green.
220 (vsFTPd 2.3.5)
Name (green:root): student
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
226 Directory send OK.
ftp> quit
221 Goodbye.
 
root@red:~# telnet green
Trying 192.168.2.2...
telnet: Unable to connect to remote host: Connection refused
 
root@red:~# ssh -l student green
ssh: connect to host green port 22: Connection refused

5. [5p] Ștergere reguli adăugate

Pentru a permite tot traficul către stația green, ștergeți pe stația host toate regulile iptables din lanțul FORWARD. Folosiți opțiunea -F (flush) a comenzii iptables. Practic revenim la situația inițială, fără reguli iptables pe stația host. Folosiți comanda iptables -L FORWARD -n -v pentru a valida ștergerea regulilor din lanțul FORWARD.

Rezolvare
root@host:~# iptables -F FORWARD
root@host:~# iptables -L FORWARD -n -v
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
root@host:~#

După ștergerea regulilor verificați funcționarea serviciilor telnet, FTP, SSH prin conectare de la stația red la stația green.

Rezolvare
root@red:~# ftp green
Connected to green.
220 (vsFTPd 2.3.5)
Name (green:root): ^C
 
root@red:~# ssh green
root@green's password: 
 
root@red:~# telnet green
Trying 192.168.2.2...
Connected to green.
Escape character is '^]'.
Ubuntu 12.04.3 LTS
green login: ^CConnection closed by foreign host.

6. [5p] Blocare completă a traficului

Pentru început verificați că stația red poate accesa alte stații din rețea. Rulați comanda

root@red:~# ping -c 2 green
PING green (192.168.2.2) 56(84) bytes of data.
64 bytes from green (192.168.2.2): icmp_req=1 ttl=63 time=0.076 ms
64 bytes from green (192.168.2.2): icmp_req=2 ttl=63 time=0.067 ms
 
--- green ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.067/0.071/0.076/0.009 ms

Asocierile între porturi și protocoale (21 și FTP, 22 și SSH, 23 și telnet) sunt cele implicite. Acest lucru nu împiedică însă un administrator să configureze un serviciu să asculte pe un port diferit de cel implicit. Pentru a preveni transferul de fișiere și conectare de la distanță pe stația red vom bloca accesul la toate porturile. Pentru aceasta vom configura stația host pentru a bloca întreg traficul de la stația red. Pentru blocarea întregului trafic rulați comanda

root@host:~# iptables -A FORWARD -s red -j REJECT
root@host:~# iptables -L FORWARD -n -v
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 REJECT     all  --  *      *       192.168.1.2          0.0.0.0/0            reject-with icmp-port-unreachable

Comanda blochează întreg traficul de la stația red (opțiunea -s) pe care stația host l-ar fi rutat (lanțul FORWARD).

Verificați că stația red nu poate accesa alte stații. Rulați comenzile

root@red:~# ping -c 2 green
PING green (192.168.2.2) 56(84) bytes of data.
From host (192.168.1.1) icmp_seq=1 Destination Port Unreachable
From host (192.168.1.1) icmp_seq=2 Destination Port Unreachable
 
--- green ping statistics ---
2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 999ms
 
root@red:~# telnet green
Trying 192.168.2.2...
telnet: Unable to connect to remote host: Connection refused
 
root@red:~# ftp green
ftp: connect: Connection refused
ftp> exit
 
root@red:~# ssh -l student green
ssh: connect to host green port 22: Connection refused

Observați că nu mai sosesc pachete de răspuns (sunt respinse de stația host), deci traficul de la stația red este blocat.

7. [10p] Permitere trafic SSH

În acest moment, traficul de la stația red către celelalte stații din rețea este blocat.

Dorim să permitem traficul SSH de la stația red către stația green. Adăugați o regulă corespunzătoare pe stația host.

Rezolvare
root@host:~# iptables -A FORWARD -s red -d green -p tcp --dport ssh -j ACCEPT

După ce ați adăugat regula, încercați realizarea unei conexiuni SSH de la stația red la stația green. Observați că nu se realizează conexiunea.

Rezolvare
root@red:~# ssh green
^C

Afișați lista de reguli iptables de pe stația host. De ce nu a reușit conexiunea? Țineți cont de ordinea regulilor afișate; sunt parcurse secvențial.

Rezolvare
root@host:~# iptables -L FORWARD -n -v
root@host:~# iptables -L FORWARD -n -v
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    6   360 REJECT     all  --  *      *       192.168.1.2          0.0.0.0/0            reject-with icmp-port-unreachable
    0     0 ACCEPT     tcp  --  *      *       192.168.1.2          192.168.2.2          tcp dpt:22

Regulile sunt parcurse secvențial. Conform primei reguli, tot traficul transmis de stația red este blocat. A doua regulă nu mai este parcursă. Trebuie să mutăm a doua regulă pe prima poziție.

Pentru rezolvarea problemei ștergeți regula iptables introdusă anterior și inserați regula pe stația host. Pentru inserare folosiți opțiunea -I a comenzii iptables. Verificați că acum conexiunea SSH între red și green va fi realizată.

Pentru a șterge o regulă puteți folosi opțiunea -D așa cum ați făcut și la exercițiul 4.

Pentru a insera o regulă folosiți opțiunea -I urmată de numele lanțului (INPUT, OUTPUT sau FORWARD), urmată de indexul poziției unde doriți plasată regulă (1, 2, 3, …) și apoi urmată de specificarea regulii.

Rezolvare
root@host:~# iptables -D FORWARD -s red -d green -p tcp --dport ssh -j ACCEPT
root@host:~# iptables -I FORWARD -s red -d green -p tcp --dport ssh -j ACCEPT
 
root@host:~# iptables -L FORWARD -n -v
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     tcp  --  *      *       192.168.1.2          192.168.2.2          tcp dpt:22
    6   360 REJECT     all  --  *      *       192.168.1.2          0.0.0.0/0            reject-with icmp-port-unreachable    
 
root@red:~# ssh -l student green
student@green's password: 
Welcome to Ubuntu 12.04.3 LTS (GNU/Linux 3.2.0-53-generic-pae i686)
 
 * Documentation:  https://help.ubuntu.com/
Last login: Thu Nov 14 14:18:53 2013 from 192.168.1.2
student@green:~$ logout
Connection to green closed.

8. [5p] Ștergere completă de reguli dintr-un lanț

Pe stația host, ștergeți toate regulile din lanțul FORWARD al iptables. Folosiți opțiunea -F a comenzii iptables.

Rezolvare
root@host:~# iptables -F FORWARD

Afișați lista de reguli iptables de pe stația host pentru a vedea că nu mai sunt reguli.

Rezolvare
root@host:~# iptables -L FORWARD -n -v
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

9. [5p] Conectare SSH folosind cheie publică

Dorim să realizăm o sesiune securizată shell la distanță (remote shell).

Sumar exerciții conectare SSH (dați click)

Sumar exerciții conectare SSH (dați click)

Pentru exercițiile de conectare SSH, vom urma pașii:

  1. Conectare folosind SSH cu chei. Totul este configurat și vedem că merge. (exercițiul 9. [5p] Conectare SSH folosind cheie publică)
  2. Copiere cheie pentru conectare SSH. Cheia există și vom face apoi conectare ca mai sus. (exercițiul 11. [5p] Copiere cheie publică la distanță pentru autentificare)
  3. Crearea cheie, copiere și conectare SSH. (exercițiul 12. [10p] Generare cheie publică și autentificare)

Urmăm pașii în acest fel pentru a urmări întâi comenzile de conectare, sintaxa SSH și rolul său și apoi să investigăm cum se întâmplă lucrurile în spate.

În cazul în care veți avea un cont pe un server și veți dori conectare SSH cu chei, veți urma doar pasul 3.

Din contul student de pe stația red conectați-vă la stația host prin SSH prin rularea comenzii

student@red:~$ ssh student@host
[...]
student@host:~$

Observați faptul că v-ați conectat direct, fără parolă, întrucât autentificarea s-a realizat folosind cheie publică. Folosiți combinația de taste Ctrl+d sau comanda exit pentru a închide sesiunea de shell la distanță.

Cheia publică folosită la conectare este disponibilă în fișierul ~/.ssh/id_rsa.pub. Pentru vizualizarea cheii rulați, pe stația red din contul utilizatorului student, comanda

student@red:~$ cat ~/.ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1[...] student@red

Un alt format de comandă SSH de conectare este cel de mai jos. Pe stația red rulați comanda

student@red:~$ ssh -l student host
[...]
student@host:~$

La fel, închideți sesiunea de shell la distanță prin folosirea combinației de taste Ctrl+d.

La distanță, cheia publică este stocată, împreună cu alte chei publice folosite pentru conectare, în fișierul ~/.ssh/authorized_keys. Rulați comanda de mai jos pentru a confirma prezența cheii publice la distanță

student@red:~$ ssh -l student host "cat ~/.ssh/authorized_keys"
ssh-rsa AAAAB3N[...] student@blue
ssh-rsa AAAAB3N[...] student@green
ssh-rsa AAAAB3N[...] student@red
ssh-rsa AAAAB3N[...] student@host

Se observă că există cheia student@red în fișierul de la distanță de pe stația host, deci se poate realiza autentificarea SSH pe bază de chei.

10. [10p] Problemă la conectarea SSH folosind chei

Din contul utilizatorului student de pe stația red conectați-vă la utilizatorul ana de pe stația host prin SSH prin rularea comenzii

student@red:~$ ssh -l ana host
ana@host's password:

Observați că vi se cere parola. Folosiți Ctrl+c pentru a anula promptul de parolă și a reveni la shell-ul inițial.

Afișați fișierul care conține cheia publică stocată local și cel care conține cheia publică stocată la distanță. Folosiți comenzile

student@red:~$ cat ~/.ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc[...] student@red
 
student@red:~$ ssh -l ana host "cat ~/.ssh/authorized_keys"
ana@host's password: 
ssh-rsa AAAAB3NzaC1yc[...] student@red

Pentru a doua comandă introduceți parola student. Observați că cele două fișiere sunt identice. În mod obișnuit conectarea SSH ar trebui să funcționeze pe bază de chei, nu ar trebui să solicite parolă.

O primă metodă de identificare a problemelor de conectare este să rulați comanda de conectare cu opțiune de verbosity:

student@red:~$ ssh -vvv -l ana host
[...]
debug3: remaining preferred: ,password
debug3: authmethod_is_enabled password
debug1: Next authentication method: password
ana@host's password: 

Din păcate mesajele afișate nu oferă informații utile. Folosiți Ctrl+c pentru a anula promptul de parolă și a reveni la shell-ul inițial.

Pentru identificarea problemei vrem să consultăm fișierele jurnal ale serverului de SSH de la distanță. Autentificați ca root pe stația host, folosiți comanda tail pentru a urmări mesajele de jurnalizare. Comanda rulează în continuu și afișează noile mesaje din fișierul primit ca argument pe măsură ce acestea apar:

root@host:~# tail -f /var/log/auth.log 
[...]
Nov 14 16:48:31 host sshd[20898]: Authentication refused: bad ownership or modes for directory /home/ana/.ssh
Nov 14 16:49:09 host sshd[20898]: Connection closed by 192.168.1.2 [preauth]

Pentru a genera din nou mesaje legate de problemă, pe stația red rulați, din nou, comanda de conectare SSH:

ssh -l ana host

Folosiți Ctrl+c pentru a anula promptul de parolă și a reveni la shell-ul inițial.

Urmăriți mesajele de jurnalizare ale serverului. Urmăriți linia care începe cu “Authentication refused:”.

Problema este la directorul .ssh/ din directorul home al utilizatorului ana.

Folosiți comanda

ls -ld <director>

pe un director pentru a afișa permisiunile pe directorul <director>. Permisiunile ar trebui să corespundă cu permisiuni pe directoarele identice deținute de alți utilizatori.

Rezolvare
Mesajul complet este
Authentication refused: bad ownership or modes for directory /home/ana/.ssh

Sunt permisiuni nepotrivite pe directorul /home/ana/.ssh. Investigăm permisiunile:

root@host:~# ls -ld /home/ana/.ssh/
drwxrwxrwx 2 ana ana 4096 Sep 18  2013 /home/ana/.ssh/

Permisiunile sunt prea permisive (drepturi complete). Întrucât directorul /home/ana/.ssh/ conține și fișierul ce reprezintă cheia privată a utilizatorului ana (posibil chiar mai multe fișiere de cheie privată), care trebuie să rămână privat, trebuie permisiuni mai restrictive pe fișier.

Corectați problema indicată de fișierele jurnal.

Rezolvare
Reducem permisiunile pe directorul /home/ana/.ssh/:
root@host:~# chmod 755 /home/ana/.ssh/
root@host:~# ls -ld /home/ana/.ssh/
drwxr-xr-x 2 ana ana 4096 Sep 18  2013 /home/ana/.ssh/

După corectarea problemei, verificați funcționarea conectării SSH folosind chei publice:

student@red:~$ ssh -l ana host
[...]
ana@host:~$ 

Dacă ați realizat configurația corectă atunci comanda de mai sus va conduce la conectarea SSH prin cheie publică, fără a vă fi solicitată parola de conectare pentru utilizatorul ana de pe stația host.

11. [5p] Copiere cheie publică la distanță pentru autentificare

În contul utilizatorului bogdan de pe stația blue (parola este student) este generată o pereche cheie privată / cheie publică, respectiv în fișierele ~/.ssh/id_rsa și ~/.ssh/id_rsa.pub. Dorim să realizăm conectare SSH folosind chei publice în contul utilizatorului student de pe stația host.

Copiați cheia publică la distanță pentru a permite conectarea. Conținutul fișierului aferent cheii publice (~/.ssh/id_rsa.pub din bogdan@blue) trebuie să ajungă în fișierul de la distanță care stochează cheile publice pentru autentificare (~/.ssh/authorized_keys din student@host). Pentru copierea cheii publice, rulați din contul utilizatorului bogdan de pe stația blue comanda

bogdan@blue:~$ ssh-copy-id student@host
student@host's password: 
Now try logging into the machine, with "ssh 'student@host'", and check in:
 
  ~/.ssh/authorized_keys
 
to make sure we haven't added extra keys that you weren't expecting.

Introduceți parola student la promptul afișat.

Verificați funcționarea corectă prin conectarea SSH la distanță:

bogdan@blue:~$ ssh -l student host
[...]
student@host:~$ 

Dacă v-ați conectat fără să vi se ceară parola înseamnă că s-a realizat autentificare prin chei publice și configurația este corectă.

12. [10p] Generare cheie publică și autentificare

În contul utilizatorului corina de pe stația blue generați o pereche cheie publică/cheie privată SSH prin rularea comenzii

corina@blue:~$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/corina/.ssh/id_rsa): 
Created directory '/home/corina/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/corina/.ssh/id_rsa.
Your public key has been saved in /home/corina/.ssh/id_rsa.pub.
[...]

Folosiți ENTER pentru a folosi căile implicite. Nu folosiți passphrase (adică apăsați ENTER când vi se solicită passphrase-ul). Cheile sunt generate respectiv, în fișierele, .ssh/id_rsa (cheia privată) și .ssh/id_rsa.pub (cheia publică).

Realizați operațiile necesare pentru a permite autentificarea pe bază de chei din contul utilizatorului corina de pe stația blue în contul utilizatorului student de pe stația host. După aceea, verificați faptul că autentificarea se face pe baza de chei.

Aceștia sunt pașii pe care îi veți urma pentru a configura conectare SSH pe bază de chei:

  1. generare pereche de chei SSH (folosind comanda ssh-keygen)
  2. copiere cheie publică în contul de la distanță (folosind comanda ssh-copy-id)
  3. conectare la distanță (folosind comanda ssh)
Rezolvare
corina@blue:~$ ssh-copy-id student@host
student@host's password: 
Now try logging into the machine, with "ssh 'student@host'", and check in:
 
  ~/.ssh/authorized_keys
 
to make sure we haven't added extra keys that you weren't expecting.
 
corina@blue:~$ ssh -l student host
[...]
student@host:~$

13. [5p] Copiere fișiere cu diverse protocoale: durată și consum de resurse

Ne propunem să măsurăm timpul de copiere și consumul de resurse pentru un transfer realizat între două stații folosind, pe rând, transfer direct, FTP și SSH. În directorul home al utilizatorului student de pe stația green există un fișier file-100M.dat. Vom transfera acest fișier în directorul home al utilizatorului student de pe stația host. Vom folosi transfer direct, transfer FTP și transfer SSH. Pentru fiecare caz, stația host va rula server-ul, iar stația green clientul.

Dați copy-paste la comenzile de mai jos ca să vă asigurați că le scrieți corect. Pentru paste folosiți, în terminal, combinația de taste Shift+Insert.

Transfer direct

Pentru transfer direct vom porni un server simplu TCP pe stația host și un client pe stația green; vom folosi utilitarul netcat, prescurtat și nc. Rulați pe stația host, în contul utilizatorului student, comanda

student@host:~$ nc -l 12345 > file-100M-nc.dat

Comanda deschide un server TCP care ascultă conexiuni pe portul 12345. Comanda rămâne activă în așteptarea unei conexiuni de la un client.

De pe stația green, din contul utilizatorului student, transferați fișierul și măsurați timpul de transfer și consumul de resurse prin rularea comenzii1)

student@green:~$ /usr/bin/time -v cat file-100M.dat | nc host 12345

Comanda de mai sus trimite un fișier comenzii nc, iar comanda nc are rolul unui client TCP care se conectează la stația host pe portul 12345.

Transfer FTP

Pentru transfer FTP, serverul de FTP este deja pornit pe stația host. De pe stația green, din contul utilizatorului student, transferați fișierul și măsurați timpul de transfer și consumul de resurse prin rularea comenzii

student@green:~$ /usr/bin/time -v curl -T file-100M.dat -u student:student ftp://host/file-100M-ftp.dat

Transfer SSH

Pentru transfer SSH, serverul de SSH este deja pornit și configurat pe stația host. De pe stația green, în contul utilizatorului student, transferați fișierul și măsurați timpul de transfer și consumul de resurse prin rularea comenzii

student@green:~$ /usr/bin/time -v scp file-100M.dat student@host:file-100M-scp.dat

Urmăriți timpii de rulare și consumul de memorie și de procesor pentru cele trei cazuri de mai sus. Observați valorile ridicate pentru SSH pentru timpul utilizator (User time) și procentul de procesor (Percent of CPU). Acesta valori ridicate se datorează componentei de criptare a SSH: această componentă asigură securizarea datelor cu un cost de reducere de performanță.

14. [5p] Download și upload folosind ''scp''

Upload-ul și download-ul prin intermediul protocolului SSH folosesc comanda scp. Vom folosi două fișiere:

  • fișierul host-file-10M.dat din directorul home al utilizatorului student de pe stația host;
  • fișierul blue-file-10M.dat din directorul home al utilizatorului corina de pe stația blue.

Autentificați-vă la cele două conturi (student@host și corina@blue) și observați prezența celor două fișiere:

corina@blue:~$ ls
blue-file-10M.dat  solution
 
student@host:~$ ls
assignment         file-100M-nc.dat   host-file-10M.dat
file-100M-ftp.dat  file-100M-scp.dat

Din contul corina de pe stația blue, descărcați fișierul host-file-10M.dat din directorul home al utilizatorului student de pe stația host folosind comanda

scp student@host:host-file-10M.dat .

Fișierul a fost copiat în directorul curent (argumentul destinație este . - punct, dot), adică directorul home al utilizatorului corina de pe blue. Listați conținutul directorului curent pentru a verifica prezența fișierului descărcat:

corina@blue:~$ ls
blue-file-10M.dat  host-file-10M.dat  solution

Din contul corina de pe stația blue, uploadați fișierul blue-file-10M.dat în directorul home al utilizatorului student de pe stația host folosind comanda

scp blue-file-10M.dat student@host:

Fișierul a fost copiat în directorul home al utilizatorului student de pe host. Listați conținutul directorului de la distanță pentru a verifica prezența fișierului încărcat:

corina@blue:~$ ssh student@host ls
assignment
blue-file-10M.dat
file-100M-ftp.dat
file-100M-nc.dat
file-100M-scp.dat
host-file-10M.dat

15. [10p] Download și upload de director folosind ''scp''

Indicație: Pentru download-ul și upload-ul unui director folosiți opțiunea -r a comenzii scp.

Vom folosi două directoare:

  • directorul assignment/ din directorul home al utilizatorului student de pe stația host;
  • directorul solution/ din directorul home al utilizatorului corina de pe stația blue.

Din contul corina de pe stația blue, descărcați directorul assignment/ din directorul home al utilizatorului student de pe stația host.

Rezolvare
corina@blue:~$ scp -r student@host:assignment .
quadratic.txt                                 100%   17     0.0KB/s   00:00    
cubic.txt                                     100%   24     0.0KB/s   00:00    
linear.txt                                    100%    8     0.0KB/s   00:00    
 
corina@blue:~$ ls
assignment  blue-file-10M.dat  host-file-10M.dat  solution

Din contul corina de pe stația blue, uploadați directorul solution/ în directorul home al utilizatorului student de pe stația host.

Rezolvare
corina@blue:~$ scp -r solution student@host:       
quadratic.txt                                 100%   15     0.0KB/s   00:00    
cubic.txt                                     100%   23     0.0KB/s   00:00    
linear.txt                                    100%    6     0.0KB/s   00:00    
 
corina@blue:~$ ssh student@host ls
assignment
blue-file-10M.dat
file-100M-ftp.dat
file-100M-nc.dat
file-100M-scp.dat
host-file-10M.dat
solution

16. [5p] Alias-uri de conectare SSH

În contul utilizatorului student de pe stația host, rulați comanda

student@host:~$ ssh r
[...]
student@red:~$ 

În urma rulării comenzii vă veți conecta prin SSH în contul utilizatorului student de pe stația red. Deconectați-vă folosind combinația de taste Ctrl+d.

Comanda de mai sus a însemnat conectarea peste SSH datorită configurației de alias-uri SSH din fișierul ~/.ssh/config. Urmăriți conținutul acestui fișier din contul utilizatorului student de pe stația host:

student@host:~$ cat ~/.ssh/config 
Host r
	User student
	HostName red

În cadrul fișierului, șirul r din cadrul liniei Host r înseamnă un alias. Folosirea comenzii ssh r va conduce la conectarea prin SSH la utilizatorul aflat după șirul User către stația aflată după șirul HostName.

Actualizați fișierul ~/.ssh/config astfel încât rularea comenzilor, respectiv,

ssh g
ssh b

să conducă la conectarea SSH în contul utilizatorului student de pe stația green, respectiv stația blue.

Rezolvare
student@host:~$ cat .ssh/config
Host r
	User student
	HostName red
 
Host g
	User student
	HostName green
 
Host b
	User student
	HostName blue
 
student@host:~$ ssh r
[...]
student@red:~$

student@host:~$ ssh g
[...]
student@green:~$

student@host:~$ ssh b
[...]
student@blue:~$

17. [BONUS - 10p] Blocare acces din Internet la rețeaua locală

Pentru simularea unei situații reale, vom considera stația red ca fiind o stație din rețeaua locală (LAN), iar stația green o stație din Internet, conectate între ele prin stația host, pe post de gateway.

Dorim să blocăm traficul TCP inițiat din Internet către rețeaua locală, adică traficul TCP inițiat de la stația green către stația red. Traficul inițiat de stația red către stația green precum și traficul de răspuns de la stația green către stația red va fi permis.

Ca exemplu practic, de pe stația red vor putea fi inițiate conexiuni SSH către stația green folosind comanda

ssh green

, dar de pe stația green nu vor putea fi inițiate conexiuni SSH către stația red folosind comanda

ssh red

Configurați iptables pe stația host pentru a realiza acest lucru.

Folosiți modulul state al iptables. Accesați pagina de manual iptables și căutați după --state. Pe distribuțiile mai noi accesați pagina de manual iptables-extensions. Pagina de manual este instalată și accesibilă pe stația host, nu pe stațiile red, green sau blue.

Afișează rezolvarea
Ascunde rezolvarea
Afișează rezolvarea
Adăugăm regula care blochează traficul TCP inițiat de la stația green către stația red:
root@host:~# iptables -A FORWARD -s green -d red -p tcp -m state --state NEW -j DROP
 
root@host:~# iptables -L -n -v
root@host:~# iptables -L FORWARD -n -v
Chain FORWARD (policy ACCEPT 65 packets, 11592 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    2   120 DROP       tcp  --  *      *       192.168.2.2          192.168.1.2          tcpflags: 0x17/0x02

Încercăm realizarea de conexiuni SSH de la stația green la stația red (nu va funcționa) și de la stația red la stația green (va funcționa):

root@green:~# ssh red
^C
root@green:~#

root@red:~# ssh green
[...]
root@green:~#

Traficul inițiat de la stația green către stația red este “capturat” de regula iptables de pe lanțul FORWARD:

root@host:~# iptables -L FORWARD -n -v
Chain FORWARD (policy ACCEPT 65 packets, 11592 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    2   120 DROP       tcp  --  *      *       192.168.2.2          192.168.1.2          tcpflags: 0x17/0x02

18. [BONUS - 10p] Transfer sincronizat de fișiere folosind ''rsync'' peste SSH

rsync este un utilitar și protocol care permite transfer incremental. Este foarte potrivit pentru situații de backup, când se transferă doar actualizările sau pentru mentenanța unui mirror, la fel transferându-se de la serverul central doar noile date. Altfel de operații poartă numele de “sincronizare” (syncing).

Dorim să facem backup prin rsync al directorului proiecte/ din directorul home al utilizatorului ana de pe stația host în contul bogdan de pe stația blue. Atunci când vom actualiza conținutul directorului proiecte/, procesul de backup va transfera doar modificările.

Folosiți rsync și protocolul SSH pentru a realiza acest lucru. Se dorește ca autentificarea să se realizeze pe bază de chei, fără parolă.

Afișează rezolvarea
Ascunde rezolvarea
Afișează rezolvarea
ana@host:~$ ssh-keygen
[...]
ana@host:~$ ssh-copy-id bogdan@blue
bogdan@blue's password:
[...]
ana@host:~$ rsync -avz -e ssh proiecte/ bogdan@blue:
sending incremental file list
./
ana.txt
are.txt
mere.txt
 
sent 214 bytes  received 72 bytes  572.00 bytes/sec
total size is 13  speedup is 0.05
 
ana@host:~$ rsync -avz -e ssh proiecte/ bogdan@blue:
sending incremental file list
 
sent 78 bytes  received 12 bytes  180.00 bytes/sec
total size is 13  speedup is 0.14
 
ana@host:~$ echo "Lok'tar ogar" > proiecte/orc.txt
ana@host:~$ ls proiecte/
ana.txt  are.txt  mere.txt  orc.txt
 
ana@host:~$ rsync -avz -e ssh proiecte/ bogdan@blue:
sending incremental file list
./
orc.txt
 
sent 166 bytes  received 34 bytes  400.00 bytes/sec
total size is 26  speedup is 0.13
 
ana@host:~$ rsync -avz -e ssh proiecte/ bogdan@blue:
sending incremental file list
 
sent 110 bytes  received 12 bytes  244.00 bytes/sec
total size is 26  speedup is 0.21
1) În cazul unui transfer prin rețea folosind netcat nu se face verificare de integritate (integrity check). Există riscul (mic, dar există) ca fișierul să nu fie transferat corespunzător. De aceea e bine să verificați integritatea acestuia prin calcularea sumei de control (checksum) folosind, de exemplu, utilitarul sha512sum.
rl/labs/08.txt · Last modified: 2020/01/09 17:17 by octavian.grigorescu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0