This shows you the differences between two versions of the page.
rl:teme:tema2 [2022/01/12 10:36] florin.stancu |
rl:teme:tema2 [2023/12/20 09:27] (current) florin.stancu |
||
---|---|---|---|
Line 2: | Line 2: | ||
* **Publicare**: | * **Publicare**: | ||
- | * //**2022-01-10 18:00**// | + | * //**2023-12-07 08:00**// |
* **Termen de predare**: | * **Termen de predare**: | ||
- | * //**2022-01-26 23:55 - deadline HARD **// | + | * //**2023-12-22 23:55 - <color red>deadline HARD!</color> **// |
**Revizii: ** | **Revizii: ** | ||
- | * //2022-01-12 10:35//: a fost urcată imaginea pe OpenStack! | + | * **//2023-12-18 22:10//:** Actualizat checker, ''v2023.2'': relaxat verificările de la task 2 (acum este nevoie doar de conectivitate IPv6 în cadrul aceleiași rețele -- deci merge și fără rutare)! |
- | * //2022-01-11 19:25//: **ex 12:** fix așteptare rsyslog să scrie pe disk, rezolvat în v2021.0.4 (''t2update''!); | + | * **//2023-12-08 12:15//:** Actualizat checker, ''v2023.1'': acum va face o verificare mai amănunțită -- toate serviciile vor fi repornite când rulați ''%%--%%save''! Re-citiți rubrica de persistență pentru a vedea cum salvați e.g., regulile ''iptables''! |
- | * //2022-01-11 13:05//: **ex 7:** descoperit problemă cu checkerul la filtrarea tracker-ului, rezolvat în v2021.0.3; | + | <hidden> |
- | * //2022-01-11 11:55//: **ex 6:** descoperit problemă cu checkerul la DNAT (se verifica portul greșit), rezolvat în v2021.0.2; | + | * **//2023-12-yy hh:mm//:** Reparat ceva |
+ | </hidden> | ||
- | Tema constă în realizarea configurației unui set de exerciții pe o topologie simulată într-o mașină virtuală. Topologia este alcătuită din mașina guest și trei containere virtualizate cu ajutorul tehnologiei LXC (atenție: nu se folosește Docker, ca la laboratoare, însă modul de utilizare este similar). | + | Tema constă în realizarea configurației unui set de exerciții pe o topologie (vedeți mai jos) simulată folosind containere (implementare în ContainerNet + Docker) într-o mașină virtuală (ori în cloud - OpenStack, ori descărcată și rulată local). |
- | Mai multe detalii despre topologie găsiți la secțiunea [[#Topologie|]]. | + | |
==== Notare ==== | ==== Notare ==== | ||
Line 20: | Line 20: | ||
Fiecare exercițiu are un punctaj propriu. Nota pe întreaga temă este dată de suma punctajelor acumulate în urma rezolvării fiecărui exercițiu. | Fiecare exercițiu are un punctaj propriu. Nota pe întreaga temă este dată de suma punctajelor acumulate în urma rezolvării fiecărui exercițiu. | ||
- | Punctajul maxim care se poate obține pe întreaga temă este 100 de puncte. Acest punctaj este echivalent cu 1.95 puncte din nota finală. | + | Punctajul maxim care se poate obține pe întreaga temă este 100 de puncte. Acest punctaj este echivalent cu **2 puncte** din nota finală. |
- | Există exerciții bonus cu ajutorul cărora puteți obține 125 de puncte. Din păcate, punctajul se trunchiază la 100 de puncte. Puteți rezolva exerciții bonus în schimbul exercițiilor obișnuite. | + | Există **și** exerciții bonus, cu ajutorul cărora puteți obține 125 de puncte. |
- | Nu este obligatorie rezolvarea tuturor exercițiilor. Exercițiile pot fi rezolvate în orice ordine, mai puțin în situația în care un exercițiu depinde de rezolvarea unui alt exercițiu. | + | Nu este obligatorie rezolvarea tuturor exercițiilor. Exercițiile pot fi rezolvate în orice ordine, mai puțin în situația în care un exercițiu depinde de rezolvarea unui alt exercițiu (de obicei, primele 4 de stabilire a conectivității containere -- Internet). |
- | ==== Topologie ==== | + | <ifauth @rl> |
- | + | **Cine vede ce este mai jos este asistent ;)** | |
- | {{:rl:topologie.png}} | + | </ifauth> |
==== Mașina virtuală ==== | ==== Mașina virtuală ==== | ||
Line 34: | Line 34: | ||
=== Utilizare === | === Utilizare === | ||
- | * Puteți rezolva tema atât folosind o mașină virtuală locală, cât și folosind infrastructura cloud OpenStack. | + | * Puteți rezolva tema ori folosind infrastructura OpenStack (aveți proiect special numit ''rl_tema_prj'' - meniu stânga sus, lângă logo OpenStack - unde găsiți și imaginea), ori o mașină virtuală locală (citiți mai jos). |
- | * Notă: pe OpenStack, autentificarea cu username și parolă nu este posibilă! Folosiți autentificarea cu chei publice, [[:rl:labs:08|prezentată aici]]. | + | * Notă: pe OpenStack, autentificarea cu username și parolă nu este posibilă! Folosiți autentificarea cu chei publice, [[:rl:info:resurse:vm-laborator|prezentată aici]]. |
* Pentru autentificare pe VM local, utilizați credențialele **student/student**. | * Pentru autentificare pe VM local, utilizați credențialele **student/student**. | ||
=== Pași pentru accesare OpenStack === | === Pași pentru accesare OpenStack === | ||
- | * Urmăriți pașii [[:rl:labs:08|din laborator]]. | + | * Urmăriți pașii [[:rl:labs:06|din laboratoare]]. |
* Link dashboard: https://cloud.grid.pub.ro/ | * Link dashboard: https://cloud.grid.pub.ro/ | ||
- | * Nume imagine: **RL 2021 Tema2** (atenție: nu pe cea cu //2020//!) | + | * Va trebui să vă importați cheia publică pe acest proiect nou ''rl_tema_prj'' (proiectul de laborator este diferit, ''rl_prj''); |
- | * Tip instanță: **m1.small** (NU aveți nevoie de mai mult) | + | * Nume imagine (de selectat la //Sources//): **RL Tema2 v2023.0**; |
- | * Puneți la VM un nume de forma cu ''Tema2_<your username>'' pentru a nu fi confundat cu VM de laborator și șters de către alți asistenți! | + | * Tip instanță: **m1.small** (NU aveți nevoie de mai mult); |
+ | * Puneți la VM un nume care să vă conține prefixul ''TEMA2_'' apoi username-ul vostru de Moodle (dacă veți avea nevoie de ajutor din partea unui asistent, să vă găsim ușor); | ||
* **OBLIGATORIU:** autentificarea cu user și parolă a fost dezactivată, folosiți EXCLUSIV chei publice ssh (pe care ar trebui s-o aveți deja configurată în cadrul laboratoarelor). | * **OBLIGATORIU:** autentificarea cu user și parolă a fost dezactivată, folosiți EXCLUSIV chei publice ssh (pe care ar trebui s-o aveți deja configurată în cadrul laboratoarelor). | ||
* **NU modificați parola la conturile root / student!** Dacă vă tăiați accesul la VM din greșeală, cereți ajutorul unui asistentului preferat pe Teams ;) | * **NU modificați parola la conturile root / student!** Dacă vă tăiați accesul la VM din greșeală, cereți ajutorul unui asistentului preferat pe Teams ;) | ||
Line 52: | Line 53: | ||
=== Rulare în VM local === | === Rulare în VM local === | ||
- | * Pentru a rula mașina virtuală a temei local, **o puteți descărca [[https://rl-checker.root.sx/share/RL_2021_Tema2.zip|de la acest URL]]** (//1.6 GB arhivat .zip, 5-6 GB dimensiune dezarhivat//). | + | * Pentru a rula mașina virtuală a temei local, **o puteți descărca [[https://rlrullz.root.sx/share/RL_Tema2_v2023_0.7z|de la acest URL]]** (//4.6GB dezarhivat//). |
- | * VM-ul este compatibil atât cu VirtualBox (testat cu 6), cât și VMWare (testat cu Workstation >= 15). Pe Linux, poate fi rulat și prin qemu+kvm. | + | * VM-ul este compatibil atât cu VirtualBox (testat cu 6), cât și VMWare (testat cu Workstation >= 16). Pe Linux, poate fi rulat și prin qemu+kvm. |
- | * Accesul prin ssh cu parolă este activat, deoarece VM-ul rulează pe o rețea privată. | + | * Va trebui să vă creați mașină virtuală nouă în hipervizorul preferat (VMWare / VirtualBox / etc.) și să importați fișierul ''vmdk'' (căutați pe Google documentație, pașii diferă în funcție de programul de virtualizare folosit). |
- | * Dacă întâmpinați probleme, creați un proiect de mașină virtuală nouă și atașați-i disk-ul existent ''vmdk''. | + | * Accesul prin ssh cu parolă (''student:student'') este activat, deoarece VM-ul rulează pe o rețea privată. |
- | * **Atenție**: Imaginea VM-ului diferă de cea a laboratorului, asigurați-vă că îl descărcați pe cel corect! | + | * **Atenție: Imaginea VM-ului diferă de cea a laboratorului**, asigurați-vă că îl folosiți pe cel corect! |
==== Verificarea temei ==== | ==== Verificarea temei ==== | ||
- | |||
- | * Mașina virtuală conține checkerul (sursă închisă) și dispune de două scripturi pentru a face actualizarea și rularea sa mai simplă. | ||
* Pentru verificarea temei este disponibil un checker local. Atenție: nu este substitut pentru depanare! | * Pentru verificarea temei este disponibil un checker local. Atenție: nu este substitut pentru depanare! | ||
* Altfel spus, contează soluția voastră, nu checker-ul. | * Altfel spus, contează soluția voastră, nu checker-ul. | ||
- | * Dacă, dintr-o greșeală, checker-ul dă rezulat pozitiv în cazul unui exercițiu rezolvat greșit nu înseamnă că se va puncta. O eventuală actualizare a checker-ul va puncta corect. | + | * Dacă, dintr-o greșeală, checker-ul dă rezulat pozitiv în cazul unui exercițiu rezolvat greșit nu înseamnă că se va puncta. O eventuală actualizare a checker-ul va puncta corect (însă veți fi notificați să re-verificați pe canalele obișnuite, forum și Teams). |
* Obiectivul trebuie să fie rezolvarea corectă a enunțului. Checker-ul vine ca o confirmare (ne dorim cât mai sigură) a acelei rezolvări. | * Obiectivul trebuie să fie rezolvarea corectă a enunțului. Checker-ul vine ca o confirmare (ne dorim cât mai sigură) a acelei rezolvări. | ||
- | * Punctajul afișat pe RL Checker va fi și cel acordat în catalog la final. | + | * Punctajul afișat de RL Checker la final va fi și cel acordat în catalog la final. |
- | * Înainte de a rula checkerul, se recomandă descărcarea ultimului update prin rularea <code>root@host$ t2update</code>. | + | * Play fair: orice tentativă de fraudare / atac la infrastructură va avea ca efect pierderea definitivă a punctajului (sau chiar repetarea materiei, în anumite cazuri), chiar dacă checkerul este //păcălit// :P. |
+ | * Înainte de a rula checkerul, se recomandă descărcarea ultimului update prin rularea: <code>root@host$ t2update</code> | ||
* Comenzile de mai jos pot fi rulate indiferent de directorul in care ne aflăm. | * Comenzile de mai jos pot fi rulate indiferent de directorul in care ne aflăm. | ||
Line 82: | Line 82: | ||
... | ... | ||
- | root@host:~# t2check 11 | + | root@host:~# t2check 10 |
- | task11 ......................... 0.0/10.0 | + | task10 ......................... 0.0/10.0 |
mail not received | mail not received | ||
</code> | </code> | ||
- | * Dacă sunt probleme, puteți să postați un mesaj pe thread-ul aferent de pe [[https://curs.upb.ro/2021/mod/forum/view.php?id=134436|forum]]; | + | * Dacă sunt probleme, puteți să postați un mesaj pe thread-ul aferent de pe [[https://curs.upb.ro/2023/mod/forum/view.php?id=85311|forum]]; |
==== Predarea temei ==== | ==== Predarea temei ==== | ||
- | - Pentru urcare soluție, rulați: <code>root@host$ t2check --save</code> | + | - Pentru împachetarea soluției, rulați: <code>root@host$ t2check --save</code> (<color red>atenție: această comandă va reseta rețelistica și reporni toate serviciile, echivalent cu un reboot mai rapid -- asigurați-vă că ați lucrat persistent (//vedeți mai jos, la task-uri, cum//)!</color>) |
- | - Rezultatul este o arhivă semnată în directorul în care invocați comanda. | + | - Rezultatul este o arhivă semnată în directorul în care invocați comanda (''$PWD''). |
- Folosind utilitarul ''scp'', copiați acest fișier pe stația voastră locală (atenție să nu încurcați directoarele și să copiați o arhivă veche / salvată în altă parte!). Dacă sunteți conectat la OpenStack prin serverul intermediar ''fep.grid.pub.ro'', va trebui să copiați mai întâi acolo, apoi s-o preluați pe stația voastră de lucru (alternativ, puteți folosi funcționalitatea de ''ProxyCommand'' a clientului ''ssh'' pentru o conexiune directă). | - Folosind utilitarul ''scp'', copiați acest fișier pe stația voastră locală (atenție să nu încurcați directoarele și să copiați o arhivă veche / salvată în altă parte!). Dacă sunteți conectat la OpenStack prin serverul intermediar ''fep.grid.pub.ro'', va trebui să copiați mai întâi acolo, apoi s-o preluați pe stația voastră de lucru (alternativ, puteți folosi funcționalitatea de ''ProxyCommand'' a clientului ''ssh'' pentru o conexiune directă). | ||
- | - Încărcați arhiva pe [[https://curs.upb.ro/2021/mod/lti/view.php?id=60795|RL Checker]] (Moodle). | + | - Încărcați arhiva pe [[https://curs.upb.ro/2023/mod/lti/view.php?id=85310|RL Checker]] (Moodle). |
- | <note important>Recomandăm ca rezolvarea exercițiilor trebuie să se facă în mod persistent. La o repornire a mașinii virtuale, rezolvările trebuie să rămână active, altfel puteți întâmpina dificultăți la o revenire ulterioară asupra temei. | + | <note important>Este **obligatoriu** ca rezolvarea exercițiilor să se facă în mod persistent. La o repornire a mașinii virtuale, rezolvările trebuie să rămână active, altfel puteți întâmpina dificultăți la o revenire ulterioară asupra temei. |
- | Folosiți comanda ''reboot'' înainte să testați de-a întregul (checkerul local doar simulează ceva mai rapid).</note> | + | Folosiți comanda ''reboot'' înainte să testați de-a întregul (checkerul local doar simulează ceva mai rapid). |
+ | |||
+ | De asemenea, puteți folosi comanda ''systemctl restart rl-topology'' pentru a reporni rapid toate containerele (sistemul lor de fișiere este și el persistent).</note> | ||
<note warning> | <note warning> | ||
- | Pentru a rezolva tema este îndeajuns să prelucrați fișiere doar din căile ''/etc'', ''/home'' și ''/root'' (atât pe host, cât și pe containere). NU instalați alte pachete în plus. | + | Pentru a rezolva tema este suficient să prelucrați fișiere doar din căile ''/etc'', ''/home'' și ''/root'' (atât pe host, cât și pe containere). NU instalați alte pachete în plus! |
</note> | </note> | ||
+ | |||
+ | <note warning> | ||
+ | NU opriți / ștergeți manual containerele Docker (decât dacă doriți să luați de la zero cu configurarea acestora, vedeți mai jos comanda). | ||
+ | |||
+ | Pentru a **șterge și reseta** configurația de pe un container, se folosiți secvența: <code>systemctl stop rl-topology && docker container rm <nume container> && systemctl restart rl-topology;</code> | ||
+ | </note> | ||
+ | |||
==== Personalizarea temei ==== | ==== Personalizarea temei ==== | ||
- | Rezolvările sunt particularizate pentru fiecare student (pe baza contului Moodle). Pentru a obține aceste date, accesați link-ul Moodle [[https://curs.upb.ro/2021/mod/lti/view.php?id=60795|RL Checker]]. | + | Rezolvările sunt particularizate pentru fiecare student (pe baza contului Moodle). Pentru a obține aceste date, accesați link-ul Moodle [[https://curs.upb.ro/2023/mod/lti/view.php?id=85310|RL Checker]]. |
- | Datele de particularizare afișate pe Moodle vor fi introduse şi în fişierul **''/root/tema2.txt''**, unde va trebui să păstrați formatul text ''VARIABILA=valoare'' (liniile noi în plus nu contează)! Atenție: nu puteți personaliza aceste valori, ele fiind verificate cu strictețe de către checker-ul online! | + | **Atenție:** datele de particularizare afișate pe Moodle vor fi introduse şi în fişierul **''/root/assignment.txt'' de pe host**, unde va trebui să păstrați formatul text ''VARIABILA=valoare'' (liniile noi în plus nu contează)! **Nu modificați aceste valori**, ele fiind verificate cu strictețe de către checker-ul online! Includeți ȘI variabila ''USERNAME''! |
Informațiile generate anterior vor fi folosite în enunțul temei cu următoarele notații: | Informațiile generate anterior vor fi folosite în enunțul temei cu următoarele notații: | ||
- | <code> | + | |
- | - $A = valoarea variabilei A | + | * ''$A'' - valoarea variabilei A |
- | - $B = valoarea variabilei B | + | * ''$B'' - valoarea variabilei B |
- | - $C = valoarea variabilei C | + | * ''$C'' - valoarea variabilei C |
- | - $D = valoarea variabilei D | + | * ... |
- | - $E = valoarea variabilei E | + | |
- | - $F = valoarea variabilei F | + | |
- | - $G = valoarea variabilei G | + | |
- | - $H = valoarea variabilei H | + | |
- | - $I = valoarea variabilei I | + | |
- | - $J = valoarea variabilei J | + | |
- | - $K = valoarea variabilei K | + | |
- | </code> | + | |
==== Discuții legate de temă ==== | ==== Discuții legate de temă ==== | ||
- | Toate discuțiile legate de probleme/întrebări/exerciții din tema de RL trebuie puse pe [[https://curs.upb.ro/2021/mod/forum/view.php?id=134436|forumul temei]]. | + | Toate discuțiile legate de probleme/întrebări/exerciții din tema de RL trebuie puse pe [[https://curs.upb.ro/2023/mod/forum/view.php?id=85311|forumul temei]]. |
Reguli de utilizare ale acestui forum: | Reguli de utilizare ale acestui forum: | ||
- | * Nu se pun rezolvări pe forum. | + | * Nu se pun rezolvări directe pe forum. |
* Fiecare întrebare legată de un task trebuie pusă pe thread-ul dedicat acelui task. | * Fiecare întrebare legată de un task trebuie pusă pe thread-ul dedicat acelui task. | ||
* În momentul în care puneți o întrebare, includeți în mesaj: | * În momentul în care puneți o întrebare, includeți în mesaj: | ||
Line 143: | Line 144: | ||
==== Subiecte ==== | ==== Subiecte ==== | ||
- | <note warning>Toate configurațiile să fie **persistente**. Trebuie să fie active și după repornirea mașinii virtuale.</note> | + | <color green>**Este recomandat să citiți enunțul în întregime prima oară și de oricâte ori aveți întrebări!**</color>. |
+ | Și, desigur, recitirea completă a task-ului următor de care vă apucați / după o pauză îndelungată de la rezolvarea acestuia. | ||
+ | |||
+ | === Topologie & infrastructură === | ||
+ | |||
+ | În topologie aveți ruterele ''host'' (fiind VM-ul care găzduiește toată infrastructura), ''Router0'' (containerul are denumirea ''R0'') și ''Router-X'' (sub ID-ul ''R-X''), ''PC1'', ''PC2'', ''PC3'' conectate la ''SW'' (switch -- nu veți avea nimic de configurat la el) prin 2 VLAN-uri (''10'' și ''20'') și ''PC-X'' (rețea cu ''R-X''). | ||
+ | |||
+ | **Atenție**: din motive tehnice, identificatorii echipamentelor ''Router0'' și ''Router-X'' au fost prescurtate la ''R0'' respectiv ''R-X''. Folosiți denumirile prescurtate DOAR ATUNCI când vă conectați la container (folosind comanda ''go'' sau comenzi docker -- dacă va fi cazul), în rest utilizați denumirea full pentru orice altceva (e.g., alias / hosts). | ||
+ | |||
+ | {{:rl:teme:tema2_topology_2023.png?600}} | ||
+ | |||
+ | <note> | ||
+ | **Fapt divers:** VLAN9 se numește rețeaua de pe OpenStack, dacă rulați local, acolo va fi rețeaua hivervizorului (VMWare / VirtualBox) cu mașina fizică. | ||
+ | </note> | ||
+ | |||
+ | <note important>Va trebui să realizați **primele 4** exerciții în ordine. Întrucât aceste exerciții oferă, în final, conectivitate la Internet, restul vor depinde de acestea!</note> | ||
+ | |||
+ | == Configurații persistente == | ||
+ | |||
+ | <note warning> | ||
+ | Toate configurațiile să fie **persistente**. Trebuie să fie active și după repornirea mașinii virtuale. | ||
+ | |||
+ | Pentru modificarea unor fișiere speciale din containerele Docker (''/etc/hosts'', ''/etc/resolv.conf'') va trebui să folosiți un script de init sau hook de ifupdown-ng. Găsiți mențiuni adecvate la exercițiile unde va fi necesar să faceți asta! | ||
+ | </note> | ||
+ | |||
+ | Pentru configurație persistentă, atât host-ul, cât și containerele vin cu [[https://github.com/ifupdown-ng/ifupdown-ng|ifupdown-ng]] pre-instalat. | ||
+ | |||
+ | Pentru a începe să configurați, verificați fișierele existente la căile ''/etc/network/interfaces'' și ''/etc/network/interfaces.d/*'' | ||
+ | (=> [[https://github.com/ifupdown-ng/ifupdown-ng/blob/main/doc/ADMIN-GUIDE.md|RTFM here ;)]]). | ||
+ | |||
+ | Pentru a configura persistent **rute adiționale** (și nu numai!), puteți folosi hook-ul ''up'' din sintaxa de configurare ''interfaces''. Exemplu (fragment): <code> | ||
+ | iface <intf> | ||
+ | address A.B.C.D/xx | ||
+ | up ip route add X.Y.Z.T/yy via Q.W.E.R | ||
+ | </code> | ||
+ | |||
+ | Fișierele ''/etc/network/interfaces*'' se parsează și execută linie cu linie, scripturile ''if[up|down]'' oprindu-se la prima eroare întâlnită. | ||
+ | De exemplu, dacă aveți într-o secțiune ''iface'' un hook "''up ip ro add invalid route...''" și pe rândurile următoare aveți alte declarații, acestea nu vor mai ajunge să fie aplicate! | ||
+ | |||
+ | Puteți folosi următorul oneliner pentru a verifica rapid o interfață: <code> | ||
+ | ifdown --force <intf>; ifup <intf>; ip a sh; ip ro sh | ||
+ | # hint: folosiți ifdown și ifup cu parametrul -a pentru a porni TOATE interfețele declarate! | ||
+ | # ÎNSĂ: NU RULAȚI `ifdown -a` pe host! VĂ VEȚI PIERDE CONECTIVITATEA PE eth0 !!! | ||
+ | </code> | ||
+ | |||
+ | **Pentru a salva regulile ''iptables''**, urmați pașii de aici: https://www.serveracademy.com/courses/linux-fundamentals/how-to-save-iptables-rules-permanently/ (există mai multe modalități, e.g. puteți pune hook-uri de ''up'' la o interfață etc.). <color red>SUB NICI O FORMĂ SĂ NU INSTALAȚI PACHETELE DESCRISE DIN TUTORIALE (mai ales ''ifupdown'' -- vă strică VM-ul, aveți deja ''ifupdown-ng''!!)</color>. | ||
+ | |||
+ | <note important>Dacă folosiți mai multe fișiere în scripturi (e.g., apelați dintr-un script alt script), folosiți căi absolute. Adică folosiți ''/root/scripts/make-juju.py'' în loc de ''./make-juju.py'' pentru a nu se baza pe directorul actual de lucru (''working directory''). NU uitați să le faceți executabile și să includeți shebang-ul!</note> | ||
+ | |||
+ | === Ex. 1 [25p] Adresare + rutare IPv4 === | ||
+ | |||
+ | - Configurați cu adrese IPv4 toate legăturile din topologie, astfel: | ||
+ | * Subnetați în două rețele fixe (de dimensiuni egale) spațiul ''10.13.$A.0/24''; distribuiți prima subrețea către ''VLAN10'', iar cealaltă lui ''VLAN20''; atribuiți prima adresă asignabilă ruterului (''Router0''), apoi următoarele în ordinea denumirilor stațiilor (i.e., ''Router0, PC1, PC3'' respectiv ''Router0, PC2'')! **Atenție**: pe router aveți deja declarate VLAN-urile în fișierul din ''/etc/network/interfaces.d/''! | ||
+ | * Pentru rețelele ''host -- Router0'' și ''host -- Router-X'', subnetați **optim** spațiul ''10.11.$B.0/29'' și distribuiți-le în ordinea mențiunii din enunț; ''host'' trebuie să aibă, mereu, **prima** adresă asignabilă! | ||
+ | * Pentru rețeaua ''Router-X -- PC-X'': ''172.18.$C.64/29''; ruterul va avea prima adresă asignabilă, iar stația ''PC-X'' **PE ULTIMA** (atenție: **nu broadcast!**, cea dinaintea acestuia)! | ||
+ | * //Recomandare:// nu modificați nimic pe containerul ''SW'' (switch), altfel riscați să vă stricați infrastructura! | ||
+ | - Configurați rutarea IPv4 (atât default gateways, cât și rute statice!) astfel încât toate stațiile să se poată accesa unele pe altele prin adresă IP! | ||
+ | |||
+ | <note warning><color red>**Atenție mare**:</color> adresa IP de pe ''eth0'' a sistemului ''host'' este asignată dinamic de către hipervizor, prin DHCP; NU vă atingeți (//never go full ifdown!//) de această interfață, altfel riscați să vă pierdeți accesul la VM!</note> | ||
+ | |||
+ | === Ex. 2 [15p] Adresare IPv6 === | ||
+ | |||
+ | - Configurați adrese IPv6 pentru rețeaua ''VLAN10'' și ''VLAN20'' (notă: variabila ''$VLANID'' va avea valoarea 10, respectiv 20): | ||
+ | * Folosiți spațiul ''2023:E666:$B:$A:$VLANID::/80''. | ||
+ | * Aceeași ordine de mai sus (ca la IPv4): ''Router0'' va avea prima adresă asignabilă, apoi ''PCn'' sortate numeric. | ||
+ | - Configurați conectivitate IPv6 între ''Router0'' și ''host'': | ||
+ | * Folosiți spațiul ''FEC0:5017:$C:$D::/64''. | ||
+ | * Prima adresă asignabilă este pentru ''host'', a doua a lui ''Router0''. | ||
+ | - Configurați rutarea IPv6 pentru a permite comunicarea între toate sistemele cu adresă IPv6. | ||
+ | * Rețeaua ''Router-X -- PC-X'' **NU** va avea adresă IPv6 ;) | ||
+ | |||
+ | === Ex. 3 [5p] Hosts === | ||
+ | |||
+ | * Realizați configurațiile necesare astfel încât echipamentele să poată fi accesate prin numele lor (folosiți numele ''host'', ''Router0'', ''PC1'', ''PC2'', ''PC3'', ''Router-X'', ''PC-X'' - atenție la MAJUSCULE!). Adăugați intrări doar pentru adresele IPv4. | ||
+ | |||
+ | <note> | ||
+ | Fișierul ''/etc/hosts'' din containere este mai special (montat ca volum ''%%--%%bind'' de către Docker). | ||
+ | Acest lucru face ca orice modificare a acestuia să se piardă la fiecare restart al containerului (aka reboot al VM-ului sau restart al serviciului ''rl-topology''). | ||
+ | Dacă (și sigur) vreți să persiste, puteți să-l salvați în altă cale (e.g., ''/etc/hosts.orig'' și să-l restaurați mereu când pornește containerul printr-un hook de ''up'' în ''/etc/network/interfaces''). | ||
+ | Ah, și nu folosiți ''cp'', folosiți ''cat'' + redirectare bash (fiind volum, nu puteți șterge + recrea fișierul, trebuie trunchiat & suprascris), e.g.: <code> | ||
+ | iface <intf> | ||
+ | up cat /etc/hosts.orig >/etc/hosts | ||
+ | </code> | ||
+ | </note> | ||
+ | |||
+ | === Ex. 4 [5p] Internet connectivity === | ||
+ | |||
+ | * Realizați configurațiile necesare pentru ca cele 4 containere sa aibă acces la Internet: | ||
+ | * Configurați translatarea pe sistemul host astfel încât containerele să poată primi răspunsuri din Internet. | ||
+ | * Configurați cele 4 containere pentru a putea accesa resurse din Internet pe baza numelor de domeniu al acestora (DNS). | ||
+ | * **Atenție**: nu translatați orice pachet este rutat (e.g., cele între containere ar trebui să-și vadă IP-urile originale)! | ||
+ | |||
+ | <note> | ||
+ | Fișierul ''resolv.conf'' este gestionat ca volum de către Docker :( | ||
+ | ... aceeași poveste ca la exercițiul anterior => aceeași soluție (e.g., faceți un fișier ''/etc/resolv.conf.orig'' pe care îl veți suprascrie peste ''/etc/resolv.conf'' cu un hook pe ''up'' din interfaces). | ||
+ | </note> | ||
+ | |||
+ | === Ex. 5 [10p] Network Address Translation === | ||
+ | |||
+ | * Configurați reguli de **NAT** pe sistemele ''host'' și ''Router0'' (după caz, ori unul ori ambele :P), astfel: | ||
+ | * Conexiunile pe ''Router0'' la porturile ''(14000 + $E)'', ''(14000 + $F)'' și ''(14000 + $G)'' să conducă la conectarea ssh pe sistemele ''PC1'', ''PC2'' respectiv ''PC3''. | ||
+ | * Conectarea pe ''host'' la portul ''(6000 + $K)'' să conducă la conectarea pe tracker-ul de pe sistemul ''PC-X''. | ||
+ | * **Sfat**: aveți grijă cum testați: DNAT-ul va funcționa DOAR dacă veniți dintr-o rețea externă ruterului ;) | ||
+ | |||
+ | === Ex. 6 [10p] Filtrare pachete (iptables) === | ||
+ | |||
+ | * Configurați **filtrarea** de pachete pe ''host'' și / sau ''Router0'' (după caz) astfel încât: | ||
+ | * conexiunile SMTP și SSH inițiate de pe sistemul ''PC3'' în afara rețelei lui să fie blocate //(inclusiv către alte rutere!)//; | ||
+ | * conexiunile către tracker-ul ce rulează pe sistemul ''PC-X'' **să nu** fie permise de la ''PC1, PC2, PC3''. | ||
+ | * blocați TOATE conexiunile externe (i.e., de pe IP-urile din afara stației) către ''PC2'', mai puțin protocoalele ''icmp'' și ''ssh''. | ||
+ | * **atenție**: NU blocați conexiunile inițiate de ''PC2'' **și nici răspunsurile** de la acestea! folosiți reguli **stateful** (i.e. connection tracking)! | ||
+ | |||
+ | === Ex. 7 [10p] Chei SSH === | ||
+ | |||
+ | * Configurați serviciul de **SSH** pe sistemele ''PC1'', ''PC2'', ''PC-X'' și ''host'' astfel încât autentificarea cu utilizatorul ''student'' de pe oricare sistem să fie permisă pe toate celelate sisteme (tot în cadrul utilizatorului ''student'') folosind chei publice; | ||
+ | * Folosind [[https://collectiveidea.com/blog/archives/2011/02/04/how-to-ssh-aliases/|alias-uri SSH]] să fie folosite comenzi simplificate pentru conectarea prin SSH între sistemele menționate mai sus: | ||
+ | * ''ssh pc1'' să ducă către sistemul ''PC1'' cu utilizatorul ''student''; | ||
+ | * ''ssh pc2'' să ducă către sistemul ''PC2'' cu utilizatorul ''student''; | ||
+ | * ''ssh pc-x'' să ducă către sistemul ''PC-X'' cu utilizatorul ''student''; | ||
+ | * ''ssh host'' să ducă către sistemul ''host'' cu utilizatorul ''student''; | ||
+ | * **Observație**: ''ssh-copy-id'' utilizează autentificare ssh pe bază de parolă pentru a copia cheia. Mașina virtuală pe OpenStack nu permite astfel de autentificare pe ''host'', așadar veți fi nevoiți să autorizați cheia publică manual in fișierul corespunzător! | ||
+ | |||
+ | <note important> | ||
+ | **Atenție**: NU VĂ ȘTERGEȚI CHEIA DE LA OPENSTACK DIN FIȘIERUL DE AUTORIZAȚII! Vă veți pierde accesul la VM.. asigurați-vă când editați fișierul că nu modificați acea linie!! | ||
+ | </note> | ||
+ | |||
+ | === Ex. 8 [10p] Căutare recursivă pe server HTTP cu autentificare === | ||
+ | |||
+ | * Creați, pe sistemul ''PC-X'' scriptul ''/home/student/scripts/pass'' care să caute recursiv prin paginile de la ''http://host/.secret/'' și să găsească fișierul ''password.txt'' (e.g., ''http://host/.secret/sub/cale/passwords.txt''). | ||
+ | * Scriptul va trebui să afișeze DOAR conținutul fișierului găsit! | ||
+ | * Va trebui să vă autentificați prin HTTP cu credențialele: | ||
+ | * //username//: ''corina'' | ||
+ | * //password//: ''RL2023'' | ||
+ | * Desigur, trebuie mai întâi să descoperiți ce tip de autentificare să folosiți! | ||
+ | |||
+ | === Ex. 9 [10p] Descărcare / încărcare fișiere între servere === | ||
- | <note important>Va trebui să realizați primele 5 exerciții în ordine. Întrucât aceste exerciții oferă, în final, conectivitate la Internet, restul se vor baza pe acestea!</note> | + | * Pe ''PC3'', realizați un script la ''/home/student/scripts/send-music'' care va prelua DOAR fișiere care conțin DOAR MAJUSCULE cu extensia ''.mp3'' (i.e. ''[A-Z]+\.mp3'', litere mici extensia!) din directorul curent (i.e.: ''$PWD'') și le va uploada pe ''PC1'', în destinația ''/home/fs/music''; folosiți credențialele ''fs:5$4l0m''. NU uitați să-l faceți executabil (+ shebang)! |
+ | * Pe ''host'', creați script-ul ''/root/scripts/copy-firmware'' care, în primul rând, descarcă DOAR fișierele cu forma ''[a-zA-Z0-9]+\.bin'' (caractere alfa-numerice + extensia ''.bin'') de pe stația ''PC-X'' din ''/opt/my-firmware'' și le încarcă (uploadează) pe stația ''PC2'', în directorul ''/tmp/firmware-files/'' (va trebui să-l creați dacă nu există!). | ||
+ | * Folosi un utilitar aplicabil protocolului (dintre ''ftp'' / ''wget'' / ''curl'' / ''scp'' / ''rsync''), după caz (recomandăm studierea tuturor înainte de a lua o decizie!)! | ||
+ | * În toate cazurile, aveți de a face DOAR cu fișiere (i.e., transfer non-recursiv); nu le copiați în alte subdidrectoare (trebuie duse/preluate direct la/în calea menționată), altfel acestea nu vor fi văzute de către checker (+ rezolvare incorectă)! | ||
+ | * **Atenție**: notația folosită în enunț este PCRE (Perl-Compatible Regular Expressions), însă acest format nu este obligatoriu implementat ca pattern de utilitarele folosite! Citiți documentația / man page-ul utilitarului înainte (atenție la glob vs regex -- au diferențe mari de sintaxă)! | ||
+ | * Pentru testare, puteți ori să vă creați fișierele necesare într-un director temporar, ori să lăsați checkerul să facă acest lucru (automat), într-un director _temporar_ (va trebui să-l căutați, though, dar e evident unde îl va pune ;). | ||
+ | * Checkerul pentru acest task va refuza să ruleze dacă nu există scripturile / nu sunt executabile (va afișa pur și simplu eroarea ''skipped'')! | ||
- | <note important>Dacă folosiți mai multe scripturi (apelați dintr-un script alt script), folosiți căi absolute. Adică folosiți ''/root/scripts/make-juju.py'' în loc de ''./make-juju.py'' pentru a nu se baza pe directorul actual de lucru (''working directory'').</note> | + | === Ex. 10 [Bonus - 10p] Wireguard tunnelling === |
- | <note warning>Nu trebuie instalați nimic în plus pe mașina virtuală, nu ar trebui să fie nevoie.</note> | + | * Dorim să conectăm rețeaua ''VLAN10'' (cea cu ''PC1'' și ''PC3'', aka un site întreg) la stația ''PC-X'' (endpoint). |
+ | * Veți folosi 2 rețele noi: subnetați **OPTIM** spațiul IPv4 ''10.66.$J.0/28''; asignați prima subrețea către site-ul ''VLAN10'', iar pe cea de-a doua pentru capetele de tunel (''Router0'' și ''PC-X'') -- folosiți convențiile de ordinea ale IP-urilor de la primul exercițiu! | ||
+ | * Denumiți interfețele de tunel ''wg-rl'' la ambele capete. | ||
+ | * Pe stațiile vizate, toate pachetele destinate către ''10.66.$J.0/28'' trebuie trecute prin acest tunel! | ||
+ | * **Hint ^**: o interfață Linux poate avea mai multe adrese asignate ;) pur și simplu, adăugați mai multe intrări de tipul ''address'' în ''interfaces''. | ||
+ | * Tunelul wireguard trebuie să fie persistent! (folosiți hook-uri în ''interfaces''). | ||
+ | * //Hint//: nu uitați să activați rutarea la ameble capete de tunel (unul ar trebui să aibă deja, însă celălalt sigur nu)! | ||
- | Se recomandă citirea întregului set de exerciții înainte de rezolvarea temei. În mod asemănător, la rezolvarea unui exercițiu se recomandă citirea întregului subset de exerciții. | + | === Ex. 11 [Bonus - 15p] Advanced NAT === |
- | - (**10 puncte**) Adresare IPv4 | + | * Pe stația ''PC3'' va fi pornit un serviciu special pe portul TCP ''999'' care va accepta DOAR pachete din rețeaua securizată prin wireguard creată la task-ul anterior (checkerul îl va porni automat; pentru testare puteți folosi ''nc'' cu argumentul ''-l'' și IP destinație de pe rețeaua WireGuard (+ desigur, portul), trebuie să puteți trimite mesaje bidirecționale prin portul forwardat). |
- | - Configurați cu adrese IP toate legăturile din topologie, astfel: | + | * Configurați firewallul pe ''PC-X'' (aveți iptables instalat) pentru a realiza DNAT astfel încât conexiunile la ''PC-X'' portul ''666'' să ducă către acest serviciu ce rulează pe ''PC3''. |
- | * Rețeaua ''red'': ''10.44.$A.0/27'' | + | * Accesul la serviciu prin ''PC-X:666'' va trebui să fie funcțional din orice rețea (e.g., încercați să vă conectați de pe ''host'')! |
- | * Rețeaua ''green'': ''172.18.$B.64/28'' | + | * **Restricție:** este obligatoriu să folosiți DOAR iptables și/sau rutare (care ar trebui să fie deja configurată la ex. anterior) pentru a rezolva acest exercițiu, e.g., nu e voie să folosiți un serviciu auxiliar care să asculte pe portul ''666'' și să redirecționeze pachetele la ''PC3''! |
- | * Rețeaua ''blue'': ''172.18.$B.80/30'' | + | * //Hint: <color #EEE>unvecva ang</color>// folosiți ''tcpdump'' cu încredere când nu funcționează ceva ;) |
- | * Sistemul host va avea prima adresă asignabilă, iar containerul, pe cea de-a doua. | + | |
- | - Configurați rutarea IPv4 pentru a permite comunicarea între toate sistemele. Sistemele ''red'', ''green'' și ''blue'' vor avea ruta default prin sistemul ''host''. | + | |
- | - (**10 puncte**) Adresare IPv6 | + | |
- | - Configurați adrese IPv6 pentru întreaga rețea astfel: | + | |
- | * Rețeaua ''red'' ''2022:2:$A:$C::/64'' | + | |
- | * Rețeaua ''green'' ''2022:3:$B:$D::/64'' | + | |
- | * Rețeaua ''blue'' ''2022:4:$B:$E::/64'' | + | |
- | * Sistemul host va avea prima adresă asignabilă, iar containerul, pe cea de-a doua. | + | |
- | - Configurați rutarea IPv6 pentru a permite comunicarea între toate sistemele. Sistemele ''red'', ''green'' și ''blue'' vor avea ruta default prin sistemul ''host''. | + | |
- | - (**5 puncte**) Hosts | + | |
- | * Realizați configurațiile necesare astfel încât echipamentele să poată fi accesate prin numele lor (folosiți numele ''host'', ''red'', ''green'', respectiv ''blue''). Adăugați intrări de hosts doar pentru adresele IPv4. | + | |
- | - (**5 puncte**) Internet connectivity | + | |
- | * Realizați configurațiile necesare pentru ca cele 3 containere sa aibă acces la Internet. | + | |
- | * Configurați sistemul host astfel încât să facă translatarea doar pentru adresele IP configurate static pe interfețele containerelor, nu și pentru alte adrese din rețelele lor. | + | |
- | * **Observație**: adresa IP de pe ''eth0'' a sistemului ''host'' este asignată dinamic de către ISP, prin DHCP; configurarea trebuie realizată astfel încât conectivitatea la internet a containerelor să nu depindă de această adresă IP. | + | |
- | - (**5 puncte**) DNS server | + | |
- | * Configurați cele 3 containere pentru a putea accesa resurse din Internet pe baza numelor de domeniu al acestora (DNS). | + | |
- | * **Observație**: ''systemd-resolved'' a fost dezactivat peste tot, deci ar trebui să meargă tehnica clasică de editare ''/etc/resolv.conf'' ;) | + | |
- | - (**10 puncte**) Configurați **NAT** pe sistemul host astfel încât: | + | |
- | * Conexiunile pe porturile ''(21600 + $G)'', ''(21600 + $H)'', ''(18600 + $I)'', să conducă la conectarea ssh pe sistemele ''blue'', ''green'' respectiv ''red''. | + | |
- | * Conectarea pe portul ''(13700 + $K)'' să conducă la conectarea pe tracker-ul de pe sistemul ''green''. | + | |
- | - (**10 puncte**) Configurați **filtrarea** de pachete pe ''host'' astfel încât: | + | |
- | * conexiunile SMTP inițiate de pe sistemul ''red'' să fie blocate //(inclusiv către host!)//; | + | |
- | * conexiunile către tracker-ul ce rulează pe sistemul ''green'' să nu fie permise de pe ''host'' (decât prin port forward). | + | |
- | * blocați TOATE conexiunile trimise către ''blue'', mai puțin protocoalele ''icmp'', ''ssh'' și ''ftp''. | + | |
- | * **atenție**: NU blocați conexiunile inițiate de ''blue'' sau răspunsurile de la acestea! folosiți reguli **stateful**; | + | |
- | - (**5 puncte**) Configurați serviciul de **SSH** pe toate sistemele astfel încât: | + | |
- | * autentificarea cu utilizatorul ''student'' de pe oricare sistem să fie permisă pe toate celelate sisteme (tot în cadrul utilizatorului ''student'') folosind chei publice; | + | |
- | * folosind [[https://collectiveidea.com/blog/archives/2011/02/04/how-to-ssh-aliases/|alias-uri SSH]] să fie folosite comenzi simplificate pentru autenficarea pe sisteme: | + | |
- | * ''ssh h'' să ducă către sistemul ''host'' cu utilizatorul ''student''; | + | |
- | * ''ssh r'' să ducă către sistemul ''red'' cu utilizatorul ''student''; | + | |
- | * ''ssh g'' să ducă către sistemul ''green'' cu utilizatorul ''student''; | + | |
- | * ''ssh b'' să ducă către sistemul ''blue'' cu utilizatorul ''student''. | + | |
- | * **Observație**: ''ssh-copy-id'' utilizează autentificare ssh pe bază de parolă pentru a copia cheia. Mașina virtuală pe OpenStack nu permite astfel de autentificare pe ''host'', așadar veți fi nevoiți să autorizați cheia publică manual in fișierul corespunzător! | + | |
- | - (**10 puncte**) Căutare recursivă pe server HTTP cu autentificare | + | |
- | * Creați pe sistemul ''red'' scriptul ''/home/student/scripts/whereswaldo'' care să caute recursiv prin paginile de la ''http://host/.X/'' și să găsească fișierul ''waldo.txt'' (e.g., ''http://host/.X/sub/cale/waldo.txt''). | + | |
- | * Scriptul va trebui să afișeze DOAR conținutul paginii găsite! | + | |
- | * Va trebui să vă autentificați prin HTTP cu credențialele: | + | |
- | * //username//: ''ana'' | + | |
- | * //password//: ''face_ReLe'' | + | |
- | * Desigur, trebuie mai întâi să descoperiți ce tip de autentificare să folosiți! | + | |
- | - (**10 puncte**) Descărcare / încărcare fișiere prin ''ftp''. Pe sistemul ''host'': | + | |
- | * Realizați un script ''/root/scripts/ftp-upload'' care uploadează DOAR fișierele de forma ''[UVT][0-10000].txt'' ('U' sau 'V' sau 'T' urmat de un număr și extensia ''.txt'') din directorul curent la URL-ul ''ftp://red/upload/'', autentificându-se cu utilizatorul ''fs'' și parola ''talent+valoare''. | + | |
- | * Realizați un script ''/root/scripts/ftp-download'' care descarcă DOAR fișierele cu forma ''([a-zA-Z]+)-([0-9]+).tar.gz'' (adică orice șir de litere mici/mari, separatorul minus ('-'), un număr și extensia ''.tar.gz'') de la URL-ul ''ftp://red/download'' în directorul curent. Descărcarea se face în mod anonim, fără autentificare. | + | |
- | * **Notă:** Transferurile trebuiesc făcute în modul binar (și NU text)! | + | |
- | * Pentru testare, puteți să vă creați structurile necesare (checkerul face acest lucru automat). | + | |
- | - (**10 puncte**) Pe sistemul ''host'' este configurat un server de e-mail (SMTP): | + | |
- | * Pe sistemul ''green'', creați scriptul ''/root/scripts/sell-nft'' care să trimită un mesaj către ''contact@host'' ce va conține: | + | |
- | * subiectul ''Cumpara NFTuri cu RR'' | + | |
- | * prima linie tipărită din argumentul primit de script; | + | |
- | * pe a doua linie a mesajului, un hash ''sha256'' al atașamentului; | + | |
- | * atașament cu fișierul ''rr.jpeg'' preluat din directorul curent de unde este rulat scriptul. | + | |
- | - (**5 puncte**) Pe sistemul ''host'', creați un set de reguli de firewall pentru **BLOCAREA** și **jurnalizarea** acceselor lui ''blue'' asupra serviciului ''telnet'' de pe sistemul ''green''. | + | |
- | * Aceste reguli trebuie să genereze mesaje syslog pentru fiecare pachet blocat, ce vor fi salvate în fișierul ''/var/log/insecure.log''. | + | |
- | * Mesajele trebuie prefixat de șirul ''"insecure-telnet: "''. | + | |
- | * **Hint:** rsyslog | + | |
- | - (**5 puncte**) Pe sistemul ''red'', creați un script ''/root/scripts/check-port'' care va primi, ca prim argument, numărul unui port TCP (1-65535), și va scrie, la stdout, textul ''"adevarat"'' dacă acel port este deschis pe ''host'' (**inclusiv IPv6!**) si ''"nah"'' în caz contrar. | + | |
- | - (**Bonus - 10 puncte**) Wireguard tunnelling | + | |
- | * Configurați un tunel Wireguard între ''green'' și ''blue''. | + | |
- | * Denumiți interfețele de tunel ''wg-rl'' pe ambele capete. | + | |
- | * Folosiți rețeaua IPv6 ''2022:0:$F::/64'' pentru capetele tunelului (''green'' va avea a prima adresă IP asignabilă, ''blue'' pe cea de-a doua). | + | |
- | * //Hint//: nu uitați să activați rutarea! | + | |
- | - (**Bonus - 15 puncte**) Advanced port forwarding | + | |
- | * Pe stația ''blue'' va fi pornit un serviciu special pe portul TCPv6 ''9944'' care va asculta DOAR pe capătul de tunel wireguard creat anterior (checkerul îl va porni automat; pentru testare puteți folosi ''nc'' cu argumentul ''-s'', trebuie să puteți trimite mesaje bidirecționale prin portul forwardat). | + | |
- | * Configurați firewallul pe ''green'' (aveți iptables instalat) pentru a realiza DNAT astfel încât conexiunile la ''green'' portul ''44'' să ducă către acest serviciu ce rulează pe ''blue''. | + | |
- | * Accesul la serviciu prin ''green:44'' va trebui să fie funcțional din orice rețea (e.g., încercați să vă conectați de pe ''host'' sau ''red'')! | + | |
- | * **Restricție:** este obligatoriu să folosiți DOAR ''iptables'' pentru a rezolva acest exercițiu. E.g., nu e voie să folosiți un serviciu auxiliar care să asculte pe portul ''44'' și să redirecționeze pachetele la ''blue''! | + | |
- | * //Hint:// Folosiți ''tcpdump'' cu încredere ;) | + | |