student@uso:~$ cd /home/student student@uso:~$ rm -rf uso-lab.git student@uso:~$ git clone https://github.com/systems-cs-pub-ro/uso-lab.git Cloning into 'uso-lab'... remote: Enumerating objects: 996, done. remote: Counting objects: 100% (290/290), done. remote: Compressing objects: 100% (206/206), done. remote: Total 996 (delta 88), reused 246 (delta 52), pack-reused 706 Receiving objects: 100% (996/996), 82.24 MiB | 8.99 MiB/s, done. Resolving deltas: 100% (319/319), done.
git pull
în directorul ~/uso-lab/labs/03-user/lab-container/
.
Infrastructura laboratorului este bazată pe containere docker ale căror imagini vor fi generate pe propriul calculator. Dacă nu aveți deja instalat Docker Engine pe sistem, scriptul ~/uso-lab/labs/03-user/lab-container/lab_prepare.sh install fizic
vă va instala aplicația.
După ce ați terminat de lucrat vă recomandăm să opriți containerele rulând comanda ./lab_prepare.sh delete
în directorul ~/uso-lab/labs/03-user/lab-container/
.
În cadrul acestei secțiuni vom învăța cum să reparăm problemele de conectivitate la rețea sau în alte cuvinte, problema “nu-mi merge Internetul”. Pentru a face asta este necesar să parcurgem toate nivelurile de rețea prin care trec datele pentru a fi trimise în Internet.
In continuare vom prezenta pașii pe care îi urmăm ca să verificăm funcționalitatea conexiunii la Internet și cum putem să facem niște configurații sumare.
Primul nivel cu care interacționăm este nivelul fizic, care are rolul de a trimite date sub formă de semnale prin mediul de transmisie. De exemplu, semnalele electrice sunt transmise prin fir de cupru, pulsurile luminoase prin fibră optică și undele radio prin wireless.
Așa arată un cablu de cupru de tip UTP (Unshielded Twisted Pair):
O altă componentă a nivelului fizic este placa de rețea a sistemului (in engleză, NIC - Network Interface Card), care va trimite datele prin mediul de transmisie.
Majoritatea timpului problemele de conexiune la Internet vin de la faptul că nu este conectat cablul de Internet la placa de rețea sau de la faptul că avem conexiune slabă la rețeaua wireless.
La nivel fizic, putem verifica conexiunea și funcționalitatea unei plăci de rețea uitându-ne la ledurile care reprezintă conexiunea la mediul fizic. Observăm în GIF-ul de mai jos cum arată ledurile unei plăci de rețea funcționale. Dacă acestea nu sunt aprinse, atunci nu vom avea conectivitate la rețea.
~/uso-lab/labs/03-user/lab-container/
comanda ./lab_prepare.sh install fizic
. Pentru a ne conecta la infrastructura pentru această secțiune vom folosi comanda ./lab_prepare.sh connect fizic
O interfață de rețea este un mijloc de realizare a configurărilor de rețea asociată de obicei unei plăci de rețea și identificată printr-un nume.
loopback
este o interfață virtuală, de auto-adresare, care se adresează sistemului însuși. Este numită lo
in Linux.
La nivelul sistemului de operare putem verifica dacă o placă de rețea este activă folosind comanda următoare:
root@fizic:~# ip link show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 99: eth0@if100: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default link/ether 02:42:0a:0a:0a:01 brd ff:ff:ff:ff:ff:ff link-netnsid 0 113: eth1@if114: <BROADCAST,MULTICAST> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default link/ether 02:42:0b:0b:0b:01 brd ff:ff:ff:ff:ff:ff link-netnsid 0 115: eth2@if116: <BROADCAST,MULTICAST> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default link/ether 02:42:0c:0c:0c:01 brd ff:ff:ff:ff:ff:ff link-netnsid 0
Starea fiecărei interfețe de rețea este reprezentată de numărul interfeței și numele ei, împreună cu parametrii săi de rulare. Majoritatea informațiilor afișate de comanda de mai sus nu sunt relevante pentru noi. O opțiune relevantă este valoarea state
, urmată de starea interfeței de rețea, care poate să fie UP
, DOWN
sau UNKNOWN
.
Formatul pentru numele interfețelor diferă de la o distribuție la alta. În cadrul infrastructurii de laborator folosim containere de tip Docker în cadrul cărora numele interfețelor este de forma ethX
, unde X este un număr. În funcție de distribuția pe care rulăm numele interfețelor poate să se fie într-un format diferit.
Observăm că interfața de rețea cu numele eth0
este pornită, deoarece linia asociată interfeței conține șirul de caractere state UP
. În același timp observăm că interfața de rețea eth1
nu este activă deoarece pe linia sa observăm șirul de caractere state DOWN
.
Pentru a porni interfața eth1
vom folosi următoarea comandă:
root@uso:~# ip link set dev eth1 up
Mereu, după ce rulăm o comandă, trebuie să verificăm dacă s-a efectuat cu succes, folosind o metodă de verificare. În cazul de față vom folosi tot comanda ip link show
:
root@fizic:~# ip link show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 99: eth0@if100: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default link/ether 02:42:0a:0a:0a:01 brd ff:ff:ff:ff:ff:ff link-netnsid 0 113: eth1@if114: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default link/ether 02:42:0b:0b:0b:01 brd ff:ff:ff:ff:ff:ff link-netnsid 0 115: eth2@if116: <BROADCAST,MULTICAST> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default link/ether 02:42:0c:0c:0c:01 brd ff:ff:ff:ff:ff:ff link-netnsid 0
Porniți interfața de rețea eth2
.
Pentru a ne deconecta de la infrastructura anterioara folosim comanda exit
.
~/uso-lab/labs/03-user/lab-container/
comanda ./lab_prepare.sh install internet
. Pentru a ne conecta la infrastructura pentru această secțiune vom folosi comanda ./lab_prepare.sh connect internet
Internetul este o interconectare de dispozitive, numite stații și organizate în rețele, care se extinde pe toată Planeta. Datele trimise în Internet trebuie redirecționate de la un nod la altul, așa incât să ajungă rapid de la o stație la altă stație.
Deci, pentru ca o stație să comunice cu o altă stație din Internet, trebuie ca cele doua stații să fie conectate la Internet.
Mai apoi, cele două stații trebuie să se poată adresa una alteia. Adică fiecare stație are nevoie de un identificator, o adresă. Cum fiecare casă din lume are o adresă cu care poate fi identificată unic, așa și fiecare stație are o adresă unică in Internet numită adresa IP (Internet Protocol).
Fiecare interfață de rețea este o cale diferită către Internet, deci fiecare are nevoie de a avea configurată câte o adresă IP.
Pentru a vedea adresele IP configurate pe interfețele de rețea folosim următoarea comandă:
root@internet:~# ip address show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 195: eth0@if196: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:0a:0a:0a:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 10.10.10.2/24 brd 10.10.10.255 scope global eth0 valid_lft forever preferred_lft forever 199: eth1@if200: <BROADCAST,MULTICAST> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:0b:0b:0b:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 203: eth2@if204: <BROADCAST,MULTICAST> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:0c:0c:0c:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
Există două tipuri de adrese IP (IPv4 și IPv6), dar în cadrul acestui laborator vom lucra numai cu adrese de tip IPv4. Adresele IP ale interfețelor sunt scrise pe liniile care conțin inet
. Adresele IPv4 sunt de forma A.B.C.D
, unde A, B, C și D sunt numere cu valori între 1 si 255.
Pentru detalii despre adresele de tip IPv6 folosiți urmăriți această1) explicație.
Există două metode pentru configurarea unei adrese IP pe o interfață:
Vom insista pe configurarea dinamică, deoarece este mai simplă. În plus, nu avem cum să aflăm informațiile despre rețea înainte de a configura interfața de rețea.
Faceți modificările necesare astfel încât interfața eth1
să fie în starea UP
.
Pentru a obține o adresă IP în mod dinamic pe o interfață folosim comanda dhclient
:
root@internet:~# dhclient eth1 mv: cannot move '/etc/resolv.conf.dhclient-new.35' to '/etc/resolv.conf': Device or resource busy
Linia mv: cannot move '/etc/resolv.conf.dhclient-new.35' to '/etc/resolv.conf': Device or resource busy
apare mereu în containerele docker atunci când încercăm să obținem o adresă IP folosind comanda dhclient
. Nu este o problemă dacă aceasta apare.
Mai sus am rulat comanda pentru a obține o adresă IP pentru interfața eth1
.
dhclient
este bazată pe protocolul DHCP (Dynamic Host Configuration Protocol). Acesta presupune că există un server pe rețea care cunoaște ce IP-uri sunt folosite pe rețea și care poate să ofere adrese IP calculatoarelor care fac cereri pe rețea. dhclient
face o cerere de rezervare a unei adrese IP către serverul DHCP de pe rețea.
Afișați adresele IP de pe toate interfețele.
Observați că am obținut o adresă IP pe interfața eth1
.
Configurați adresa IP pe interfața eth2
.
Pentru șterge o adresă IP de pe o interfața folosim comanda ip address flush
în felul următor:
root@internet:~# ip address flush eth1 root@internet:~# ip address show eth1 199: eth1@if200: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:0b:0b:0b:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
Putem să afișăm configurația unei singure interfețe de rețea folosind numele interfeței ca parametru pentru comanda ip address show
.
Ștergeți configurația de rețea de pe interfețele eth1
și eth2
.
ping
. Această comandă trimite mesaje către o stație și așteaptă un răspuns de la ea.
De exemplu, dacă vrem să verificăm conectivitatea la serverul 8.8.8.8
(un server public din Internet), folosim comanda:
student@uso:~$ ping -c 4 8.8.8.8 PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data. 64 bytes from 8.8.8.8: icmp_seq=1 ttl=61 time=23.0 ms 64 bytes from 8.8.8.8: icmp_seq=2 ttl=61 time=25.7 ms 64 bytes from 8.8.8.8: icmp_seq=3 ttl=61 time=24.8 ms 64 bytes from 8.8.8.8: icmp_seq=4 ttl=61 time=25.2 ms --- 8.8.8.8 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3092ms rtt min/avg/max/mdev = 23.051/24.731/25.707/1.020 ms
Comportamentul implicit al comenzii ping
este să trimită pachete la infinit. Am folosit opțiunea -c 4
în exemplul de mai sus pentru a reduce numărul de pachete trimise la 4.
Atunci când nu pot fi trimise mesaje către stația identificată prin adresa IP, mesajul de eroare va arăta în felul următor:
student@uso:~$ ping 10.10.10.10 PING 10.10.10.10 (10.10.10.10) 56(84) bytes of data. From 10.10.10.3 icmp_seq=1 Destination Host Unreachable From 10.10.10.3 icmp_seq=2 Destination Host Unreachable From 10.10.10.3 icmp_seq=3 Destination Host Unreachable From 10.10.10.3 icmp_seq=4 Destination Host Unreachable ^C --- 10.10.10.10 ping statistics --- 4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 3074ms
Pentru verificarea conectivității în interiorul rețelei trebuie să verificăm că putem să trimitem mesaje folosind utilitarul ping
unui calculator din rețea.
În mod implicit comanda ping
trimite mesaje de verificare a conexiunii la infinit. De data aceasta, în loc să rulăm comanda ping
folosind opțiunea -c 4
, am oprit rularea comenzii folosind combinația de taste Ctrl+c
.
O țintă bună de testare pentru trimiterea mesajelor în rețea este (default) gateway-ul. Un gateway este un dispozitiv de rețea care se ocupă de interconectarea rețelelor și care primește mesaje de la toate stațiile din rețea pentru a le trimite în Internet.
Gateway-ul este configurat static sau dinamic, cum este configurată și adresa IP a unei interfețe.
Pentru a identifica gateway-ul, folosim comanda ip route show
în felul următor:
student@uso:~$ ip route show default via 192.168.40.2 dev eth0 proto dhcp src 192.168.40.128 metric 100 10.10.10.0/24 dev br1 proto kernel scope link src 10.10.10.253 11.11.11.0/24 dev br2 proto kernel scope link src 11.11.11.253 12.12.12.0/24 dev br3 proto kernel scope link src 12.12.12.253 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown 192.168.40.0/24 dev eth0 proto kernel scope link src 192.168.40.128 metric 100 192.168.40.2 dev eth0 proto dhcp scope link src 192.168.40.128 metric 100 192.168.202.0/24 dev eth1 proto kernel scope link src 192.168.202.128 metric 100 192.168.202.1 dev eth1 proto dhcp scope link src 192.168.202.128 metric 100
Observăm că adresa IP a default gateway-ului este 192.168.40.2
, deoarece acesta se află pe linia care conține șirul de caractere default
.
Aflați adresa de rețea de pe interfața eth1
.
Verificați conexiunea cu gateway-ul folosind comanda ping
.
1.1.1.1
.
Verificați conexiunea la serverul 8.8.8.8
oferit de Google folosind comanda ping
.
După cum ați observat, până acum am lucrat numai cu adrese IP, dar noi lucrăm în viața de zi cu zi cu numele site-urilor, deoarece ne este mai ușor să reținem nume decât adrese IP.
Pentru a rezolva această necesitate folosim serviciul DNS (Domain Name Server). Acesta este oferit de un server către care noi trimitem cereri de lookup pentru o adresa hostname cum ar fi www.google.com
. Serverul DNS va răspunde cu adresa IP asociată cu adresa cerută.
Ne dorim să avem un serviciu DNS funcțional în permanență pe sistemul pe care lucrăm.
În mod implicit serviciul DNS este configurat prin DHCP.
Serviciul DNS poate fi configurat în multe moduri care depind de platforma pe care o folosim. Pentru mașina virtuala folosită de noi ne putem folosi de utilitarul nmcli
pentru a identifica serverul DNS folosit. Comanda grep
identifică din rezultatul unei comenzi doar linia care conține șirul de caractere DNS
.
student@uso:~$ nmcli dev show | grep DNS IP4.DNS[1]: 10.0.2.3
Exista o posibilitate ca pe noua masina virtuala de laborator sa se gaseasca serverul DNS curent cu comanda:
student@uso:~$ resolvectl status | grep 'Current DNS' Current DNS Server: 1.1.1.1
Conform cu outputul comenzii, serverul DNS către care sunt trimise comenzi este 1.1.1.1
.
Pentru a verifica funcționalitatea serviciului DNS, putem să facem o cerere DNS folosind comanda host
în felul următor:
student@uso:~$ host elf.cs.pub.ro elf.cs.pub.ro has address 141.85.227.116 elf.cs.pub.ro mail is handled by 10 elf.cs.pub.ro.
Rezultatul rulării comenzii host
este o lista cu servicii și adrese care pot fi identificate prin numele elf.cs.pub.ro
. Pe linia care conține șirul de caractere address
se află adresa IPv4 asociată numelui. Observăm că serverul elf.cs.pub.ro
găzduiește și un server de mail. Acest lucru este evidențiat de linia care conține parametrul mail
.
Cererile DNS nu trebuie să fie făcute direct de noi atunci când încercăm să accesăm o resursă din Internet folosind un nume, deoarece aplicațiile fac cereri în mod implicit.
student@uso:~$ ping google.com PING google.com (216.58.214.238) 56(84) bytes of data. 64 bytes from bud02s24-in-f14.1e100.net (216.58.214.238): icmp_seq=1 ttl=63 time=19.5 ms 64 bytes from bud02s24-in-f14.1e100.net (216.58.214.238): icmp_seq=2 ttl=63 time=21.6 ms 64 bytes from bud02s24-in-f14.1e100.net (216.58.214.238): icmp_seq=3 ttl=63 time=21.3 ms 64 bytes from bud02s24-in-f14.1e100.net (216.58.214.238): icmp_seq=4 ttl=63 time=19.4 ms ^C --- google.com ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3006ms rtt min/avg/max/mdev = 19.377/20.426/21.588/1.009 ms
Observați că utilitarul ping
a aflat de unul singur care este adresa IP asociată numelui google.com
și a făcut cererea în fundal și a verificat conexiunea cu serverul de la adresa IP 216.58.214.238
.
În caz că vrem să schimbăm temporar serverul DNS pe care îl folosim trebuie să modificăm fișierul /etc/resolv.conf
. Acest fișier specifică DNS-ul care va fi folosit pentru cereri pe linia care conține cuvântul nameserver, după cum puteți vedea mai jos.
student@uso:~$ cat /etc/resolv.conf student@uso:~$ cat /etc/resolv.conf <...> nameserver 127.0.0.53 options edns0
Dacă schimbăm adresa serverului DNS cu altă adresă, cum ar fi cea a serverului DNS oferit de Google, putem să vedem o schimbare în răspunsurile de la serverul DNS pentru unele site-uri.
student@uso:~$ host google.com google.com has address 172.217.20.14 google.com has IPv6 address 2a00:1450:400d:803::200e <...> student@uso:~$ echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf student@uso:~$ cat /etc/resolv.conf nameserver 8.8.8.8 student@uso:~$ host google.com google.com has address 172.217.18.78 google.com has IPv6 address 2a00:1450:400d:809::200e <...>
Acestea sunt modificări temporare folosite pentru depanarea problemelor cu serviciul DNS.
1.1.1.1
;google.com
.Atunci când folosim Internetul, ce facem de fapt este că ne conectăm la aplicații care rulează pe servere în Internet și noi pornim la rândul nostru aplicații pe calculatorul nostru care așteaptă conexiuni din Internet.
Pentru a distinge aplicațiile și destinația mesajelor, folosim conceptul de porturi. Astfel, fiecare aplicație deschide un port pentru a comunica cu exteriorul.
Portul este o adresă locală unei stații. Dacă adresa IP identifică stația, portul identifică aplicația de rețea de pe stație. Astfel putem avea mai multe aplicații rețea pe o stație.
Există două tipuri de porturi care pot fi deschise, în funcție de protocolul folosit:
Pentru afișarea porturilor deschise, pe care comunică o aplicație, folosim comanda netstat
:
student@uso:~$ sudo netstat -tlpn Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:5939 0.0.0.0:* LISTEN 794/teamviewerd tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 530/systemd-resolve tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 693/sshd: /usr/sbin tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 572/cupsd tcp 0 0 127.0.0.1:6010 0.0.0.0:* LISTEN 2630/sshd: student@ tcp6 0 0 :::22 :::* LISTEN 693/sshd: /usr/sbin tcp6 0 0 ::1:631 :::* LISTEN 572/cupsd tcp6 0 0 ::1:6010 :::* LISTEN 2630/sshd: student@
Pentru comanda de mai sus folosim următoarele opțiuni pentru filtrarea afișării:
-t
afișează doar porturile TCP deschise-l
afișează doar porturile deschise care ascultă mesaje, nu și cele deschide pentru trimiterea mesajelor-p
afișează programul care a deschis portul2)-n
afișează IP-ul pe care se ascultă după conexiuniAfișați porturile UDP deschise pe stația pe care lucrați.
Hint
Având în vedere că opțiunea -t
se referă la porturile TCP, care credeți ca va fi opțiunea necesară pentru identificarea porturilor UDP?
Vrem să observăm cum răspunde serverul HTTP la mesaje. De regulă un server HTTP răspunde printr-un mesaj în format HTML.
Pentru a trimite mesaje, indiferent de tipul aplicației care primește mesajul folosim comanda nc
în felul următor
student@uso:~$ nc google.com 80 test HTTP/1.0 400 Bad Request Content-Type: text/html; charset=UTF-8 Referrer-Policy: no-referrer Content-Length: 1555 Date: Tue, 20 Oct 2020 19:48:04 GMT <!DOCTYPE html> <html lang=en> <meta charset=utf-8> <meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width"> <title>Error 400 (Bad Request)!!1</title> <style> *{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px} </style> <a href=//www.google.com/><span id=logo aria-label=Google></span></a> <p><b>400.</b> <ins>That’s an error.</ins> <p>Your client has issued a malformed or illegal request. <ins>That’s all we know.</ins>
Am rulat comanda nc
iar apoi am scris mesajul test
și am apăsat tasta Enter
. Mesajul primit este un răspuns de tipul Bad Request
, deoarece am trimis un mesaj care nu este în formatul așteptat de serverul HTTP.
127.0.0.1
).elf.cs.pub.ro
.Dispozitivele pe care le folosim noi devin din ce în ce mai mici, mai eficiente și ieftine. Asta se întâmplă deoarece multe dintre aplicațiile care până nu de curând rulau pe calculatorul propriu s-au mutat în spațiu online. De exemplu, în loc să descărcăm filme și să le urmărim de pe calculator, folosim o aplicație cum ar fi Netflix pentru a ne transmite prin Internet filmul pe care vrem să îl urmărim. Un alt exemplu relevant este Google Drive, care ne permite să stocăm, să replicăm și să edităm documente într-o interfață web, în loc să le păstrăm local pe calculatorul pe care îl folosim. Toată puterea de procesare și tot spațiul de stocare s-a mutat de pe calculatorul propriu pe servere aflate în Internet.
Vom numi aceste aplicații care rulează în Internet servicii.
Un serviciu este o aplicație care oferă o funcționalitate utilizatorilor care apelează la ele. Serviciile în domeniul calculatoarelor lucrează folosind paradigma server-client. Un avantaj major al acestei abordări este că reduce puterea de calcul necesară pentru rularea aplicațiilor de către utilizatori. Aceștia au nevoie doar de o aplicație client care știe să comunice cu serverul. Astfel, aplicația client trimite o cerere către aplicația server, serverul primește cererea, procesează cererea și servește răspunsul aplicației client care a făcut cererea.
Această paradigmă poate fi observată în schema următoare:
Atunci când noi vrem să urmărim un film pe Netflix aplicația client Netflix de pe calculator sau smart TV va trimite o cerere de descărcare a filmului de pe serverul Netflix aflat la distanță.
În viață de zi cu zi aplicația pe care o folosim cel mai mult este browserul web, deoarece majoritatea aplicațiilor pe care le folosim au fost transformate în pagini web cu care noi interacționăm. Browserul web este o aplicație care execută o cerere HTTP către un server web, identificat printr-o adresă, un link, prin care face o acțiune și primește un răspuns. De exemplu, când accesăm pagina www.facebook.com
se trimite o cerere către serverul HTTP, iar acesta trimite un răspuns către browser sub forma unei pagini web, în formatul HTML, pe care browserul o afișează.
Pentru interacțiunea cu serverele web putem folosi și clienți web în linie de comandă. Clienții web folosiți în linie de comandă sunt folositori atunci când nu avem acces la o interfață GUI, sau când încercăm să automatizăm un proces. De exemplu, pentru a verifica automat starea unui site avem nevoie să descărcăm pagina site-ului.
Există mai multe implementări de clienți web în linie de comandă. Vom folosi comanda wget
pentru descărcarea unei pagini web.
student@uso:~$ wget elf.cs.pub.ro --2020-10-20 23:01:02-- http://elf.cs.pub.ro/ Resolving elf.cs.pub.ro (elf.cs.pub.ro)... 141.85.227.116 Connecting to elf.cs.pub.ro (elf.cs.pub.ro)|141.85.227.116|:80... connected. HTTP request sent, awaiting response... 200 OK Length: 168 [text/html] Saving to: ‘index.html’ index.html 100%[===========================================================>] 168 --.-KB/s in 0s 2020-10-20 23:01:02 (7,61 MB/s) - ‘index.html’ saved [168/168] student@uso:~$ cat index.html <html> <head> <meta name="google-site-verification" content="gTsIxyV43HSJraRPl6X1A5jzGFgQ3N__hKAcuL2QsO8" /> </head> <body> <h1>It works!</h1> </body> </html>
Comanda wget
primește ca parametru link-ul către pagina pe care vrem să o descărcăm.
Am folosit comanda cat
pentru afișarea conținutului fișierului index.html
. Fișierul index.html
este fișierul descărcat în mod implicit, dacă nu descărcăm o pagină specifică.
www.facebook.com
. Afișați conținutul fișierului descărcat.
http://wttr.in/
. Afișați conținutul fișierului descărcat.http://elf.cs.pub.ro/uso/res/final/141/ex5.csv
. Ce tip de fișier este acesta?
~/uso-lab/labs/03-user/lab-container/
comanda ./lab_prepare.sh install ssh
. Pentru a ne conecta la infrastructura pentru această secțiune vom folosi comanda ./lab_prepare.sh connect ssh
În multe situații atunci când lucrăm cu sisteme, este necesar să rulăm aplicații pe alte stații în afara calculatorului nostru fără să avem acces fizic la stații.
Protocolul cel mai folosit pentru accesul la stații la distanță este protocolul SSH. SSH permite autentificarea la o stație pe care rulează un server SSH. Când ne conecta la o stație, trebuie să precizăm utilizatorul cu care vrem să ne logăm. Pentru autentificare introducem parola utilizatorului, sau folosim o cheie de acces la stație.
Pentru a rula comenzi pe o altă stație putem folosi programul SSH (Secure Shell) pentru a ne conecta la acesta în felul următor:
student@uso:~$ hostname uso.local student@uso:~$ ssh root@10.10.10.3 The authenticity of host '10.10.10.3 (10.10.10.3)' can't be established. ECDSA key fingerprint is SHA256:I3Ybkkk7nF2FjwVHMzjkyujDnhlRlnSwPRVwUKm6OCM. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '10.10.10.3' (ECDSA) to the list of known hosts. root@10.10.10.3's password: Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 5.4.0-51-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage This system has been minimized by removing packages and content that are not required on a system that users do not log into. To restore this content, you can run the 'unminimize' command. The programs included with the Ubuntu system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/\*/copyright. Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. root@ssh:~# ls / bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var root@ssh:~# hostname ssh
Unde root
este numele utilizatorului și 10.10.10.3
este adresa IP, sau hostname-ul stației la care vrem să ne conectăm.
Atunci când ne conectăm la o stație, clientul SSH va încerca să autentifice stația la care ne-am conectat. Dacă ne conectăm pentru prima oară la un sistem trebuie să spunem clientului că am verificat datele clientului la care ne-am conectat.
În mod implicit protocolul SSH va folosi autentificarea cu parolă. Parola introdusă în exemplul de mai sus este parola root
.
Odată ce ne-am conectat la calculator, avem acces la un shell în care rulăm comenzi ca mai sus. Putem observa că ne-am autentificat pe un calculator diferit deoarece s-a schimbat promptul terminalului de la student@uso:~$
la root@ssh:~#
și s-a afișat un mesaj numit Message of the Day.
În exemplul de mai sus am rulat comanda hostname
care afișează numele stației la care ne-am conectat pentru a ne asigura că ne-am conectat pe un nou calculator. Putem observa numele stației și din prompt.
11.11.11.3
folosind utilizatorul root
și parola root
.12.12.12.3
folosind utilizatorul student
și parola student
.
Atunci când ne conectăm la o stație avem acces la un shell pe care putem să îl folosim, dar dacă nu este necesar putem să rulăm mai multe comenzi, sau vrem să automatizăm rularea comenzilor pe alte stații putem folosi comanda SSH în felul următor:
student@uso:~$ ssh root@10.10.10.3 ip address show root@10.10.10.3's password: 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 544: eth0@if545: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:0a:0a:0a:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 10.10.10.3/24 brd 10.10.10.255 scope global eth0 valid_lft forever preferred_lft forever 546: eth1@if547: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:0b:0b:0b:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 11.11.11.3/24 brd 11.11.11.255 scope global eth1 valid_lft forever preferred_lft forever 550: eth2@if551: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:0c:0c:0c:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 12.12.12.3/24 brd 12.12.12.255 scope global eth2 valid_lft forever preferred_lft forever
Am rulat comanda ip address show
pentru a afișa setările de rețea pe stația de la adresa IP 10.10.10.3
, autentificându-ne ca utilizatorul root
.
Rulați comanda cat /etc/passwd
pe stația de la IP-ul 10.10.10.3
fără să intrați în interfața în linia de comandă de pe stații. Vă veți autentifica folosind utilizatorul root
și parola root
.
Pentru a transfera fișiere la distanță folosim scp
(secure copy). Comanda scp
se folosește de protocolul SSH pentru transferul de date între stații, astfel ne putem folosi de modelul de autentificare de la SSH, ca în comanda de mai jos:
student@uso:~$ scp /bin/bash student@10.10.10.3:~/ student@10.10.10.3's password: bash 100% 1156KB 30.5MB/s 00:00 student@uso:~$ ssh student@10.10.10.3 ls ~ student@10.10.10.3's password: bash
Fișierul /bin/bash
a fost copiat de pe stația uso
pe stația de la adresa IP 10.10.10.3
în directorul home al utilizatorului student
. Am rulat comanda ls ~
prin SSH pentru a verifica că s-a efectuat copierea cu succes.
Trimiterea fișierelor poate fi realizată în orice direcție:
Pentru descărcarea fișierelor de pe un server folosim comanda scp
:
student@uso:~$ scp root@10.10.10.3:/etc/resolv.conf . root@10.10.10.3's password: resolv.conf 100% 38 19.3KB/s 00:00 student@uso:~$ cat resolv.conf nameserver 127.0.0.11 options ndots:0 student@uso:~$ ssh root@10.10.10.3 cat /etc/resolv.conf root@10.10.10.3's password: nameserver 127.0.0.11 options ndots:0
Comanda rulată anterior a descărcat fișierul resolv.conf
din directorul /etc/
de pe stația 10.10.10.3
în directorul curent (.
).
Descărcați fișierul /etc/passwd
de la adresa 10.10.10.3
folosind utilizatorul student
și parola student
în directorul /home/student/Downloads
.
Pentru copierea unui director folosim opțiunea -r
:
student@uso:~$ scp -r ./Downloads/ root@10.10.10.3:~/ root@10.10.10.3's password: macos.txt 100% 18 4.2KB/s 00:00 index.html 100% 168 168.4KB/s 00:00 teamviewer_15.10.5_amd64.deb 100% 14MB 48.1MB/s 00:00
Comanda anterioară a copiat directorul Downloads
și conținutul său din directorul curent în directorul home al utilizatorului root
de la adresa 10.10.10.3
.
Copiați directorul /usr
de pe stația de la adresa 10.10.10.3
în directorul home al utilizatorului curent. Vă veți autentifica pe stația de la distanță folosind utilizatorul root
și parola root
.
În anumite scenarii ne dorim să evităm introducerea parolei pentru autentificarea la o stație la distanță. De exemplu, ne dorim să rulăm aceeași comandă pe 10 stații. Dacă am folosi autentificare bazată pe parolă ar fi nevoie să scriem într-un fișier în clar parola. Aceasta este o problema de securitate, deoarece dacă păstrăm o cheie în format text aceasta poate fi furată de cineva. O alternativă ineficientă este să scriem parola de 10 ori de mână.
Pentru a trece de această problemă putem să folosim mecanismul de autentificare cu chei. Autentificarea cu chei presupune existență a două chei pereche:
Cele două chei sunt legate matematic, iar posesorul cheii private se poate autentifica pe orice sistem unde este disponibilă cheia publică. Câtă vreme posesorul cheii private este singurul care are acces la cheie, nimeni nu se va mai putea autentifica în locul său.
Pentru generarea unei perechi de chei folosim comanda ssh-keygen
:
student@uso:~$ ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/home/student/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/student/.ssh/id_rsa Your public key has been saved in /home/student/.ssh/id_rsa.pub The key fingerprint is: SHA256:mN9IlWoU6bmSA1vvKBSAfAB/Rg9GwTaAhqZ1Kc0vfHM student@uso The key's randomart image is: +---[RSA 3072]----+ |=+o**o .. | |+=++Oo .. . | |+.o*oo....o | |. o= =+Eo | | Bo=S. | | o ++oo | | . =o . | | . . . | | . | +----[SHA256]-----+
În procesul de generare a cheilor ni se cere și un passphrase pentru a asigura securitatea cheii private în cazul în care este pierdută, furată sau altcineva are acces accidental la ea. Desigur, uitarea passphrase-ului face cheia nefolosibilă. Așa că passphrase-ul trebuie reținut (și protejat) ca orice altă parolă. Este indicat să nu protejați cheia printr-un passphrase deoarece prezintă aceleași probleme ca folosirea unei parole.
Pentru copierea cheii publice pe o stație folosim comanda ssh-copy-id
:
student@uso:~$ ssh-copy-id root@10.10.10.3 /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/student/.ssh/id_rsa.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 keys root@10.10.10.3's password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh 'root@10.10.10.3'" and check to make sure that only the key(s) you wanted were added.
Este necesar să cunoaștem parola utilizatorului pentru copierea cheii publice.
Atunci când copiem cheia publică, aceasta va fi copiată pentru un singur utilizator. Dacă vrem să ne autentificăm pe același sistem ca utilizatori diferiți fără parola, este necesar să copiem cheia publică pentru fiecare utilizator.
mere
.student
de pe stația 10.10.10.3
fără parolă.Există anumite tipuri de aplicații care funcționează în mod implicit în mediul grafic și aceste aplicații nu pot fi rulate în interfața în linie de comandă. De exemplu, installer-ul unui joc nu poate să fie rulat din linie de comandă.
Controlul acestor aplicații se poate reduce la două probleme:
Pentru control complet al unei sesiuni desktop grafice există o mai multe soluții, cum ar fi VNC, sau FreeRDP, dar noi ne vom concentra pe soluția numită TeamViewer, deoarece oferă suport pentru toate sistemele convenționale.
TeamViewer poate fi descărcat de la această adresă și permite autentificarea la o mașină folosind un ID și o parolă generate de aplicația server.
Descărcați și instalați aplicația TeamViewer pe mașina virtuală USO
și pe stația voastră fizică.
Pentru a ne conecta la o mașină la distanță avem nevoie de ID-ul mașinii și parola conexiunii. Aceste informații se găsesc în primul ecran al aplicației TeamViewer, cum se vede mai jos.
Vom scrie ID-ul stației la care vrem să ne conectăm în câmpul Partner ID
de pe calculatorul de pe care vrem să ne conectăm (stația client).
După ce apăsăm tasta Enter
apare promptul pentru parolă, unde completăm parola stației la care vrem să ne conectăm.
După ce am introdus parola a apărut pe ecran desktop-ul mașinii la care am vrut să mă conectez. În cazul de față este vorba de un sistem MacOS pe care am rulat TeamViewer.
Deasupra cadrului în care apare desktop-ul de la distanță apar butoane ce ne permit să închidem conexiunea, sau să trimitem acțiuni și fișiere către calculatorul server.
Conectați-vă la mașina virtuală USO de pe stația voastră fizică.
Pentru controlul unei ferestre de pe stația server putem să folosim protocolul SSH în modul X Forwarding (se referă la X Window System, care este un protocol de afișare al ferestrelor întâlnit în Linux). În acest fel se afișează pe stația client datele aplicației grafice care ar fi afișate pe stația server.
Acest mod de transfer nu este rapid, deoarece transferul se face printr-un protocol care nu este menit pentru aplicații care au nevoie să fie responsive, cum sunt ferestrele interactive, dar pot fi folosite pentru aplicații cum ar fi kituri de instalare ale programelor.
Pentru a porni o aplicație grafică pe un calculator la distanță trebuie să ne conectăm la această stație folosind opțiunea -X
a comenzii ssh
.
Pentru a rula browserul firefox
pe stația de la adresa 10.10.10.3
, ne-am conectat la aceasta folosind comanda ssh
cu opțiunea -X
și am pornit aplicația ca și când am porni-o local.
Observație:
Nu putem să preluăm controlul unei aplicații dacă aceasta a fost pornită deja pe stația de la distanță, deoarece putem doar sa primim semnalul video pentru aplicații nou pornite.
Deschideți aplicația grafică qbittorrent
ca utilizatorul student
pe stația 10.10.10.3
.
~/uso-lab/labs/03-user/lab-container/
comenzile ./lab_prepare.sh install openvpn
, ./lab_prepare.sh install openvpn-client1
și ./lab_prepare.sh install openvpn-client2
. Pentru a ne conecta la infrastructura necesară acestei secțiuni, vom folosi comanda ./lab_prepare.sh connect openvpn-client1
pentru stația openvpn-client1
și ./lab_prepare.sh connect openvpn-client2
pentru a vă conecta la stația openvpn-client2
.
O aplicație de tip VPN (Virtual Private Network) este o aplicație care permite crearea rețelelor de calculatoare în Internet fără ca acestea să fie neapărat în aceeași rețea fizică.
Funcționalitatea unui VPN este încapsularea datelor trimise de către un calculator, criptarea și trimiterea lor către un server care le va trimite mai departe către destinație.
Primul avantaj al folosirii unui VPN este “ascunderea” traficului între client și serverul VPN-ului. Astfel, acesta nu mai pot fi văzute de alte entități până când ajung la serverul VPN. Mai mult, datele care se vor îndrepta spre o destinație pot să depășească anumite filtre bazate pe locație, deoarece locația de unde provin va fi înlocuită de serverul VPN.
Al doilea avantaj al VPN-urilor este interconectarea facilă între calculatoare care se află în rețele locale diferite. De exemplu, pentru a juca un joc în LAN (Minecraft pe rețea), putem folosi un VPN, cum ar fi Hamachi3) , la care se conectează doi utilizatori. Serverul de VPN va primi datele de la clienți și le va trimite mai departe dintr-o rețea locală în alta.
Identificați adresele IP configurate pe interfețele stațiilor openvpn-client1
și openvpn-client2
.
Verificați conectivitatea între cele două stații folosind adresele IP identificate mai sus.
Pentru a porni VPN-ul, vom folosi comanda openvpn
. Rulați următoarea comandă pe ambele stații pentru a porni clientul de VPN:
root@openvpn-client1:~# openvpn --config ./openvpn-client1.ovpn --daemon root@openvpn-client1:~# ip address show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 3: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 100 link/none inet 192.168.255.6 peer 192.168.255.5/32 scope global tun0 valid_lft forever preferred_lft forever 45: eth0@if46: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:0a:0a:0a:0f brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 10.10.10.15/24 brd 10.10.10.255 scope global eth0 valid_lft forever preferred_lft forever root@openvpn-client2:~# openvpn --config ./openvpn-client2.ovpn --daemon root@openvpn-client2:~# ip address show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 2: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 100 link/none inet 192.168.255.10 peer 192.168.255.9/32 scope global tun0 valid_lft forever preferred_lft forever 47: eth0@if48: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:0b:0b:0b:0f brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 11.11.11.15/24 brd 11.11.11.255 scope global eth0 valid_lft forever preferred_lft forever
Observăm că a apărut o nouă interfață de rețea în sistem care nu are o componentă fizică. Adresa IP setată pe această interfață este adresa care identifică stațiile în rețeaua VPN-ului. Observați că ambele adrese de pe interfețele tun0
sunt foarte similare. Asta înseamnă că cele două stații sunt acum în aceeași rețea virtuală.
Testați conectivitatea de pe stația openvpn-client1
cu stația openvpn-client2
. Folosiți adresele IP configurate pe interfețele tun0
de pe fiecare stație.
Pentru a valida că datele chiar trec prin VPN, rulăm comanda traceroute 8.8.8.8
și observăm că mesajele spre Internet nu trec prin interfața eth0
. Mesajele trec prin interfața tun0
, ajung la serverul VPN identificat prin adresa 192.168.255.1
în pasul 1, iar abia apoi sunt lansate mai departe spre Internet.
root@openvpn-client1:~# traceroute 8.8.8.8 traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets 1 192.168.255.1 (192.168.255.1) 6.033 ms 6.031 ms 5.881 ms 2 10.10.10.253 (10.10.10.253) 8.582 ms 8.447 ms 8.306 ms 3 10.0.2.2 (10.0.2.2) 8.165 ms 8.031 ms 7.808 ms 4 * * * 5 * * * 6 r-c3550-l3-vlan11.bucharest.roedu.net (141.85.0.65) 8.308 ms 5.578 ms 4.876 ms 7 172.31.255.93 (172.31.255.93) 4.681 ms 6.882 ms 6.855 ms 8 po-23.acc1.buc.roedu.net (37.128.225.225) 16.711 ms 16.151 ms 16.751 ms 9 bu-13.core2.buc.roedu.net (37.128.232.177) 9.248 ms 9.268 ms 9.232 ms 10 hu-0-0-0-0.core3.nat.roedu.net (37.128.239.101) 8.510 ms 8.466 ms 6.542 ms 11 te-0-6-0-1.peers1.nat.roedu.net (37.128.239.42) 6.347 ms 5.894 ms 5.987 ms 12 google.interlan.ro (86.104.125.129) 31.665 ms 31.614 ms 31.529 ms 13 108.170.252.65 (108.170.252.65) 31.506 ms 108.170.251.193 (108.170.251.193) 31.146 ms 108.170.252.1 (108.170.252.1) 31.591 ms 14 172.253.73.153 (172.253.73.153) 31.795 ms 74.125.37.197 (74.125.37.197) 30.256 ms 74.125.37.167 (74.125.37.167) 30.068 ms 15 dns.google (8.8.8.8) 29.710 ms 34.122 ms 30.538 ms
Aceasta a fost o demonstrație a modului de lucru folosind openvpn
în linie de comandă pentru configurarea unui VPN folosind fișiere de configurare. Aceasta nu este singura metodă de conectare la VPN, există implementări diferite, cum ar fi WireGuard4) sau Cisco AnyConnect5) care oferă același serviciu dar implementat în mod diferit, oferind interfață grafică sau un mod facil de configurare.
sudo
pentru a permite afișarea numelor programelor care ascultă pe portul deschis. Comanda netstat
trebuie executată de un utilizatot privilegiat pentru această funcționalitate oferită de opțiunea -p
.