This shows you the differences between two versions of the page.
rl:labs:08:contents:10 [2020/12/01 10:43] iulia.florea removed |
rl:labs:08:contents:10 [2024/10/29 14:41] (current) eduard.dumistracel [10. [10p] Tunel SSH invers] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ==== 10. [5p] Blocare servicii necriptate ==== | + | ==== 10. [10p] Tunel SSH invers ==== |
- | 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. | + | Sunt situații în care dorim ca o stație să fie accesibilă din exterior, dar este dificil să obținem un port în gateway (pentru //port forwarding//): fie din rațiuni administrative, fie din motive de securitate. Pentru a permite totuși o conexiune din exterior, se poate crea un tunel SSH invers. Tunel SSH invers înseamnă următorii pași: |
+ | * se creează o conexiune SSH de la o stație cu adresă IP privată la un server extern cu adresă IP publică, | ||
+ | * se deschide un port pe serverul cu adresă IP publică | ||
+ | * traficul către acel port este tunelat prin conexiunea SSH către stația cu adresă IP privată | ||
- | 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''. | + | Dorim să permitem conectarea la stația ''red'' din Internet pe SSH. Vom crea o conexiune SSH "directă" de la stația ''red'' la contul vostru de pe ''fep.grid.pub.ro''. Prin această conexiune veți tunela invers traficul SSH către ''red'' permițând conexiunea din exterior. |
- | <spoiler Prezentare scurtă iptables (dați click)> | + | Pentru început, de pe stația ''red'' creăm o conexiune SSH directă către contul de pe ''fep.grid.pub.ro'' (identic cu cel de pe ''cs.curs.pub.ro''): |
- | ''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: | + | <code bash> |
- | * acceptarea pachetului (''ACCEPT'') | + | root@red:~# ssh -l $USERNAME fep.grid.pub.ro -R 100XY:localhost:22 |
- | * 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 | + | $USERNAME@fep.grid.pub.ro's password: |
+ | Last login: Mon Sep 9 09:55:37 2013 from 141.85.225.214 | ||
+ | [$USERNAME@fep-62-2 ~]$ ss -tln | grep 100XY | ||
+ | tcp 0 0 127.0.0.1:100XY 0.0.0.0:* LISTEN | ||
+ | tcp 0 0 ::1:100XY :::* LISTEN | ||
+ | </code> unde ''$USERNAME'' este numele contului de pe ''fep.grid.pub.ro''/''cs.curs.pub.ro'', iar ''XY'' este un identificator numeric unic al stației din laborator (dacă nu aveți pe monitorul stației din laborator un identificator discutați cu asistentul). Introduceți parola corespunzătoare contului vostru de pe ''fep.grid.pub.ro''/''cs.curs.pub.ro''. | ||
- | O diagramă a drumului urmat de un pachet de rețea în nucleu este [[https://commons.wikimedia.org/wiki/File:Diagrama_linux_netfilter_iptables.png|aici]]. | + | Observăm că se deschide portul ''100XY'' pe ''fep.grid.pub.ro''. Acest port va fi folosit pentru tunelul invers care ne va duce pe stația ''red''. |
- | Comanda ''iptables'' înseamnă lucrul cu reguli de filtrare de la nivelul nucleului. În mod obișnuit se va preciza: | + | Argumentul ''-R 100XY:localhost:22'' transmis comenzii ''ssh'' are următoarea semnificație: |
- | * tipul de operație pe regulă (adăugare, ștergere, înlocuire, inserare) | + | * ''100XY'' - portul de pe server pe care se vor asculta conexiuni care vor fi tunelate invers; |
- | * punctul din nucleul în care trebuie să se găsească pachetul pentru a se aplica regula | + | * ''localhost'' - stația către care vor fi trimise pachetele primite prin tunel (chiar stația locală); |
- | * regula în sine | + | * ''22'' - portul către care vor fi trimise pachetele primite prin tunel (adică portul SSH local). |
- | De exemplu, comanda de mai jos are semnificația descrisă în continuare:<code bash> | + | După ce alți colegi rulează comenzile similare vă veți putea conecta pe stația ''red'' a acestora folosind portul deschis de ei; discutați cu alți colegi ca să vă spună ce port au deschis. Pentru aceasta, veți folosi stația fizică și vă veți conecta pe contul de pe ''fep.grid.pub.ro''. |
- | iptables -A FORWARD -d green -p tcp --dport telnet -j REJECT | + | |
- | </code> | + | |
- | * ''-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). | + | <note important> |
- | </spoiler> | + | Pe ''fep.grid.pub.ro'' rulează un load balancer pentru SSH. Din acest motiv este posibil să intrați pe "celălalt" sistem. Verificați că numele de host din prompt corespunde cu cel pe care l-ați folosit inițial la crearea tunelului: adică ambele să fie ''fep-62-2'' sau ''fep-62-1''. Pentru siguranță folosim și comanda ''ss'':<code bash> |
- | + | [$USERNAME_COLEG@fep-62-2 ~]$ ss -tln | grep 100ZT | |
- | 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.<code bash> | + | tcp 0 0 127.0.0.1:100ZT 0.0.0.0:* LISTEN |
- | root@host:~# iptables -A FORWARD -d green -p tcp --dport telnet -j REJECT | + | tcp 0 0 ::1:100ZT :::* LISTEN |
</code> | </code> | ||
- | + | În output-ul comenzii de mai sus ''100ZT'' este portul deschis de coleg. | |
- | Pentru a verifica adăugarea regulii de mai sus, rulați pe stația ''host'' comanda<code bash> | + | |
- | 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 | + | |
- | </code> | + | |
- | + | ||
- | Pentru a afișa informații și despre pachetele prelucrate și interfețele folosite, rulați pe stația ''host'' comanda<code bash> | + | |
- | 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 | + | |
- | </code> | + | |
- | + | ||
- | 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<code bash> | + | |
- | 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 | + | |
- | </code> | + | |
- | 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<code bash> | + | |
- | telnet green | + | |
- | </code> | + | |
- | + | ||
- | Vă apare un mesaj de forma<code> | + | |
- | Trying 192.168.2.2... | + | |
- | telnet: Unable to connect to remote host: Connection refused | + | |
- | </code> 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<code bash> | + | |
- | 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 | + | |
- | </code> | + | |
- | 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<code bash> | + | |
- | ftp green | + | |
- | ssh -l student green | + | |
- | </code> | + | |
- | + | ||
- | 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. | + | |
- | + | ||
- | <note tip> | + | |
- | 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''. | + | |
</note> | </note> | ||
- | De pe stația ''red'' verificați blocarea traficului FTP către stația green folosind comanda<code bash> | + | După conectarea colegului la ''fep'', realizăm o conexiune prin tunelul SSH pe portul ''100ZT'' deschis de coleg:<code bash> |
- | ftp green | + | [$USERNAME_COLEG@fep-62-2 ~]$ ssh -l student localhost -p 100ZT |
+ | Warning: Permanently added '[localhost]:100ZT' (RSA) to the list of known hosts. | ||
+ | root@localhost's password: | ||
+ | [...] | ||
+ | root@red:~# | ||
</code> | </code> | ||
+ | În cadrul conexiunii ni se cere parola utilizatorului ''root'' de pe stația ''red'' (adică parola ''student''). | ||
- | <hidden> | + | În final ați accesat stația ''red'' a colegului, o stația cu adresă IP privată inaccesibilă din exterior. Pentru aceasta ați folosit o altă stație (care ar putea fi din altă rețea) pentru a se conecta la ''fep.grid.pub.ro'' și de acolo la ''red'' prin intermediul tunelului invers creat inițial. |
- | <solution> | + | |
- | <code bash> | + | |
- | 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 | + | Creați un fișier pe stația ''red'' proaspăt accesată, iar colegul poate verifica faptul că, într-adevăr, ați accesat container-ul său prin tunelul SSH invers pe care l-a creat anterior. |
- | ^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 | + | |
- | </code> | + | |
- | </solution> | + | |
- | </hidden> | + |