[GNU/Linux] Configurare proxy da shell

Oggi vedremo come configurare il sistema per permettere alle applicazioni da linea di comando di utilizzare un proxy. Le applicazioni da linea di comando molto spesso non hanno infatti nativamente l’opzione per veicolare le trasmissioni verso un proxy, diversamente dalle applicazioni grafiche (ad esempio i browser hanno sempre le opzioni per la configurazione di eventuali proxy). Dunque, la soluzione per la linea di comando è quella di configurare i parametri del proxy come variabile d’ambiente, e costringere in questo modo l’applicazione a passare dal proxy. Tramite la shell sono supportati i proxy con protocollo HTTP, HTTPS, e FTP. Vediamo adesso in dettaglio come fare.

Prima di tutto controlliamo tra le variabili d’ambiente che non siano già impostati proxy:

# ENV | grep -i proxy

Se non viene ritornato niente possiamo procedere a configurare il/i proxy:

# export http_proxy=”http://<proxy-server-ip>:<port>”
# export https_proxy=”http://<proxy-server-ip>:<port>”
# export ftp_proxy=”http://<proxy-server-ip>:<port>”

Nel caso in cui ci siano già state definite variabili proxy, è possibile eliminarle e definirle nuovamente:

# unset http_proxy
# export http_proxy=”http://<proxy-server-ip>:<port>”

Ricordo che le variabili d’ambiente definite con i comandi precedenti risultano temporanee, mentre per renderle permanenti è necessario modificare i file .bash_profile o .bashrc, come ho scritto dettagliatamente in questo post:

[GNU/Linux] Come configurare le variabili d’ambiente

Nel caso in cui il proxy richieda l’autenticazione è necessario invece configurare le variabili d’ambiente in questo modo:

# export http_proxy="<username>:<password>@http://<proxy-server-ip>:<port>/"

Infine controlliamo di aver correttamente definito le variabili, osservando l’output dei comandi:

# echo $http_proxy
# echo $https_proxy
# echo $ftp_proxy

Ulteriori risorse sui proxy in Linux:

Matteo

[Programmazione][Java] Could not find the main class

Se lanciando un’applicazione Java da terminale appare il seguente errore:

Java Virtual Machine Launcher.
Could not find the main class.
Program will exit.

il problema è molto probabilmente dovuto ad una configurazione errata della variabile d’ambiente CLASSPATH. Una soluzione è quella di configurare correttamente la variabile, mentre l’altra è quella di eseguire il programma Java con l’opzione -classpath:

java -classpath . applicazione

dove applicazione rappresenta il nome del programma Java. In questo modo viene detto a Java che il classpath è la propria directory locale.

Una lista dei problemi più comuni con Java può essere trovata al link seguente:

http://www.dis.uniroma1.it/~figest/problemi.html

Matteo

[GNU/Linux] Come configurare le variabili d’ambiente

Una variabile è una piccola parte della memoria RAM identificata da un nome e in grado di contenere dei valori (nomi, date, …). Nel momento in cui un utente definisce una nuova variabile, il sistema associa al nome di tale variabile un indirizzo di memoria nel quale viene memorizzato il valore indicato. Per definire una variabile è sufficiente usare la seguente sintassi:

# NOME_VARIABILE=valore

Le variabili d’ambiente sono invece particolari variabili che permettono ad ogni utente di configurare il proprio ambiente di lavoro. Vediamo una lista dei comandi da tenere sempre a portata di mano.

Per vedere una lista delle variabili d’ambiente impostate nel sistema il comando è:

# env

environment_variables

Per settare una nuova variabile d’ambiente (“temporanea”, vedere più avanti per la spiegazione):

# export NOME_VARIABILE="valore della variabile"

Per visualizzare il valore di una variabile d’ambiente:

# echo $NOME_VARIABILE

Per cancellare una variabile d’ambiente:

# unset NOME_VARIABILE

E’ importante notare che per cancellare una variabile non è sufficiente effettuare un’assegnazione con un valore nullo, ma bisogna necessariamente usare unset. Ad esempio il comando VARIABILE="" imposterà semplicemente il valore della variabile con quello della stringa vuota, ma non cancellerà la variabile, dunque fate attenzione!

Le variabili d’ambiente possono essere suddivise in 3 categorie: temporanee, locali (per un singolo utente), o globali (per tutti gli utenti). Una variabile definita semplicemente all’interno della sessione di una shell avrà una durata limitata all’esecuzione della shell stessa. In questo caso:

# VARIABILE_PROVA=/home/pippo/tmp
# export VARIABILE_PROVA

la variabile verrà eliminata nel momento in cui la sessione della shell verrà chiusa (logout, exit, riavvio del sistema, …).

Un altra categoria è quella delle variabili d’ambiente locali, ossia relative ad un singolo utente. Queste possono essere definite in:

  • ~/.bash_profile – file è eseguito una volta al login
  • ~/.bashrc – file eseguito eseguito alla creazione di una nuova shell. La maggior parte delle variabili dovrebbe essere posta al suo interno.

Infine ci sono le variabili globali definite in modo simile alle precedenti:

  • /etc/profile – file letto una volta al login;
  • /etc/bashrc – file letto ogni volta che viene avviata una nuova shell.

Matteo

[Windows] Visualizzare file nascosti in Win XP con bug

Potrebbe succedere che in Windows XP non vengano visualizzati file e directory nascoste, anche spuntando la relativa opzione nel menù “Opzioni cartella”. Il problema probabilmente è dovuto a qualche programma o virus che ha corrotto le relative chiavi all’interno del registro di sistema. In particolare il problema può essere notato nel momento in cui viene spuntata l’opzione “visualizza file e cartelle nascosti”, e ricontrollando successivamente la spunta torna su “non visualizzare cartelle e file nascosti”.
Come risolvere il problema? Vediamone i passi da seguire.

Aprire il registro di sistema:

Start -> Esegui -> regedit

Dunque cercare:

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced

Nel frame di destra dobbiamo assicurarci che il valore Reg_Dword "Hidden" sia impostato a “1″, sapendo che le opzioni possibili sono:

  1. Visualizza file e cartelle nascoste;
  2. Non visualizzare file e cartelle nascoste.

Inoltre se è presente un valore reg_sz "Hidden", questo deve essere cancellato.

Fatto questo andiamo a cercare:

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\Folder\Hidden\SHOWALL

Dunque, nel frame di destra deve essere creato il valore Reg_Dword "CheckedValue" e impostato su 1. Se dovesse essere presente il valore reg_sz "CheckedValue", questo andrebbe eliminato.

Riavviate il sistema per sicurezza… et voilà i file nascosti!!

Matteo

[Programmazione][Java] Eccezioni: come gestirle correttamente

Oggi vediamo le eccezioni in Java, ma non spiegherò cosa sono (ci sono miliardi di documenti sul web al riguardo), piuttosto farò un po’ di chiarezza su quali tipi di eccezioni esistono e su come gestirle correttamente.

Brevemente, in Java un’eccezione è un evento che si può presentare durante l’esecuzione di un programma, e che interrompe il normale flusso delle istruzioni. A livello pratico, un’eccezione è un oggetto che viene creato al presentarsi dell’errore, e la gerarchia delle classi è visibile nella seguente figura, e ha come padre Throwable.

eccezioni_java

Gerarchia delle eccezioni Java

Ci sono 2 classi distinte: Error e Exception. A sua volta, la classe Exception può essere suddivisa in questo modo:

  • eccezioni controllate (checked): possono verificarsi indipendentemente dalle scelte del programmatore, per esempio un errore durante la lettura di un file.
  • eccezioni non controllate (unchecked): classi RuntimeException e Error. Possono verificarsi indipendentemente dalle scelte del client/utente, e possono invece dipendere dalla realizzazione di codice poco robusto, come ad esempio eccezioni NullPointerException (colpa del programmatore).

Questa distinzione è molto importante, perché ci dice quali sono le eccezioni da prendere in considerazione durante la scrittura di un programma e dunque quali sono le eccezioni da gestire. Come suggerisce giustamente il nome :-) , le eccezioni controllate devono necessariamente essere gestite all’interno di un programma, con i canonici comandi try/catch, altrimenti il compilatore non sarà in grado di compilare con successo il codice. Le eccezioni controllate possono ad esempio essere generate con l’apertura di un file o di una risorsa (IOException), oppure con l’acceso o manipolazione di un database (SQLException), e le cause sono esterne al programma stesso. Per questo motivo il programmatore deve gestire adeguatamente le eccezioni di questo tipo, non sapendo se saranno sollevate (la risorsa può non essere disponibile, la connessione al database può essere stata interrotta, …). Un semplice codice di esempio può essere il seguente:

try {
//apertura file
}catch (FileNotFoundException fnfe)
{
System.err.println("FileNotFoundException: " + fnfe.getMessage());
}

Le eccezioni non controllate invece non devono obbligatoriamente essere gestite, in quanto non dovrebbero sollevarsi in presenza di codice ben scritto (tutti noi scriviamo codice robusto no?! ;-) ). In ogni caso è bene controllare attentamente il codice scritto al fine di evitare brutte sorprese ed evitare assolutamente eccezioni del tipo: un puntatore è nullo (NullPointerException), è state effettuata una divisione di un numero per zero (ArithmeticException), … Ad esempio un codice come il seguente:

try
{
int x;//input fornito dall'utente
System.out.println(5/x);
}catch(ArithmeticException ae)
{
System.err.println(ae.getMessage());
}

dovrebbe essere sostituito con il seguente codice:

int x;//input fornito dall'utente
if(x == 0)
{
System.out.println("Errore: l'input fornito è errato. Non è accettato il valore 0.");
System.exit(1);
}else
{
System.out.println(5/x);
}

Per ulteriori approfondimenti sulle eccezioni in generale leggere:

Matteo

[Programmazione][Java] Privilegi root per bind di porte 1-1023

Se dobbiamo creare un server in Java per accettare comunicazioni su TCP, è necessario usare la classe ServerSocket, mentre quella Socket è specifica per il lato client. Durante la creazione della componente client, bisogna fare particolare attenzione a quali porte indichiamo se ci troviamo su sistemi Linux/Unix. Ad esempio, il codice per mettere in ascolto un server sulla porta 80 è il seguente:

try
{
     ServerSocket server= new ServerSocket(80);
}catch (IOException iex)
{
     System.err.println(ex);
}

Il codice è corretto, ma potrebbe essere sollevata un’eccezione su sistemi Unix/Linux o anche Windows, in quanto sono necessari i privilegi di root/administrator per poter usare le porte nel range 1-1023.

Matteo

[Programmazione][Java] Utility per convertire numeri esadecimali

Ho realizzato in Java una piccola utility a linea di comando che effettua la conversione di un numero decimale in uno esadecimale e viceversa. Prima di vedere come utilizzarla, vediamo brevemente cos’è un numero esadecimale, per chi non lo ricordasse ;-) .

Da wikipedia: “Il sistema numerico esadecimale (spesso abbreviato come esa o hex) è un sistema numerico posizionale in base 16, cioè che utilizza 16 simboli invece dei 10 del sistema numerico decimale tradizionale. Per l’esadecimale si usano in genere simboli da 0 a 9 per le prime dieci cifre, e poi le lettere da A a F per le successive sei cifre, per un totale di 16 simboli.

Nella seguente tabella è visibile la conversione da decimale a esadecimale a binario.

Ad esempio, se abbiamo il numero esadecimale 1F5A, possiamo effettuare la conversione in decimale nel seguente modo: (1 x 16^3) + (15 x 16^2) + (5 x 16^1) + (10 x 16^0) = 8026. Inoltre, spesso un numero esadecimale viene indicato anteponendo al numero 0x, specialmente nei sistemi Unix-like, diventando ad esempio 0x1F5A.

Nel momento in cui l’utility viene avviata con il comando HCT (acronimo di Hex Conversion Tool, la classe che contiene il main), viene fornito il seguente menu:

$ java HCT
                       _____________________________
                      /                             \
                     |      Hex Conversion Tool      |
                     |             v1.0              |
                      \_____________________________/

            [ Matteo Cappelli aka roghan | matcap83@libero.it ]

[ Options ]
 1 - convert decimal to hex
 2 - convert hex to decimal
 3 - exit

Choose an option:
|

L’utility, con la relativa documentazione javadoc, è scaricabile dal seguente link:

Matteo

[GNU/Linux] Script per modificare MAC address

Ho scritto un piccolo script bash che permette in Linux di manipolare l’indirizzo MAC di una scheda di rete, la cui operazione in gergo viene detta spoofing. Lo script può essere usato su tutte le principali distribuzioni e permette di cambiare l’indirizzo MAC con uno generato casualmente oppure con uno indicato dall’utente. Le istruzioni per eseguire lo script sono le seguenti:

Usage: macs.sh [OPTIONS]
Spoof your wired or wireless network adapter with a new MAC address.
Options:
-r <interface> spoof interface with a random MAC address
-s <interface> <addr> spoof interface with specified MAC address
-o <interface> restore interface with original MAC address
-v <interface> view MAC address and vendor of adapter
-
a view MAC address of every network adapters
-h show this help

Examples:
sh macs.sh -r eth0
sh macs.sh -s wlan1 001122334455
sh macs.sh -s eth3 00:1C:39:FB:6C:88
sh macs.sh -o eth0MAC Spoofer v1.0b by Matteo "roghan" Cappelli

Tra le funzionalità vi è anche quella di visualizzare il vendor di una scheda di rete, e per fare ciò mi sono appoggiato ad uno script ideato da Hessel Schut.

Si tratta di uno script bash, dunque deve essere lanciato con l’interprete sh. Vediamo alcuni esempi:

# sh macs.sh -r eth1 modifica l’indirizzo dell’interfaccia eth1 con uno random
# sh macs.sh -s eth1 00:0C:29:FB:6C:4B modifica l’indirizzo di eth1 con 00:0C:29:FB:6C:4B
# sh macs.sh -o eth3 ripristina l’indirizzo MAC reale di eth3
# sh macs.sh -v eth2 visualizza l’indirizzo MAC e vendor di eth2
# sh macs.sh -a visualizza gli indirizzi MAC e vendor di tutte

Lo script è rilasciato con licenza GNU GPL v3, e può essere scaricato liberamente dal seguente link:

Matteo

[Reti] Come risolvere i problemi di connessione – parte 1

Spesso capita che la rete non funzioni, e ci chiediamo quale e dove possa essere il problema. E’ il nostro sistema che non va? E’ il server che non risponde? E’ la trasmissione che non funziona? Insomma ci sono sempre tante domande e non sempre è immediato trovare la risposta, e finiamo per cambiare parametri e impostazioni nel tentativo di ripristinare la connessione! Gli utenti più inesperti poi finisco per installare svariati tipi di software che promettono di ripristinare la connessione e di sistemare tutto, come questo Connectivity fixer. Non ci sono programmi più inutili e magari dannosi (chi ha detto spyware?! Io no ;-) …).

Internet connection problem

Questo post rappresenta invece la prima parte di un altro post che avevo scritto qualche tempo fa, in cui spiegavo come fare troubleshooting della rete e verificare il collegamento ad Internet. In questo articolo invece esaminiamo il problema partendo dalla connessione alla rete locale, e senza far uso di risoluzioni DNS.

Prendiamo come esempio l’architettura di rete visibile in figura, e supponiamo di essere il sistema Bob con indirizzo IP 172.17.10.3 e di voler contattare la macchina Server con indirizzo 172.17.30.2. Nell’immagine non ho specificato le subnet per semplificare il tutto e renderlo fruibile anche a chi può avere meno conoscenze informatiche, comunque possiamo assumere che la subnet sia /24, uguale per ogni indirizzo.

diagramma_rete

Diagramma di rete

Come è visibile dal grafico si tratta di una piccola rete, tuttavia il problema può facilmente essere esteso ad una rete molto più grande come anche ad Internet (semplicemente non ci sarà un solo router tra sorgente e destinazione ma una serie di N dispositivi, come backbone, …). Vediamo i passi da fare per controllare il funzionamento della rete dal punto di vista di Bob:

  1. Test del loopback. Apriamo un terminale (prompt cmd in Windows, shell in Linux e MacOS) e facciamo ping verso 127.0.0.1.
    $ ping 127.0.0.1
    PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
    64 bytes from 127.0.0.1: icmp_req=1 ttl=64 time=0.773 ms
    64 bytes from 127.0.0.1: icmp_req=2 ttl=64 time=0.125 ms
    64 bytes from 127.0.0.1: icmp_req=3 ttl=64 time=0.080 ms
    64 bytes from 127.0.0.1: icmp_req=4 ttl=64 time=0.083 ms
    --- 127.0.0.1 ping statistics ---
    4 packets transmitted, 4 received, 0% packet loss, time 3001ms
    rtt min/avg/max/mdev = 0.080/0.265/0.773/0.293 ms

    Questo è l’indirizzo di loopback e se il risultato è positivo significa che lo stack TCP/IP è stato inizializzato correttamente. In caso invece di fallimento il servizio che gestisce lo stack TCP/IP deve essere ripristinato all’interno del sistema operativo. Per effettuare il ripristino dello stack in Windows è possibile consultare questo link, mentre per Linux quest’altro.

  2. Test della scheda di rete. Adesso facciamo ping verso l’indirizzo IP del sistema locale, nell’esempio 172.17.10.3.
    $ ping 172.17.10.3
    PING 172.17.10.3 (172.17.10.3) 56(84) bytes of data.
    64 bytes from 127.0.0.1: icmp_req=1 ttl=64 time=0.111 ms
    64 bytes from 127.0.0.1: icmp_req=2 ttl=64 time=0.079 ms
    64 bytes from 127.0.0.1: icmp_req=3 ttl=64 time=0.080 ms
    64 bytes from 127.0.0.1: icmp_req=4 ttl=64 time=0.078 ms
    --- 127.0.0.1 ping statistics ---
    4 packets transmitted, 4 received, 0% packet loss, time 3001ms
    rtt min/avg/max/mdev = 0.078/0.087/0.111/0.013 ms

    Se con il ping vengono ricevute le risposte significa che la NIC funziona correttamente così come i driver/moduli di sistema, ma ciò non indica che la rete è esente da problemi quali cavi rotti o collegamenti interrotti. Un esito invece negativo potrebbe essere indice di scheda di rete guasta o di driver/moduli non installati correttamente. Provate a riavviare il sistema e, su Windows, a reinstallare i driver, mentre su Linux ad aggiornare il kernel e riavviare moduli e servizi secondo le istruzioni a questo link.

  3. Test del gateway. Ora è in turno del gateway/router. Effettuate il ping verso il default gateway per testare la comunicazione nella rete locale, nell’esempio 172.17.10.1.
    $ ping 172.17.10.1
    PING 172.17.10.1 (172.17.10.1) 56(84) bytes of data.
    64 bytes from 192.168.139.2: icmp_req=1 ttl=128 time=0.255 ms
    64 bytes from 192.168.139.2: icmp_req=2 ttl=128 time=0.237 ms
    64 bytes from 192.168.139.2: icmp_req=3 ttl=128 time=0.241 ms
    64 bytes from 192.168.139.2: icmp_req=4 ttl=128 time=0.219 ms
    --- 192.168.139.2 ping statistics ---
    4 packets transmitted, 4 received, 0% packet loss, time 3004ms
    rtt min/avg/max/mdev = 0.219/0.238/0.255/0.012 ms

    Un esito negativo significa che c’è un problema o nella trasmissione dei dati (cavo rotto/scollegato), o nel default gateway che non è in grado di elaborare le richieste, oppure un blocco delle richieste da parte di un firewall o altro dispositivo interconnesso tra Bob e il default gateway (switch, hub, AP, …).

  4. Test del server remoto. Infine, se tutti i 3 punti precedenti hanno avuto esito positivo, testiamo la connessione verso il server remoto, nel nostro esempio  172.17.30.2.
    $ ping 172.17.30.2
    PING 172.17.30.2 (172.17.30.2) 56(84) bytes of data.
    64 bytes from 172.20.0.1: icmp_req=1 ttl=128 time=1.46 ms
    64 bytes from 172.20.0.1: icmp_req=2 ttl=128 time=0.913 ms
    64 bytes from 172.20.0.1: icmp_req=3 ttl=128 time=2.40 ms
    64 bytes from 172.20.0.1: icmp_req=4 ttl=128 time=0.714 ms
    --- 172.20.0.1 ping statistics ---
    4 packets transmitted, 4 received, 0% packet loss, time 3005ms
    rtt min/avg/max/mdev = 0.714/1.375/2.407/0.657 ms

    Se l’esito è negativo significa che il problema è da ricercarsi nella rete remota. Inoltre, nel caso in cui sia possibile raggiungere la rete remota con il ping, sarebbe ideale poter replicare i test partendo dal server remoto verso il sistema sorgente.

Nel caso di connessione a Internet (e non locale) anche se tutti e 4 i punti hanno avuto esito positivo la comunicazione potrebbe non funzionare. In questo caso il problema è imputabile al servizio DNS, e per i passi da esseguire rimando a questo post.

Matteo

2011 in review

Here is a 2011 annual report for this blog made by the WordPress.com.

Here’s an excerpt:

The concert hall at the Syndey Opera House holds 2,700 people. This blog was viewed about 8.500 times in 2011. If it were a concert at Sydney Opera House, it would take about 3 sold-out performances for that many people to see it.

Click here to see the complete report.

Matteo