mercoledì 10 novembre 2010

Come catturare tutto il traffico TCP e girarlo su un proxy HTTP o SOCKS in Linux

Oggi (forse meglio dire da oggi in avanti) mi è capitato di dover utilizzare un proxy per potermi connettere a internet. Il dramma è stato che per poterlo fare avrei dovuto configurare ogni singola applicazione, dal browser al client di posta compreso il messenger, ecc. È vero, avrei potuto usare le preferenze del proxy di rete che Gnome mette a disposizione (anche se non ho trovato dove mettere user e password ???), ma così non avrei potuto usare altri 1000 programmi (alcuni senza interfaccia grafica) che non ereditano questa configurazione (come ad esempio il mio amatissimo wget).


In realtà il mio problema più grande deriva dal fatto che utilizzo il PC in un sacco di posti, e non ho proprio voglia di dover modificare la configurazione del proxy su tutte le applicazione tutte le volte che mi sposto.

Così mi sono messo a cercare una soluzione più elegante e adatta alle mie esigenze.
Ho trovato la soluzione che fa per me! Si chiama RedSocks, aiutato dal Firewall è in grado di catturare tutte le richieste di rete in uscita e girarle al proxy.
La configurazione non sembra molto complessa, anzi, il concetto di base è molto semplice.
Su quasi tutte le distrubuzioni Linux è presente iptables. Iptables è il programma con cui si configura Netfilter, un componente del kernel linux che permette di intercettare, manipolare e redirigere i pacchetti che transitano sulla scheda di rete.
La configurazione del sistema in questo modo risulta molto facile da gestire.

Come funziona
Si deve configurare Netfilter in modo che intercetti tutte le connessioni verso l'esterno (tutte quelle che vanno proxate) e che le giri al demone RedSocks.
Infine è necessario configurare RedSocks in modo che riceva le richieste e che le possa passare al proxy.

La documentazione di RedSocks dice che può supportare i seguenti proxy: SOCKS4, SOCKS5 or HTTPS (HTTP/CONNECT). Io personalmente ho provato solo il socks5 con autenticazione.

Preparazione del sistema
La mia distribuzione è una Ubuntu based, quindi (almeno credo) tutte le configurazioni riportate di seguito sono funzionanti anche su Ubuntu.

QUI potete trovare la mia versione compilata per x64 con tutte le shell per la gestione dello start e dello stop (ho compilato anche per x32). Vi ricordo che l'eseguibile ha una dipendenza dalle librerie libevent 1.4.2.

Script di start per iptables
Utilizzo il dispatcher del NetworkManager per lanciare lo script che va a creare la chain REDSOCK su iptables (utilizzando iptables-restore)
Lo script va messo in /etc/NetworkManager/dispatcher.d/01firewall

if [ -x /usr/bin/logger ]; then
        LOGGER="/usr/bin/logger -s -p daemon.info -t FirewallHandler"
else
        LOGGER=echo
fi

case "$2" in
        up)
                if [ ! -r /etc/iptables.rules ]; then
                        ${LOGGER} "No iptables rules exist to restore."
                        return
                fi
                if [ ! -x /sbin/iptables-restore ]; then
                        ${LOGGER} "No program exists to restore iptables rules."
                        return
                fi
                ${LOGGER} "Restoring iptables rules"
                /sbin/iptables-restore -c < /etc/iptables.rules
                ;;
        down)
                if [ ! -x /sbin/iptables-save ]; then
                        ${LOGGER} "No program exists to save iptables rules."
                        return
                fi
                ${LOGGER} "Saving iptables rules."
                /sbin/iptables-save -c > /etc/iptables.rules
                ;;
        *)
                ;;
esac

Il file /etc/iptables.rules contiene la configurazione della regola da applicare al firewall ed è stata prodotta con il comando iptables-save

# Completed on Tue Oct  5 16:24:40 2010
# Generated by iptables-save v1.4.4 on Tue Oct  5 16:24:40 2010
*nat
:PREROUTING ACCEPT [248829:58547933]
:OUTPUT ACCEPT [8387:566480]
:POSTROUTING ACCEPT [8404:567274]
:REDSOCKS - [0:0]
-A REDSOCKS -d 0.0.0.0/8 -j RETURN 
-A REDSOCKS -d 10.0.0.0/8 -j RETURN 
-A REDSOCKS -d 127.0.0.0/8 -j RETURN 
-A REDSOCKS -d 169.254.0.0/16 -j RETURN 
-A REDSOCKS -d 172.16.0.0/12 -j RETURN 
-A REDSOCKS -d 192.168.0.0/16 -j RETURN 
-A REDSOCKS -d 224.0.0.0/4 -j RETURN 
-A REDSOCKS -d 240.0.0.0/4 -j RETURN 
-A REDSOCKS -p tcp -j REDIRECT --to-ports 12345 
COMMIT
# Completed on Tue Oct  5 16:24:40 2010

Per verificare il corretto funzionamento potete andare a vedere il file di log /var/log/daemon.log dovreste trovare una riga del tipo FirewallHandler: Restoring iptables rules

Script di start per RedSocks
Ho creato il servizio "redsocks" che ho messo sotto /etc/init.d/redsocks (ricordatevi di mettere i permessi di esecuzione)

#!/bin/sh
### BEGIN INIT INFO
# Provides:          defaultdaemon
# Required-Start:    $syslog
# Required-Stop:     $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start daemon at boot time
# Description:       Enable RedSocks by daemon.
### END INIT INF

redsocks_start() {
  echo -n "Starting redsocks..."
  PID=$(pidof redsocks)
  if [ -z "$PID" ]; then
    /usr/sbin/redsocks -c /etc/redsocks.conf
    PID=$(pidof redsocks)
  else
    PID="already running $PID"
  fi
  echo " ($PID)"
}

redsocks_stop() {
  echo -n "Stopping redsocks..."
  PID=$(pidof redsocks)
  if [ -n "$PID" ]; then
    kill $PID
  else
    PID=" (not running)"
  fi
  echo " ($PID)"
}

redsocks_restart() {
  redsocks_stop
  sleep 1
  redsocks_start
}

redsocks_status() {
  PID=$(pidof redsocks)
  if [ -n "$PID" ]; then
    echo "RedSocks is running ($PID)"
  else
    echo "RedSocks is not running"
  fi
}

case "$1" in
'start')
  redsocks_start
  ;;
'stop')
  redsocks_stop
  ;;
'restart')
  redsocks_restart
  ;;
'status')
  redsocks_status
  ;;
'enable')
  EN=$(iptables -t nat -L OUTPUT|grep REDSOCKS)
  if [ -z "$EN" ]; then
    iptables -t nat -A OUTPUT -p tcp -j REDSOCKS
    echo "RedSocks enabled"
  else
    echo "RedSocks already enable"
  fi
  ;;
'disable')
  EN=$(iptables -t nat -L OUTPUT|grep REDSOCKS)
  if [ -n "$EN" ]; then
    iptables -t nat -D OUTPUT -p tcp -j REDSOCKS
    echo "RedSocks disabled"
  else
    echo "RedSocks already disable"
  fi
  ;;
*)
  echo "Usage redsocks "
  ;;
esac

exit 0

NB: eseguite anche il seguente comando per permettere solo all'utente root di leggere il file di configurazione di redoscks (questo perché all'interno della configurazione ci sarà la vostra password scritta in chiaro)

sudo chmod 600 /etc/redsocks.conf

Per installare il servizio è necessario eseguire questo comando:

sudo update-rc.d redsocks defaults 98 02

In questo modo il servizio viene eseguito allo start del sistema. Il servizio supporta i seguenti comandi:
  • start - avvia il demone
  • stop - stoppa il demone
  • restart - stoppa e riavvia il demone
  • enable - abilita l'utilizzo del demone
  • disable - disabilita l'utilizzo del demone
Nella mia configurazione il sistema è pronto per utilizzare RedSocks, ma volutamente non eseguo la seguente riga:

sudo iptables -t nat -A OUTPUT -p tcp -m owner --uid-owner darkk -j REDSOCKS

Questo significa che la regola REDSOCKS è stata definita, ma non è utilizzata da nessuno. Eseguendo il precedente comando si da istruzione al firewall di attivare la regola. Oppure si può richiamare il servizio "redsocks" con il comando enable

sudo service redsocks enable

Per disattivare il meccanismo è sufficiente eseguire questa istruzione

sudo iptables -t nat -D OUTPUT -p tcp -j REDSOCKS

oppure richiamare il servizio con il comando disable:

sudo service redsocks disable

Conclusioni
A questo punto il mio sistema alla partenza esegue il demone redsocks e crea la regola sul firewall. Se voglio attivare il proxy eseguo il servizio con il comando enable, se lo voglio disattivare con il comando disable.

All'interno del mio pacchetto trovate tutto quello che ho utilizzato.
Un'ottima idea può anche essere qualla di mettere un Launcher sul pannello per attivare e disattivare il servizio.

I launcher li ho creati in questo modo:


1 commenti:

Enrico ha detto...

Grazie per le dritte!