Come monitorare un server Node.js via telnet

Iniziamo col tranquillizzare il lettore: la parola "telnet" nel titolo non deve assolutamente spaventarci. Anche se usiamo Node.js da poche settimane e conosciamo solamente le nozioni rudimentali di JavaScript, siamo sicuramente in grado di trarre vantaggio da una connessione telnet. Questo articolo spiega come procedere passo passo e dovrebbe essere comprensibile anche dai meno esperti. Prima di entrare nei dettagli spieghiamo perche puo risultare conveniente usare una connessione telnet per monitorare un server remoto.

Iniziamo col tranquillizzare il lettore: la parola “telnet” nel titolo non deve assolutamente spaventarci. Anche se usiamo Node.js da poche settimane e conosciamo solamente le nozioni rudimentali di JavaScript, siamo sicuramente in grado di trarre vantaggio da una connessione telnet. Questo articolo spiega come procedere passo passo e dovrebbe essere comprensibile anche dai meno esperti. Prima di entrare nei dettagli spieghiamo perché può risultare conveniente usare una connessione telnet per monitorare un server remoto.

Consideriamo il seguente scenario: abbiamo messo in piedi un piccolo server con Node.js e vogliamo gestirlo o amministrarlo in remoto. Se stessimo lavorando con un linguaggio di programmazione di pagine dinamiche (come ad esempio PHP), potremmo inserire una pagina di autenticazione che permetta l’accesso all’applicazione in qualità di amministratore. Quando lavoriamo con Node.js, un sistema di questo tipo è piuttosto complesso. Se la nostra esigenza è solo quella di fare delle prove di collegamento, ovvero eseguire dei test o semplicemente monitorare lo stato del server, potrebbe bastare una semplice pagina di informazioni, raggiungibile su un URL ben preciso. Anche se non divulghiamo l’indirizzo dell’URL di questa pagina, di fatto esso resterebbe comunque pubblico. Chiunque faccia una ricerca su Internet potrebbe trovare questo URL come esito della ricerca.

Un sistema via telnet è generalmente più facile da chiudere al pubblico, anche senza conoscenze specifiche. Il vantaggio rispetto alla pagina Web è che la connessione telnet usa un protocollo diverso. Per fare qualche esempio, quando navighiamo da una pagina all’altra di solito usiamo il protocollo HTTP, se invece ci colleghiamo attraverso un client FTP usiamo il protocollo FTP. Una connessione via telnet usa un altro protocollo, che per semplicità possiamo chiamare semplicemente TELNET. Trattandosi di un protocollo diverso da HTTP e FTP possiamo restringere (ad esempio via Plesk) gli indirizzi che hanno accesso al protocollo: in questo modo solamente noi (dell’indirizzo IP che dichiariamo) avremo accesso alla connessione telnet.

Se l’argomento qui sopra è troppo complesso, o non descrive la nostra situazione, non preoccupiamoci. Possiamo comunque usare telnet temporaneamente, come strumento di verifica e collaudo, senza preoccuparci della sicurezza della connessione. Lo snippet che vedremo nelle prossime pagine potrebbe servire semplicemente a verificare se riusciamo a connetterci al server remoto da un’altra macchina (ad esempio il nostro PC di casa). La connessione via telnet è un modo molto semplice di monitorare alcune variabili del server remoto, senza dover sviluppare delle pagine Web dedicate al monitoraggio.

L’altro vantaggio riguarda il debug del codice. Lavorando con Node.js spesso dobbiamo configurare diversi moduli, i quali potrebbero aver bisogno di dialogare tra loro aprendo connessioni simili ad una connessione telnet. Sapere come collaudare e verificare la bontà di queste connessioni può risultare utile. Come vedremo tra poco bastano davvero poche righe di codice per mettere in piedi un sistema di comunicazione tra client e server basato sul protocollo telnet.

Il codice Node.js

Il codice Node.js

Come promesso in apertura dell’articolo, spieghiamo passo passo qual è la procedura, evitando di scendere nei dettagli tecnici a favore dei lettori meno esperti. Per lavorare con telnet ci basta saper aprire il prompt dei comandi su Windows o la finestra della shell su Linux. Questi sono strumenti dobbiamo conoscere comunque per lavorare con Node.js. Qualunque sia il nostro sistema operativo, per comodità faremo riferimento a finestre di questo tipo usando il termine generico “shell”.

Passiamo adesso al codice Node.js del server, copiandolo da qui sotto e incollandolo all’interno di un file che per comodità chiameremo “server.js”.

nella realtà la funzione status() conterrà il codice che fornisce le informazioni che ci interessano. L’implementazione della funzione status() non riguarda perciò la conoscenza del protocollo telnet: essa potrebbe essere realizzata anche scrivendo una serie di istruzioni del tipo console.log, per scrivere sullo schermo le variabili del server che vogliamo monitorare.

L’unica vera novità introdotta dal codice qui sopra dovrebbe essere l’uso del modulo “repl”. La sigla REPL può essere praticamente considerata sinonimo di “shell”, ciò indica un qualunque ambiente dove abbiamo una console dei comandi che permette di lavorare in maniera interattiva. In altre parole, anche il banale prompt dei comandi di Windows è un sistema di tipo REPL.

Quando invochiamo il metodo start sulla variabile shell apriamo, com’è logico aspettarsi, una nuova shell. Se non precisiamo alcun argomento la nuova finestra avrà il prompt di default e accetterà dati dalla tastiera, che in questo caso è il flusso (cioè lo “stream”) di default. Se invece precisiamo altri argomenti, ad esempio

stiamo definendo un prompt diverso da quello classico, che in questo caso sarà “Server:remote>”. Come secondo argomento passiamo la variabile socket, creata dal modulo “net”. Siccome non ci interessano i dettagli ci basta sapere che in questo modo stiamo dicendo alla shell che il suo input non è più la tastiera, ma una connessione via rete. In particolare la nuova shell accettarà dati in ingresso (cioè i comandi) proprio da una connessione remota. Siccome diciamo al server di restare in ascolto sulla porta 5010, il codice qui sopra crea un server telnet che permette all’utente di collegarsi su questa porta.

Con questo il codice lato server è finito. Passiamo adesso alla pratica, provando a collegarci da un client remoto.

Prova di collegamento

Prova di collegamento

Per collaudare il server realizzato a pagina precedente procediamo nel seguente modo. Innanzitutto eseguiamo il server, lanciando il comando node server.js. Dopodiché, per simulare la connessione del client apriamo un’altra shell (ad esempio un altro prompt dei comandi) che svolgerà il ruolo di client. Per connettere il client al server basterà digitare il comando telnet localhost 5010. Se lavoriamo con Windows dovremmo trovarci in una situazione come quella di figura 1.

telnet_01

Figura 1 – Finestra del server e finestra del client

Dopo esserci connessi possiamo provare a digitare il comando status() su una qualsiasi delle due finestre. In ogni caso il risultato dovrebbe essere il seguente

Se infatti guardiamo al codice di pagina precedente vedremo che abbiamo aggiunto la funzione status alla shell, usando l’istruzione

a questo punto dovremo notare che in realtà abbiamo eseguito un’istruzione di questo tipo due volte, perché abbiamo anche scritto

Questo perché lo snippet di pagina precedente crea due console, ovvero inizializza due shell: una locale e una remota. Quella remota è disponibile solo quando ci colleghiamo da un’altra finestra, usando il protocollo telnet. Quella locale invece è disponibile direttamente sul server, quando eseguiamo lo snippet Node.js. Quest’ultima shell non è strettamente necessaria se vogliamo usare lo snippet per monitorare il server da remoto: l’abbiamo inserita a scopo didattico, per mostrare come cambia il comportamento del modulo REPL quando precisiamo un flusso d’ingresso diverso. Nel nostro caso le due shell si distinguono proprio dal flusso d’ingresso: la shell remota accetta in ingresso la connessione telnet, mentre quella locale accetta in ingresso i dati provenienti dalla tastiera.

Con questo abbiamo finito. Come accennato, la funzione status andrebbe arricchita aggiungendo il codice che vogliamo monitorare. In questo modo possiamo eseguire la funzione status da una qualsiasi macchina remota, esattamente come se fossimo sul server. Come già detto, ai fini della sicurezza, questo è possibile solamente se il server remoto accetta in ingresso connessioni di tipo telnet. Questo aspetto solitamente dipende dalla configurazione del provider: se non abbiamo accesso a tale configurazione la connessione telnet potrebbe essere disabilitata. In altre parole: se non possiamo configurare accessi di tipo telnet, lo snippet di pagina precedente dovrebbe essere del tutto innocuo. Conclusioni

Lo snippet di pagina precedente usa due volte l’oggetto shell ritornato dal modulo “repl”. Ciò significa che l’istruzione di import del modulo, oltre a rendere accessibile il modulo “repl”, si occupa anche di creare l’oggetto che rappresenta la shell, tramite l’istruzione

se guardiamo al codice, vedremo che eseguiamo il metodo start su quest’oggetto due volte: la prima volta per la variabile local, la seconda volta per la variabile remote. Queste due variabili sono quindi “imparentate” perché create eseguendo lo stesso metodo start sullo stesso oggetto shell. Ciò suggerisce che le due shell (locale e remota) non siano indipendenti: possiamo verificarlo creando una variabile da una parte (scrivendo ad esempio “a=12”) e poi visualizzando la stessa variabile dall’altra parte (scrivendo ad esempio “a+2”).

La conclusione è che le due shell sono connesse e quindi permettono di condividere dati e funzioni. È proprio in virtù di questo meccanismo che possiamo monitorare, da una macchina remota, qualsiasi variabile esistente nell’ambiente Node.js. Le potenzialità sono moltissime e vale la pena fare qualche prova: anche se non useremo mai telnet come protocollo per monitorare la macchina remota, è sempre utile essere in grado di verificarne il funzionamento.