Caricare documenti e articoli online 
INFtub.com è un sito progettato per cercare i documenti in vari tipi di file e il caricamento di articoli online.


 
Non ricordi la password?  ››  Iscriviti gratis
 

Cosa sono le porte TCP/IP

informatica



Cosa sono le porte TCP/IP Una qualsiasi macchina, per presentarsi sulla rete Internet, deve avere un indirizzo TCP/IP attivo. Che sia esso dinamico, quindi assegnato da un provider o da un server DHCP, o statico, quindi attribuito in modo fisso all'atto della configurazione del protocollo, non importa, l'importante è che esista. Oltre all'indirizzo, ognuna di queste macchine ha poi una serie di porte disponibili ad essere interrogate. Ma vediamo esattamente cosa sono tali porte. Immaginiamo che un indirizzo TCP/IP sia una via di una grande città. In tale vi 929f52j a vi sono N abitazioni. Ognuna di queste abitazioni ha un proprio numero civico al quale possiamo bussare per verificare l'esistenza di una certa persona.  Essendo il numero civico l'elemento di distinzione fra le diverse abitazioni, sulla stessa via possiamo identificare, in modo certo, le diverse persone che vi abitano. Allo stesso modo su un computer, identificato da un indirizzo TCP/IP, possiamo distinguere fra i diversi server che vi sono montati, in quanto rispondono a porte TCP/IP diverse. Esistono anche quelli che sono dei default. Ad esempio un server WEB risponde normalmente sulla porta 80, un servizio telnet sulla 23 e un FTP alla 21. Per sapere quali sono i default più utilizzati, provate a prendere, dalla vostra directory Windows, il file SERVICES. In tale file sono presenti alcuni di quelli che sono i default maggiormente diffusi. Si parla di default infatti perché nessuno ci vieta di montare un server telnet su una porta diversa dalla 23. Il server sicuramente funzionerà, ma occorrerà avvisare i client, che verranno utilizzati per la connessione, che il server è montato su una porta diversa da quella standard.  La tecnica del cambio della porta di default può risultare molto utile contro eventuali attacchi alla rete da parte di hacker alle prime armi, che non controllano tutte le porte di una certa classe di indirizzi, ma soltanto quelle di default. In questo modo un'eventuale incursione, o comunque un'eventuale scansione di una rete tramite le porte standard non porterebbe a nessun risultato.



Figura 1 - Single IP port scanner


Esistenza di una porta attiva Una volta compreso il perché esistano porte diverse che controllano l'attività dei vari servizi Internet, vediamo come sia possibile costruire un semplice programma Java in grado di controllare se ad una porta risponde un determinato server, oppure se su una certa porta non è installato nessun programma.

echo, 7 ftp-data, 20 ftp, 21 telnet, 23 smtp time, 37 name, 42 bootp tftp finger, 79 http, 79 pop3, 110 nntp, 119 login, 513 printer, 515 route, 520

Per effettuare questo controllo occorre, prima di tutto, conoscere l'esistenza della classe Socket, del package java.net. Tale classe è in grado di attivare una connessione remota, con una determinata macchina su una determinata porta. Per tale ragione si rivela molto utile ai nostri scopi.  Le righe di codice che andremo a scrivere, per effettuare la connessione saranno pertanto le seguenti:

String cIP = "192.168.0.1"; int nPort = 23; Socket test = new Socket( cIP, nPort );

dove con cIP viene identificato l'indirizzo IP della macchina che vogliamo controllare e nPort la porta alla quale vogliamo accedere. L'unico problema che possiamo incontrare, durante l'esecuzione di questo codice, è dato dal fatto che il costruttore della classe Socket potrebbe generare un'eccezione. Se infatti guardiamo il sorgente di tale costruttore:

public Socket(String host, int port) throws UnknownHostException, IOException

possiamo notare che vengono generate due eccezioni. La prima di tipo UnknowHost che identifica il fatto che la macchina che stiamo cercando di controllare non esiste o non è raggiungibile con la nostra configurazione TCP/IP e la seconda di tipo IO, cioè di trasmissione dati.  Per poter catturare queste due eccezioni, evitando che il nostro programma vada in errore, basterà semplicemente impostare un try ... catch. In questo caso però, dato che non ci servono dei dettagli sul perché è accaduto l'errore, possiamo scrivere del codice completamente generico che in una sola catch riesca a gestire tutte le casistiche d'errore. Tale codice sarà così composto:

try catch(Throwable e)

Al posto di gestire due catch specifiche sulle eccezioni UnknownHostException e IOException, generate da Socket, possiamo semplicemente gestirne una sulla classe Throwable. Tale classe è la base di tutte le eccezioni e pertanto, qualsiasi sia quella generata, sicuramente verrà catturata da questa catch generica. Il cuore del programma di port scanner è finalmente pronto. Se infatti la connessione tramite Socket non genererà nessun errore, vorrà dire che la porta esiste ed è attiva, in caso contrario vorrà dire che quella porta non è attiva, o che esiste un firewall, dal quale siamo costretti a passare, che ci preclude l'utilizzo della porta che stiamo controllando. È infatti possibile che, fra la nostra macchina e il range di macchine sulle quali stiamo attivando una scansione, esista un firewall, che controlli quale porte sono disponibili all'accesso tramite Internet e quali no. È possibile quindi che, pur essendo attiva una determinata porta, il nostro calcolatore non sia in grado di controllarla, in quanto la richiesta di accesso arriva da un indirizzo IP non riconosciuto e pertanto viene bloccata ancora prima di raggiungere la macchina da controllare.

Figura 2 - Class C port scanner


Scansione di un range di porte Proviamo ora a potenziare la scansione che abbiamo costruito fino a questo momento aggiungendo, prima di tutto, la gestione di un'intera classe C di indirizzi e successivamente incapsulando il codice all'interno di un thread. In questo modo sarà possibile parallelizzare più processi. Con classe C si identifica quel gruppo di indirizzi che hanno uguale radice numerica. Facendo conto che una determinata macchina abbia l'indirizzo 192.168.0.100, le macchine, facenti parte della sua Classe C di indirizzi, sono tutte quelle comprese fra 192.168.0.1 e 192.168.0.255. Per modificare il programma, in modo che sia in grado di gestire l'intera classe, effettueremo solamente una piccola variazione all'indirizzo da controllare, facendo in modo che tale indirizzo diventi dinamico:

String cIP = "192.168.0."; int nPort = 23; for( int nClassC=0; nClassC<=255; nClassC++ ) catch ( Throwable e )

In questo caso viene sfruttata una caratteristica di Java che ci permette di sommare ad una stringa un valore intero. La somma fra queste due tipologie di dati subisce infatti una conversione automatica del valore int in una stringa. È per questa ragione che, sommare un oggetto String ad uno di tipo int, non porta a nessun errore, a differenza di molti altri linguaggi di programmazione. A questo punto siamo in grado di effettuare una scansione di un'intera classe C, sulla porta 23, o su una qualsiasi altra porta che decideremo di andare a controllare. Il problema che ci si pone ora di fronte è quello, inevitabile, delle performance. Un algoritmo del genere è sicuramente funzionante, ma pecca di velocità. Infatti la creazione dell'oggetto Socket blocca completamente il programma, che rimane in attesa di "un segnale di vita" da parte della macchina che si sta tentando di raggiungere. Perché allora dobbiamo perdere tutto questo tempo, nell'attesa che qualcuno ci risponda? Perché non possiamo parallelizzare più processi, in modo da sfruttare a pieno la potenza elaborativa della macchina che stiamo utilizzando? Per poter andare incontro a quest'esigenza java ci mette a disposizione una classe del package java.lang che fa esattamente al caso nostro. Tale classe è Thread. Gli oggetti Thread hanno infatti una caratteristica molto importante che è quella di non bloccare il programma nel quale sono eseguiti. Viene creato un processo parallelo che entra in esecuzione insieme alla parte di codice nella quale è stato creato. Per chi ha lavorato col linguaggio C su piattaforme UNIX, l'effetto é esattamente uguale a quello provocato da una fork(). Per incapsulare la scansione su un Thread siamo però costretti a creare una piccola classe che conterrà, al suo interno, il singolo controllo di porta. Tale classe ha però una caratteristica molto importante, che è data dal metodo che ne determinerà l'attivazione. Tale metodo si chiama run() e sarà il metodo che dovremo sovrascrivere, inserendo al suo interno il codice di scansione. Il risultato che otterremo sarà quindi:

public class checkSingleIP extends Thread

public void run()    catch ( Throwable e )

Ora, per poter attivare il singolo processo di controllo IP, dovremo semplicemente creare un oggetto della classe checkSingleIP e mandarlo in esecuzione tramite il metodo start che a sua volta chiamerà il metodo run che siamo andati ad implementare nella nostra classe. Nel main della classe principale andremo così a fare un richiamo alla classe checkSingleIP:

checkSingleIP ip     new checkSingleIP( "192.168.0.1", 23 ); ip.start

A questo punto il programma è sufficientemente veloce e ci assicura una buona affidabilità nella scansione di una rete di indirizzi TCP/IP. In realtà, esiste un problema rappresentato dal numero massimo di connessioni socket che la macchina sulla quale si esegue il programma può supportare. Su alcuni sistemi operativi, se andiamo oltre una certa soglia di socket attivi, il programma non è più in grado di effettuare la connessione e genera un'eccezione, ancora prima di aver tentato una connessione con la macchina remota. 

Figura 3 - Port Listener


Conclusioni Costruire un port scanner è un'operazione molto semplice. Il difficile risiede solo nel fatto di rendere efficace l'algoritmo di scansione, tramite l'aggiunta di algoritmi che ne possano aumentare l'efficacia o tramite l'aggiunta di accorgimenti che ne possano parallelizzare i processi. I thread ci permettono fortunatamente la programmazione concorrente ed in questo caso hanno aiutato molto nella costruzione di un programma performante. Esistono però molti altri ambiti applicativi, nei quali è possibile utilizzare tale tecnica, come ad esempio i Socket Server. Attenzione però a non attivare troppi processi all'interno di una macchina, in quanto essi potrebbero rallentare a





Privacy




Articolo informazione


Hits: 5081
Apprezzato: scheda appunto

Commentare questo articolo:

Non sei registrato
Devi essere registrato per commentare

ISCRIVITI



Copiare il codice

nella pagina web del tuo sito.


Copyright InfTub.com 2024