Monthly Archives: gennaio 2016

Come mantenere attive le nostre connessioni ssh

Come mantenere attive le nostre connessioni ssh? A volte capita di venire disconnessi da un server SSH remoto se si utilizza la connessione per qualche minuto. Per evitare ciò, è possibile configurare il nostro client SSH (file /etc/ssh/sshd_config) con le seguenti opzioni:

Host * 
Protocol 2 
ServerAliveinterval 60

La prima linea indica che la direttiva ServerAliveinterval sarà applicata verso tutti i server SSH; se invece viene specificato un nome di host specifico le impostazioni seguenti saranno valide solo per quel server SSH. La seconda linea indica che devono necessariamente essere stabilite connessioni SSH v2, in quanto la direttiva funziona solo con tale versione del protocollo.
La terza linea specifica la direttiva ServerAliveinterval, non presente nelle configurazioni di default, la quale prevede l’invio al server SSH di un pacchetto attraverso il canale criptato dopo un numero specificato di secondi di inattività, richiedendo una risposta. Tale sincronizzazione evita ogni problema di disconnessione automatica. Da notare che alcuni server SSH utilizzano comunque l’opzione TCPKeepAlive che prevede l’invio, dal server SSH al client, di un pacchetto TCP dopo un tempo fissato di idle, tipicamente due ore, ma la direttiva lato client che abbiamo impostato risulta più idonea allo scopo.

La potenza di lsof

Dopo aver parlato del comando fuser, ecco un altro interessante comando utilizzato per individuare file aperti, e non solo. lsof è un comando molto complesso: per una completa trattazione vi rimandiamo alla man page.
In particolare, secondo l’ormai nota implementazione di ogni sistema UNIX, dove ogni cosa (per esempio pipe, directory, device, i-node e socket) viene trattata come se fosse un semplice file, il comando lsof, eseguito senza parametri, restituisce tutti i file aperti da qualsiasi programma correntemente in esecuzione.
Per restringere tale output (che omettiamo per mancanza di spazio) a quei processi posseduti da uno specifico utente, è possibile utilizzare l’opzione -u, come mostrato in quest’esempio

lsof -u m4xp0w3r 
    COMMAND PIO FD TYPE DEVICE NODE     NAME 
sshd     2354 mem REG     254,0     105723  /lib/libcap.so.1.10 
sshd     2354 DEL REG     0,8     127123574 /dev/zero 
bash     2363 cwd DIR     254,4     7274497 /home/m4xp0w3r
bash     2363 txt REG     254,0     4126    /bin/bash 
bash     2363 mem REG     254,0     105698  /lib/ld-2.5.so

Di seguito si riportano alcune note sulle informazioni meno comprensibili riportate in queste diverse colonne di output che dovrebbero poi essere integrate dalla vostra curiosità.
La colonna FD mostra le informazioni circa il file descriptor associato al processo: ad esempio la stringa cwd indica la directory di lavoro corrente mentre la stringa mem indica una risorsa presente in memoria.
La colonna TYPE riporta informazioni circa il tipo di file: ad esempio la stringa REG indica un file regolare (normale) mentre la stringa DIR una directory del filesystem.
La colonna DEVICE riporta il device associato al processo (rispettivamente major-number, minor-number) mentre la colonna NODE può essere utile se si sta tentando di recuperare un file cancellato.
Il comando lsof <filename> mostra quali processi hanno dei file aperti con il nome specificato mentre lsof +D <dir> mostra quali processi hanno dei file aperti nella directory specificata. Entrambe le opzioni, ed in particolare quest’ultima, possono essere molto utili se ad esempio si sta tentando di smontare un filesystem senza successo a causa di un messaggio di errore del tipo filesystem in use.

Altre utilizzi tipici possono essere:

lsof -e <processname>

mostra tutti i processi che corrispondono o che iniziano con la stringa specificata i quali hanno file aperti.

lsof -i

mostra tutte le informazioni in riferimento a socket IP. In particolare quest’ultima modalità ci consente di individuare eventuali problemi di sicurezza piuttosto che semplicemente monitorare l’attività dei nostri server in rete.
Ad esempio, in combinazione con il comando watch, è possibile monitorare in tempo reale, di default ogni 2 secondi (CTRL+C per uscire). cosa stia accadendo al nostro server web (porta 80) in questo modo:

watch lsof -i :80

Tramite questo comando è quindi possibile individuare quali host stanno accedendo il nostro server web, mentre attraverso il comando:

lsof -i@<hostname_or_ip_address>

è possibile controllare tutte le connessioni di un particolare host alla nostra Linux Box, come mostrato dal seguente output semplificato (dove viene individuata una sola connessione SSH effettuata dal client 192.168.0.2):

COMMAND PID TYPE NAME 
sshd 10128 IPv6 192.168.O.1: ssh->192.168.O.2:1735

Infine è possibile recuperare informazioni simili, relativamente ai socket UNIX aperti sulla nostra Linux Box, mediante l’opzione -U.
Si ricorda che i socket UNIX sono utilizzati per gestire la comunicazione inter-processo, dove, in altre parole, il concetto di rete (relativo ai socket IP) è sostituito dalla singola macchina locale.
Questa opzione spesso viene utilizzata in combinazione con il comando strace quando si sta tentando di tracciare dei bug di sistema a basso livello.

La potenza di fuser

Talvolta può essere estremamente utile, ad esempio in pre­senza di errori del tipo device is busy, individuare quali pro­cessi stiano accedendo ad un particolare file o filesystem. Per ottenere ciò è sufficiente utilizzare il comando fuser nella sua più banale forma, come ad esempio:

fuser filename.txt 
/home/m4xp0w3r/filename.txt: 12768

Questo numero (12768) non è altro che l’ID del processo che sta accedendo al file specificato.Tramite l’opzione -u è possibile determinare l’owner del processo, ad esempio:

fuser -u /var/run/sendmail.pid 
/var/run/sendmail.pid: 2507 (root)

Per ottenere altre informazioni sull’operazione in corso, è possibile utilizzare l’opzione -v del comando ottenendo ad esempio:

fuser -v auth.log
                     UTENTE      PID ACCESSO COMANDO
/var/log/auth.log:   syslog     1058 F.... rsyslogd

Questo comando mostra l’utente proprietario del processo, l’ID del processo, come il file sia stato acceduto (in questo caso la lettera f indica che il file è aperto) e il comando che è stato utilizzato per accedervi, in questo caso un semplice more.
Inoltre, per terminare tutti quei processi che accedono un particolare file, è possibile utilizzare l’opzione -k in questo modo (se desiderato, in congiunzione con l’opzione -i, verrà richiesta conferma per ogni kill che verrà eseguito):

fuser -k filename.txt

Per quello che riguarda i filesystem, è necessario utilizzare il comando con l’opzione -m, che restituisce qualcosa del tipo:

fuser -m /dev/sdal 
/dev/sdal: 2935rce 2968m 2984rce 3014rce 3015rce 3063rce 3066rce 3068rce [ ... ] 3356rce 10054rce 10055rce 1013lrce 1024lm 10293rc

La maggior parte di questi processi accedono la directory corrente (lettera e), sono in esecuzione (lettera c) e coinvolgono directory di root (lettera r) mentre altri stanno utilizzando shared library o memory-mapped file (lettera m). Infine è anche possibile utilizzare il comando fuser per monitorare porte di rete (cambiando il namespace dell’operazione di default del comando), mediante l’opzione -n «protocol» <port_number>, come mostrato di seguito:

fuser -n tcp 22
22/tcp: 2399

che di fatto mostra quali processi stiano utilizzando il numero di porta specificato, operazione molto utile in presenza di errori del tipo port is busy. che di fatto mostra quali processi stiano utilizzando il numero di porta specificato, operazione molto utile in presenza di errori del tipo port is busy.

Multiplexing nelle reti packed-switched

Nell’ambito dei sistemi di telecomunicazioni classici, vengono comunemente utilizzate due tecniche di multiplexing che prendono il nome di Time-Division Multiplexing (TDM) e Frequency-Division Multiplexing (FDM) rispettivamente.
La prima è una tecnica di condivisione di un canale di comunicazione secondo la quale ogni dispositivo ottiene a turno uso esclusivo dello stesso per un breve lasso di tempo. La TDM è la scelta preferita per sistemi a commutazione di circuito poiché permette di garantire la costanza del bit-rate assegnato a ciascun utente, eventualmente anche a costo di una non piena efficienza di sfruttamento della larghezza di banda del mezzo trasmissivo.
A differenza di quanto accade in una rete a commutazione di pacchetto, infatti, in una rete a commutazione di circuito la capacità del canale trasmissivo è interamente dedicata ad una specifica comunicazione. All’inizio della comunicazione si stabilisce una connessione diretta tra sorgente e ricevente: per questo motivo, storicamente, la tecnica TDM viene utilizzata nelle reti telefoniche.
La multlplazfonc a divisione di frequenza, meglio conosciuta come Frequency-Division Multiplexing (FDM), è una tecnica secondo la quale un canale trasmissivo viene diviso in sottocanali, ognuno costituito da una banda di frequenza separata. Questo rende possibile la condivisione dello stesso canale da parte di diversi dispositivi che possono comunicare contemporaneamente.
Questa tecnica è utilizzata, ad esempio, nelle trasmissioni televisive e radiofoniche: ogni emittente trasmette contemporaneamente attraverso l’etere che costituisce il canale di comunicazione condiviso. Ogni emittente trasmette su una determinata frequenza ed il ricevente per selezionare la trasmissione deve sintonizzarsi sulla frequenza appropriata.
Le due tecniche che abbiamo visto non possono essere utilizzate efficacemente in una rete packet-switched: nel caso in cui un host non avesse dati da trasmettere ci sarebbe un inutile spreco di risorse in quanto lo slot temporale (TDM) o la banda di frequenza (FDM) non sarebbero utilizzati. Questa situazione è molto più frequente di quanto possa sembrare, si pensi ad esempio ad un utente che spende del tempo a leggere una pagina Web prima di navigare verso un’altra pagina: durante la lettura non genera alcun traffico, quindi il suo slot temporale o la sua frequenza rimarrebbero inutilizzati.
Inoltre TDM e FDM funzionano molto bene se il numero di flussi da gestire è fisso o comunque limitato, ma non sono adeguate a gestire situazioni in cui il numero di flussi può cambiare dinamicamente, e anche questo è uno scenario piuttosto comune in reti packet-switched: si pensi, ad esempio, ad una LAN ed alla possibilità di connettere ad essa un numero di host che può variare nel tempo. L’aggiunta (e la rimozione) di tali host sarebbe problematica da gestire alla luce di quanto appena detto.
Queste considerazioni portano all’utilizzo di un’altra tecnica, definita Statistica/ Time-Division Muftiplexing (STDM). Questa tecnica è estremamente semplice: contrariamente a quanto accade con TDM in cui è consentito trasmettere soltanto all’interno di un determinato slot temporale, in questo caso la trasmissione avviene on demand, ossia se ci sono dati da trasmettere essi vengono trasmessi, senza la necessità di aspettare che arrivi il proprio turno.
A questo punto potrebbero sorgere dei problemi in quanto non esistono meccanismi per assicurare che tutti i flussi possano trasmettere: una volta che un flusso dati è partito, è importante garantire che questo non occupi il mezzo trasmissivo per un tempo indefinito, impedendo ad altri flussi di utilizzare il mezzo trasmissivo stesso. Da qui la necessità di limitare la trasmissione di ciascun flusso per garantire a tutti gli altri flussi di poter utilizzare il mezzo trasmissivo quando ne abbiano necessità.
Il meccanismo che consente di imporre questo limite è il pacchetto: ogni messaggìo viene spezzato in pacchetti, la cui massima dimensione viene limitata. Il flusso, quindi, trasmette una sequenza di pacchetti che, riassemblati, costituiscono il messaggio originario. Il vantaggio di questo approccio è semplice da comprendere: qualora ci fosse un unico flusso, esso potrebbe sfruttare l’intera capacità del mezzo trasmissivo, ma se i flussi fossero due, i pacchetti dei due flussi comincerebbero a intercalarsi, dividendosi equamente la banda disponibile grazie ad una serie di meccanismi per evitare la congestione del mezzo trasmissivo. Se a questo punto si aggiungesse un altro flusso, è facile capire che il meccanismo porterebbe ad un adeguamento dell’utilizzo del mezzo ed i tre flussi si dividerebbero ancora una’volta in parti uguali le capacità del mezzo trasmissivo.
In un approccio del genere non ci sono sprechi di risorse: se c’è un solo flusso esso monopolizza il mezzo trasmissivo e, nel momento in cui si aggiungono altri flussi, essi si dividono la cauacità del mezzo trasmissivo.