Daily chess puzzle

Play chess online

StortoAranci - Digital Notes

my little experience in Information Tecnology.

02 luglio 2007

OpenVPN IP Routing ed HTTP Proxy

A pensarci bene, sono sicuro che disporre di una VPN basata su SSL è una gran cosa, prima di tutto perchè può essere utilizzata in ambienti dove i firewall sono restittivi. Mi riferisco in particolare ai firewall aziendalli che controllano il traffico uscente dei dipendenti per mezzo di ACL (access control list).

In molte aziende che ho visitato, il collegamento ad Internet avviene tramite un http proxy. Connessioni ad Internet di questo tipo non consentono l'impiego di protocolli diversi dall'HTTP. (niente SMTP, POP3, streaming UDP ecc.ecc.).
Per tale motivo, quando mi capita di fare assistenza in posti di questo genere la domande più frequente è:

Ma non c'è un modo per arginare il proxy?

Come dice la parola stessa, un HTTP proxy mastica solo il protocollo HTTP.
Potete immaginare quante persone ho visto accanirsi nel tentativo di instradare traffico di varia natura verso questi poveri proxy?
C'è una considerazione aggiuntiva da fare; nelle grandi organizzazioni, spesso oltre al limite del protocollo si aggiunge quello imposto dalle ACL. In alcuni casi quindi non è possibile visitare pagine web dal contenuto morale dubbio, siti di hacking, casinò e via dicendo.
A dire il vero non ho mai visto ACL implementate veramente bene. Spesso il sito non è raggiungibile mediante l'URL ma lo è se viene specificato l'indirizzo IP del server. Tranne in rari casi questo non è necessariamente un problema dal momento che l'url è indispensabile se sullo stesso server vengono ospitati più siti web (host virtuali).

Ma è veramente impossibile utilizzare i proxy HTTP senza queste limitazioni?

Direi proprio di no; esistono diversi tools che consentono di fare http tunneling. Il principio su cui si basano questi arnesi è veramente semplice. Si tratta di convertire tutto il traffico generato da un punto A in HTML e di dirigerlo verso un altro punto B passando attraverso il proxy. Nel punto B il traffico viene riportato allo stato originale ed instradato regolarmente.

Costruire un tunnel HTTP è relativamente semplice; basta avere un host oltre il proxy in grado di ricevere il traffico http e di smistarlo correttaemnte secondo le necessità.

Ci sono addirittura dei siti su Internet che offrono, più o meno gratuitamente, un tunnel HTTP anche per il traffico P2P.
Programmi dediti allo scopo ce ne sono veramente tanti, basta fare un giretto su Internet.
A volte però le ACL inibiscono pesantemente l'uso di questi software perchè con la scusa di voler restare anonimi, in realtà vengo utilizzati per navigare apertamente senza i limiti imposti dal proxy.

In questi casi non resta che costruire un sistema ad-hoc in grado di ricevere i pacchetti http da instradare. Questo vuol dire che è necessario disporre di almeno un host apero su Internet dotato di un IP pubblico.

Se invece la necessità si ferma all'invio e recezione di posta elettronica, esistono strumenti come html2pop3 che sono visti con meno astio da parte degli amministratori di sistema.

22 maggio 2007

OpenVPN e IP routing

Ciao belli, questa volta parliamo di OpenVPN ed reti WAN.

In particolare vedremo come modificare la tabella di routing di una workstation che opera in una WAN che implementa OpenVPN.

Supponiamo di avere un pc connesso ad una rete locale (WAN o LAN non è rilevante adesso) e di voler raggiungere un'altra rete tramite VPN (utilizzando OpenVPN nello specifico).

Tutto quello che dovremo fare è impostare correttamente il nostro client.

Supponiamo inoltre che la rete agganciata in VPN non sia una semplice LAN bensì una WAN.

Come possiamo fare in modo che il nostro client possa navigare in tutta la rete remota?

Per comprendere meglio questa domanda, diamo un'occhiata alla figura riportata di seguito:



In questo esempio ci sono 3 reti differenti (Work LAN, LAN e DMZ) suddivise nel seguente modo:

Area Subnet Gateway
Work 10.0.0.0/8 10.0.0.1
LAN 192.168.0.0/8 192.168.0.1
DMZ 192.168.1.0/8 192.168.1.1


Sono presenti inoltre due connessioni ad Internet (una per B ed una per C).

Per comodità indichiamo le macchine con delle lettere (A, B, C, D) assumendo che abbiano i seguenti indirizzi IP:

Host Network Address
A Work LAN 10.0.0.238
A LAN (VPN) 192.168.0.6
B WorkLAN 10.0.0.1
B Internet 208.77.188.166
C LAN 192.168.0.1
C DMZ 192.168.1.1
C Internet 28.15.33.1
D DMZ 192.168.1.20


Nel momento in cui A porta a termine con successo la connessione VPN, i pacchetti verso la rete LAN seguono la linea tratteggiata.
Quello che noi vogliamo ottenere è di riuscire a far comunicare l'host A con l'host D.
In questo esempio utilizzeremo un client Windows ma sono sicuro che gli utenti di altre piattaforme non avranno problemi a riprodurre gli stessi comandi sul proprio sistema operativo.

Dopo aver installato e configurato Openvpn per la conenssione remota, possiamo eseguire il comando ipconfig /all. Il risultato dovrebbe essere simile a questo:


Configurazione IP di Windows

        Nome host . . . . . . . . . . . . . . : HOST_A
        Suffisso DNS primario  . . . . . . .  : worklan.local
        Tipo nodo . . . . . . . . . . . . . .  : Ibrido
        Routing IP abilitato. . . . . . . . . : No
        Proxy WINS abilitato . . . . . . . .  : No
        Elenco di ricerca suffissi DNS. . . . : worklan.local

Scheda Ethernet Connessione alla rete locale (LAN) 2:

        Suffisso DNS specifico per connessione:
        Descrizione . . . . . . . . . . . . . : TAP-Win32 Adapter V8
        Indirizzo fisico. . . . . . . . . . . : FF-FD-4E-18-2F-07
        DHCP abilitato. . . . . . . . . . . . : Sì
        Configurazione automatica abilitata   : Sì
        Indirizzo IP. . . . . . . . . . . . . : 192.168.0.6
        Subnet mask . . . . . . . . . . . . . : 255.255.255.0
        Gateway predefinito . . . . . . . . . :
        Server DHCP . . . . . . . . . . . . . : 192.168.0.1
        Lease ottenuto. . . . . . . . . . . . : mercoledì 13 giugno 2007 16.45.53
        Scadenza lease . . . . . . . . . . .  : giovedì 12 giugno 2008 16.45.53

Scheda Ethernet Connessione alla rete locale (LAN):

        Suffisso DNS specifico per connessione: worklan.local
        Descrizione . . . . . . . . . . . . . : Broadcom NetLink (TM) Gigabit Ethernet
        Indirizzo fisico. . . . . . . . . . . : FF-07-28-CB-55-B8
        DHCP abilitato. . . . . . . . . . . . : Sì
        Configurazione automatica abilitata   : Sì
        Indirizzo IP. . . . . . . . . . . . . : 10.0.0.238
        Subnet mask . . . . . . . . . . . . . : 255.255.255.0
        Gateway predefinito . . . . . . . . . : 10.0.0.1
        Server DHCP . . . . . . . . . . . . . : 10.0.0.13
        Server DNS . . . . . . . . . . . . .  : 10.0.0.12
        Lease ottenuto. . . . . . . . . . . . : mercoledì 13 giugno 2007 12.14.36
        Scadenza lease . . . . . . . . . . .  : giovedì 14 giugno 2007 12.14.36


A questo punto possiamo utilizzare il comando tracert per capire in che modo i pacchetti vengono instradati nella rete. Per fare questo partiamo cercando ad esempio un qualunque computer appartenente alla rete work lan:

tracert 10.0.0.5


La risposta dovrebbe essere simile a questa:

Tracing route to desktop5.worklan.local.0.0.10.in-addr.arpa [10.0.0.5]
over a maximum of 30 hops:

  1   <10 ms   <10 ms   <10 ms  desktop5.work.local.0.0.10.in-addr.arpa [10.0.0.5]

Trace complete.


Come è possibile notare tra il punto 10.0.0.238 ed il punto 10.0.0.5 c'è un solo salto. Questo perchè i due computer appartengono alla stessa rete.

Ripetiamo lo stesso comando ma cambiamo indirizzo di destinazione:

tracert 192.168.0.44


Tracing route to [192.168.0.44]
over a maximum of 30 hops:

  1   <130 ms   <143 ms   <172 ms   [192.168.0.44]

Trace complete.


Anche in questo caso il salto è sempre uno poichè l'host A ha un indrizzo di rete appartenenete alla rete LAN (192.168.0.6).
Adesso è la volta di scoprire se l'host D è disponibile sulla rete. Come abbiamo fatto in precedenza, utilizziamo il comando tracert con l'indirizzo desiderato:

tracert 192.168.1.20


Tracing route to 192.168.1.20 over a maximum of 30 hops
    1    <1 ms    <1 ms    <1 ms  gateway1.worklan.local [10.0.0.1]
    2    65 ms    52 ms    67 ms  208.77.188.166
    3  gateway.my-isp-example.com [208.77.50.249]
  reports: Destination net unreachable.  Trace complete.


Come è possibile notare, qualcosa non è andato per il verso giusto.
L'instradamento dei pacchetti IP segue regole ben precise che è necessario conoscere se vogliamo riuscire nel nostro intento.

Eseguendo il comando ipconfig /all possiamo notare come l'host A sia dotato di due schede di rete che si connettono ad altrettante reti locali. Quando un pacchetto IP deve essere consegnato a destinazione, il protocollo IP esegue alcuni controlli:

Se esistono regole particolari specificati per l'indirizzo IP del destinatario, il pacchetto seguirà dette regole.
Altrimenti: se il pacchetto è destinato ad un indirizzo IP della rete locale verrà instradato tramite detta rete.
Altrimenti: se il pacchetto IP non è destinato alla rete locale, si demanda il compito della consegna al gateway di default.

Nel nostro caso, poichè non esistono regole particolari specificate per l'indirizzo 192.168.1.20 e poichè non si tratta di un indirizzo di rete locale (in entrambe le reti) il nostro pacchetto è stato instradato verlo l'host B (10.0.0.1).
L'host B a sua volta non sapendo come consegnare il pacchetto ne ha demandato la consegna al proprio gateway di default (208.77.50.249) con scarsi risultati dato che l'indirizzo 192.168.1.20 appartiene ad una classe di indirizzi LAN non instradabili su Internet.
Per tale motivo l'ultimo host ha risposto alla richiesta con un errore: "destinazione irraggiungibile".
Anche nel caso in cui l'host B fosse stato in grado di instradare il pacchetto verso l'indirizzo 192.168.1.20, questi sicuramente non avrebbe raggiundo il nostro obbiettivo (host D) poichè per raggiungere questo computer, noi sappiamo che è necessario passare attraverso la nostra VPN.

Per farla breve, Default Gateway per noi vuol dire: "se non sei riuscito in altro modo, rivolgiti a lui".

Le regole di instradamento di cui parlavamo prima sono visibili tramite il comando route. Eseguiamo il comando specificando il parametro print e cerchiamo di capirci qualcosa:

route print


===========================================================================
Elenco interfacce
0x1 ........................... MS TCP Loopback interface
0x2 ...ff fd 4e 18 2f 07 ...... TAP-Win32 Adapter V8 - SecuRemote Miniport
0x10003 ...ff 07 28 cb 55 b8 ...... Broadcom NetLink (TM) Gigabit Ethernet
Connection
===========================================================================
===========================================================================
Route attive:
Indirizzo rete             Mask             Gateway       Interfac.  Metric
          0.0.0.0          0.0.0.0         10.0.0.1      10.0.0.238   20
         10.0.0.0    255.255.255.0       10.0.0.238      10.0.0.238   20
       10.0.0.238  255.255.255.255        127.0.0.1       127.0.0.1   20
   10.255.255.255  255.255.255.255       10.0.0.238      10.0.0.238   20
        127.0.0.0        255.0.0.0        127.0.0.1       127.0.0.1   1
      192.168.0.0    255.255.255.0      192.168.0.1     192.168.0.6   1
      192.168.0.6  255.255.255.255        127.0.0.1       127.0.0.1   30
    192.168.0.255  255.255.255.255      192.168.0.6     192.168.0.6   30
        224.0.0.0        240.0.0.0       10.0.0.238      10.0.0.238   20
        224.0.0.0        240.0.0.0      192.168.0.6     192.168.0.6   30
  255.255.255.255  255.255.255.255       10.0.0.238      10.0.0.238   1
  255.255.255.255  255.255.255.255      192.168.0.6     192.168.0.6   1
Gateway predefinito:          10.0.0.1
===========================================================================

Tralasciamo la sezione delle interfacce e concentriamoci solo sulle route attive. In questa sede non ha senso spiegare il significato di tutte le rige; l'importante è comprendere come avviene il routing in base alla tabella sopra riportata.

La prima cosa che bisogna sapere è che per instradare un pacchetto, il protocollo calcola un AND logico bit per bit tra l'indirizzo del destinatario e la sottorete (Mask).
Se come risultato dell'operazione logica otteniamo l'indirizzo di rete (prima colonna), la regola è soddisfatta ed il pacchetto seguirà un percorso piuttosto che un altro.
Qualora più regole fossero soddisfatte contemporaneamente, la priorità verrà assegnata mediante la metrica (ultima colonna). In realtà quello che abbiamo appena asserito riguardo alla metrica non è corretto; essa serve a dare un peso alle connessioni. Più la metrica è alta e più è facile aspettarsi connessioni lente o con parecchi intermediari (hop).

Per capire come vengono testate le regole, facciamo un esempio con l' indirizzo ip 10.0.0.5 utilizzato in precedenza rappresentando gli indirizzi ip in forma binaria:

Rapp. Decimale Rapp. Binaria
Indirizzo: 10.0.0.5 00001010.00000000.00000000.00000101
Mask: 255.255.255.0 11111111.11111111.11111111.00000000
AND: 10.0.0.0 00001010.00000000.00000000.00000000

Se adesso traduciamo il valore ottenuto dall'AND logico (00001010.00000000.00000000.00000000) in decimale otteniamo 10.0.0.0 che corrisponde all'indirizzo di rete appartenente all'interfaccia 10.0.0.238 (seconda regola nella tabella delle route attive).
Quando la regola è soddisfatta, il pacchetto viene instratato tramite il gateway specificato nella regola stessa.

Detto questo diamo uno sguardo ad alcune delle regole riportate nella tabella delle route attive.
La prima è quella relativa al gateway di default. In pratica viene adottatta quando nessuna altra regola può essere soddisfatta. Da notare che, nel nostro caso, il gateway predefinito è mappato sull'interfaccia (10.0.0.238) questo significa che tutto il traffico verso Internet passa tramite la scheda di rete e non tramite la VPN.
Impostare un gateway predefinito anche per la connessione VPN (vedi risultato del comando ipconfig/all) non ha senso dal momento in cui solo un gateway può instradare di default i pacchetti.

Le righe 2 e 6 indicano che se l'indirizzo fa parte della rete locale, il pacchetto può essere consegnato direttamente dall'host, senza dover richiedere la consegna ad altri gateway.

La riga 5 indica che l'indirizzo 127.0.0.1 è l'indirizzo di loopback (host locale). Nel caso dell'HOST_A l'indirizzo di loopback sta a significare proprio l'HOST_A.

La terza e la settima riga indicano che gli indirizzi dell'host sono equivalenti a quello di loopback mentre le righe che cominciano per "224.0.0.0" indicano il broadcast.

Dopo questa sbrodolata di informazioni, come possiamo raggiungere il nostro scopo?

Basta parlare di teoria, torniamo alla pratica.
Per risolvere agevolmente il nostro problema, aggiungiamo una regola specifica tale per cui i pacchetti destinati alla rete 192.168.1.0/8 vengano instradati tramite un altro gateway.

Fondamentale per noi è conoscere l'host preposto ad instradare correttamente i nostri pacchetti verso la rete DMZ.

Una costrizione che non possiamo violare nella costruzione della regola è che detto gateway deve appartenede ad una rete locale (altrimenti l'instradamento avverrebbe tramite il gateway di default).

Nel nostro esempio, il gateway preposto ad instradare i pacchetti verso la rete DMZ è l'host C (192.168.0.1).

Il comando che consente l'inserimento di una nuova regola è sempre route questa volta abinato al parametro add.

route add 192.168.0.0 mask:255.255.255.0 192.168.0.1


L'essenziale per aggiungere una regola tramite il comando "route add" è:
- l'indirizzo della rete: 192.168.0.0
- la mask: 255.255.255.0
- il gateway: 192.168.0.1

Se volessimo consenrare la validità della nostra regola al riavvio del pc, potremmo indicare anche il parametro -p (permanente).

Eseguendo nuovamente il comando route print la nuova regola dovrebbe comparire nell'elenco delle route attive.

A questo punto possiamo fare una prova per capire se la regola funziona correttamente o meno:

tracert 192.168.1.20


Rilevazione instradamento verso 192.168.1.20 su un massimo di 30 punti di passaggio

  1   560 ms   507 ms   420 ms  192.168.0.1
  2   474 ms   561 ms   443 ms  192.168.1.20

Rilevazione completata.


Come è possibile vedere, questa volta abbiamo colto nel segno.

Spero che questo articolo sia stato utile. Esistono diversi modi per raggiungere l'obbiettivo e questo solo uno dei tanti.

Per saperne di più:

La Homepage di OpenVPN
Il comando Route di Windows
Cenni preliminari sul routing
Un utile tutorial sul routing IP ed IPX

17 maggio 2007

Freeradius Wi-Fi and TLS on Fedora Core

If like me you are a fedora user and you have to deploy a WPA security in your WLAN you will find some useful information in the welldone article about freeradius called:Securing Your WLAN with WPA and FreeRADIUS.
The article does some useful exaples but uses a generic linux distribution so some changes must be done for fedora.
In particular when i made the CA for my machine, that CA simply didn't work for me. This because the article assumes that the "openssl.cnf" config file is well-formed.
By my experience you have to change the line:

x509_extensions = usr_cert

with:

x509_extensions = v3_ca

I don't know if other linux distros have a different value for the "x509_extensions" parameter.

As usual, if i'm wrong please, let me know.

EFMBE

05 aprile 2006

sgcop - install from images

The SG20 don't has got an usb device and actually i don't know if the bios support boot from usb devices over pcmcia, so i make an image of sgcop pre-installed on my system. To make sgcop working with this image you need:

An easy way to use the images is to burn a multisession disk with systemrescue on it, then open a new session trasferring the image files on cd, so you can restore the images directly from cd.

An alternate solution may be a pendrive.

My SG30 comes with a 20 GB hard disk so i make smaller images from partitions to fit in SG10/20 hard disks.

You can use fdisk to make partitions and partimage to restore the image files on disk.

Before restoring the images make sure you have enough space:

  • 16 MB (boot partition hda1)
  • 1,5 GB (logs partition hda2)
  • 4,0 GB (root partition hda4)

If you want to restore the mbr without partimage exec this command on shell:

dd if=sgcop-mbr of=/dev/hdx

Where hdx is your hard disk device.

After restoring you can mount the 'Logs' partition and delete the file:

/var/ipcop/ethernet/settings

Finally put the hard disk on your sg10/20 and run 'setup'.

Why not ghost? Ghost don't work properly with linux ext3 and grub; finally ghost isn't freeware.

17 marzo 2006

sgcop - the ipcop porting for Toshiba SGxx Magnia series

SGCop is the IPCop porting for the Toshiba SGxx Magnia computers. When I planned my LAN at home i was looking for an embedded SOHO firewall/router for Internet ADSL sharing. Buying a Toshiba SG30 Magna on ebay was the best choice for me but the Magnia's operative system is far to have the "security" i have in mind so i've decided to install IPCop instead. Installing IPCop on SG30 is hard due to lack of a graphic interface and CD-ROM and besides it's desined for old-computers deployment. This porting is 100% IPCop compatible. On this table you will find the main differences:
Diff. IPCopSGCop
CFLAGS-O2 -mcpu=i386 -march=i386 -pipe -fomit-frame-pointer-O2 -mcpu=i686 -march=pentium3 -pipe -fomit-frame-pointer
Serial ConsoleNoYes
LCD supportNoYes
Install from PendriveNoYes
Installation:
You can install SGCop in several ways.
  1. You can put the SGxx HD on another pc and make an install like IPCop does.
  2. You can temporary add a CD-ROM and/or a graphic card on the SGxx and make an install like IPCop does.
  3. You can use 'syslinux' to make a pendrive bootable from the sgcop ISO and use the serial console from the SGxx.

Install from usb:
First of all you need a serial connection to the SGxx (ex: Windows Hyper Terminal) and a Pendrive with 64MB free.

During SGxx boot enter the BIOS and change the "boot sequence" then select usb device instead of IDE hard disk.

To make the pendrive bootable you need to run some commands in your linux box.

Use cfdisk to make a new partition on the pendrive:

cfdisk /dev/sda

Select only "ext3" or "vfat" file system type only.

mkfs.msdos /dev/sda1

Now mount the pendrive and the iso image:

mkdir /mnt/usb mkdir /mnt/iso
mount -o loop sgcop-1.4.10.i686.iso /mnt/iso
mount -t vfat /dev/sda1 /mnt/usb

Copy the content of the iso image to the pendrive:

cp -ra /mnt/iso/* /mnt/usb

The -r argument specifies a recursive copy including every directory, and the -a preserves as much as possible the structure of the data in the USB. Now you need to copy some files in the folder /boot/isolinux of the mounted pendrive to the root of the pendrive so you can boot from it:

cd /mnt/usb/boot/isolinux
cp vmlinuz /mnt/usb/
cp isntroot.gz /mnt/usb/
cp isolinux.cfg /mnt/usb/syslinux.cfg

finally make the pendrive bootable with the following command:

syslinux -s /dev/usb

If everything was right you can now plug the pendrive in the SGxx and boot.

Installation notes:
If you're running the installation from a serial console beware because you can't redirect on /dev/ttyX (you can't manage virtual consoles)
If you don't need a detailed output during installation use the command "install /dev/null"

If you are running the install from floppy and you want to use a SCSI device remember this: you "must" use a 2.88 MB compatible floppy.

IPCop compatibility:
You can use any add-in/modification made for IPCop but remember that IPCop is compiled to run on a generic "i386".

SGCop theme:
SGCop replaces the original IPCop's theme.
Thanks to Mariane for his "elegant 2005 IPCop theme."
If you want to contact the author email to: schneider.mariane@gmx.de

Downloads:

sgcop-install-1.4.10.i686.iso
sgcop-sources.1.4.10.tar.bz2
md5sum.txt

01 marzo 2006

tR1 WinRar Server Backups (vbscript)

L'utilizzo di WinRar per le operazioni di backup può essere utile anche nell'ambito di un dominio Active Directory al fine di centralizzare tutti i files in un solo punto.

A tale scopo presento qui una variante di tR1 Winrar Backup che consente di fare i backup in remoto di cartelle condivise in rete.

Per prima cosa, non si fa uso in WinRar del parametro '@' ma di un file esterno che contiene le cartelle su cui eseguire i backup.

Lo script accetta alcuni parametri a riga di comando: -C: (Indica un backup completo) -LOG: (indica il file di log) -L: (indica il file di elenco delle cartelle soggette a backup) -P:<Password> (specifica una password da dare a WinRar)


'tR1 WinRar Backup 'Copyright (C) 2005-2006 vittorio benintende <vittorio@lucullo.it> 'This file is distributed under the GPL license ' Option Explicit 'params Const WORK_DIR="c:\backups\install" Const DEST_DIR="c:\backups\data" const ForReading=1 const ForWriting=2 Const ForAppending=8 const SUFF_COMPLETO="completo" CONST SUFF_GIORNALIERO="incrementale" const SUFF_EXT=".rar" Const TEMP=".tmp" const PASSWORD=" -hp" Const FILE_NOT_FOUND="File Not Found" Const MAX_LOG_SIZE=1000000 Const TITLE="tR1 Server Backup" Const VER="1.42" 'files Const DEF_LOG_FILE="backup.log" Const DEF_LIST_FILE="myBackups.txt" 'logging Const SUCCESS =0 Const ERROR =1 Const WARNING=2 Const INFORMATION=4 Const AUDIT_SUCCESS=8 Const AUDIT_FAILURE=16 Const DEF_NUM=5 Const REPLACE_CHAR="+" Const ALT_REPLACE_CHAR="-" Dim f, WshShell, FSO,fListFile,fTemp Dim lngResult Dim strWinRarCmd Dim blCompleto,blWarning,blPassword Dim lngPos,lngCiclo Dim WIN_RAR_CMD, WIN_RAR_CMD2 Dim objArgs Dim strArgs Dim strcurrent, strCurrentCMD Dim aryCampi,aryFiles Dim strLogFile,strListFile Dim strPassword Dim lngLogSize 'network Dim objNet strWinRarCmd=WIN_RAR_CMD2 strLogFile=WORK_DIR & "\" &amp; DEF_LOG_FILE strListFile=WORK_DIR & "\" &amp; DEF_LIST_FILE strPassword="" Set objArgs = WScript.Arguments For lngPos = 0 to objArgs.Count - 1 blPassword=FALSE Select Case UCase(objArgs(lngPos)) Case "-C" strWinRarCmd=WIN_RAR_CMD blCompleto=TRUE End Select If UCase(Left(objArgs(lngPos),5))="-LOG:" Then strLogFile=Right(objArgs(lngPos),Len(objArgs(lngPos))-5) End If If UCase(Left(objArgs(lngPos),3))="-L:" Then strListFile=Right(objArgs(lngPos),Len(objArgs(lngPos))-3) End If If UCase(Left(objArgs(lngPos),3))="-P:" Then strPassword=PASSWORD & Right(objArgs(lngPos),Len(objArgs(lngPos))-3) blPassword=True End If If blPassword Then strArgs=strArgs & " -P:" Else strargs=strArgs & " " &amp; objArgs(lngPos) End If Next 'argomenti WIN_RAR_CMD = """c:\program files\winrar\winrar.exe"" a -ac -ag -dh " & strPASSWORD &amp; " -inul -ibck -ilog" & strLogFile &amp; " -m5 -os -ow -r -t -ts " & DEST_DIR &amp; "\*" & SUFF_COMPLETO &amp; SUFF_EXT & " ""?""" WIN_RAR_CMD2= """c:\program files\winrar\winrar.exe"" a -ac -ao -ag -dh " &amp; strPASSWORD & " -inul -ibck -ilog" &amp; strLogFile & " -m5 -os -ow -r -t -ts " &amp; DEST_DIR & "\*" &amp; SUFF_GIORNALIERO & SUFF_EXT &amp; " ""?""" If blCompleto Then strWinRarCmd=WIN_RAR_CMD Else strWinRarCmd=WIN_RAR_CMD2 End If blWarning=FALSE Set WshShell = WScript.CreateObject( "WScript.Shell" ) Set FSO = CreateObject("Scripting.FileSystemObject") If Trim(strArgs)="" Then strArgs ="no" WshShell.LogEvent INFORMATION, TITLE & " starting with " &amp; strArgs & " options." 'prendiamo le dimensioni del log On Error Resume Next Set f = fso.getfile(strLogFile) lnglogsize=CLng(f.Size) 'grezzo tail del log If lngLogSize>MAX_LOG_SIZE Then f.copy strlogfile & ".old", TRUE Set f = Nothing fso.deletefile (strLogFile) Else Set f = Nothing End If On Error GoTo 0 'inizio Set f = fso.OpenTextFile(strLogFile , ForAppending, True) f.writeline "--------------------------------------------------------------------" f.writeline "(" & Now &amp; ") Starting program..." f.writeline TITLE & " v." &amp; VER f.writeline "starting with " & strArgs &amp; " options." f.writeline "Environment:" On Error Resume Next Set objNet = CreateObject("WScript.NetWork") If Err.Number <> SUCCESS Then 'If error occured then display notice f.writeline "(" & Now &amp; ") Error getting network info." Else f.writeline "User " & objNet.UserName &amp; vbCRLF & _ "Computer " & objNet.ComputerName &amp; vbCRLF & _ "Domain " & objNet.UserDomain End if On Error GoTo 0 Set objNet = Nothing f.writeline "Reading from file '" &amp; strListFile & "'" On Error Resume Next Set fListFile = fso.OpenTextFile(strListFile, ForReading, FALSE) If err.number<>SUCCESS Then f.writeline "(" & Now &amp; ") Error opening list file." WshShell.LogEvent Error, TITLE & " Error opening file." f.close WScript.Quit (1) End If On Error GoTo 0 f.close Set f = Nothing Do While not fListFile.AtEndOfStream strCurrent = Trim(fListFile.ReadLine) if strCurrent="" then strCurrent=";" If Left(strCurrent,1)=";" Then 'commento Else aryCampi= Split(strCurrent, "*", -1, 1) lngPos=DEF_NUM If UBound(aryCampi)>0 Then If not IsNumeric(aryCampi(1)) Then aryCampi(1)=DEF_NUM Else aryCampi(1)=CLng(aryCampi(1)) If aryCampi(1)<1>10 Then aryCampi(1)=DEF_NUM End If End If lngPos=aryCampi(1) End If If arycampi(0)<>"" Then Set f = fso.OpenTextFile( strLogFile, ForAppending, True) strCurrentCMD=replace(replace(strWinRarCmd,"*",replace(replace(aryCampi(0),":",ALT_REPLACE_CHAR),"\",REPLACE_CHAR)),"?",aryCampi(0)) f.writeline vbcrlf & "###" &amp; aryCampi(0) & "###" f.writeline "(" & Now &amp; ") [WinRAR] Creating " & replace(replace(aryCampi(0),":",ALT_REPLACE_CHAR),"\",REPLACE_CHAR) &amp; " file..." 'consentiamo a rar di scrivere nel logv f.close Set f = Nothing lngResult=WshShell.Run (strCurrentCMD ,0,true) Set f = fso.OpenTextFile(strLogFile , ForAppending, True) Select Case lngResult Case SUCCESS f.writeline "(" & Now &amp; ") [WinRAR] Done." Case 1 f.writeline vbcrlf & "(" &amp; Now & ") [WinRAR] Cannot create empty file." case 6 f.writeline "(" & Now &amp; ") [WinRAR] Cannot find source." blWarning=TRUE Case 255 f.writeline "(" & Now &amp; ") [WinRAR] Aborted by user." blWarning=TRUE Case Else f.writeline vbcrlf & "(" &amp; Now & ") [WinRAR] Error (" &amp; lngResult & ")." 'aggiungo un ritorno a capo perché winrar non lo mette. blWarning=TRUE End Select 'controlliamo l'eliminazione If lngResult=SUCCESS Then If blCompleto Then 'cancelliamo tutti i gionalieri f.writeline "(" & Now &amp; ") Checking old files deletion..." lngResult=WshShell.Run ("cmd.exe /c dir /B /O:D """ & DEST_DIR &amp; "\" & replace(replace(aryCampi(0),":",ALT_REPLACE_CHAR),"\",REPLACE_CHAR) &amp; SUFF_GIORNALIERO & "*" &amp; SUFF_EXT & """ > " &amp; strListFile & TEMP ,0,true) 'f.writeline ("cmd.exe /c dir /B /O:D """ & DEST_DIR &amp; "\" & replace(aryCampi(0),"\",REPLACE_CHAR) &amp; SUFF_GIORNALIERO & "*" &amp; SUFF_EXT & """ > " &amp; strListFile & TEMP &amp; " 2 > c:\errore.txt") On Error Resume Next Set fTemp = fso.OpenTextFile(strListFile & TEMP, ForReading) lngResult=Err.number On Error GoTo 0 If lngResult=SUCCESS Then On Error Resume Next aryFiles= Split(fTemp.ReadAll, vbcrlf, -1, 1) lngResult=Err.number On Error GoTo 0 If lngResult=SUCCESS Then f.writeline "(" & Now &amp; ") Deleting " & CLng(UBound (aryFiles)) &amp; " incremental files..." For lngCiclo=0 to CLng(UBound (aryFiles)) If aryFiles(lngCiclo)<>"" and aryFiles(lngCiclo)<>FILE_NOT_FOUND Then On Error Resume Next fso.DeleteFile (DEST_DIR & "\" &amp; aryFiles(lngCiclo)) If err<>SUCCESS Then f.write "(" & Now &amp; ") [Delete] Error (" & err &amp; ") deleting file " End If On Error GoTo 0 f.writeline (DEST_DIR & "\" &amp; aryFiles(lngCiclo)) End If Next f.writeline "(" & Now &amp; ") Done." End If 'lngResult Else f.writeline "(" & Now &amp; ") [Delete] Error (" & lngResult &amp; ") opening temp file." End If Set aryFiles= Nothing 'prendiamo i bkp completi ed eliminiamo quelli in eccesso lngResult=WshShell.Run ("cmd.exe /c dir /B /O:D """ & DEST_DIR &amp; "\" & replace(replace(aryCampi(0),":",ALT_REPLACE_CHAR),"\",REPLACE_CHAR) &amp; SUFF_COMPLETO & "*" &amp; SUFF_EXT & """ > " &amp; strListFile & TEMP ,0,true) On Error Resume Next Set fTemp = fso.OpenTextFile(strListFile & TEMP, ForReading) lngResult=Err.number On Error GoTo 0 If lngResult=SUCCESS Then On Error Resume Next aryFiles= Split(fTemp.ReadAll, vbcrlf, -1, 1) lngResult=Err.number On Error GoTo 0 If lngResult=SUCCESS Then If UBound (aryFiles) > lngPos Then f.writeline "(" & Now &amp; ") Deleting " & CLng(UBound (aryFiles) - lngPos) &amp; " complete files..." For lngCiclo=1 to CLng(UBound (aryFiles) - lngPos) If aryFiles(lngCiclo)<>FILE_NOT_FOUND Then On Error Resume Next fso.DeleteFile (DEST_DIR & "\" &amp; aryFiles(lngCiclo)) If err<>SUCCESS Then f.write "(" & Now &amp; ") [Delete] Error (" & err &amp; ") deleting file " End If On Error GoTo 0 f.writeline (DEST_DIR & "\" &amp; aryFiles(lngCiclo)) End If Next f.writeline "(" & Now &amp; ") Done." End If End If 'lngResult Else f.writeline "(" & Now &amp; ") [Delete] Error (" & lngResult &amp; ") opening temp file." End If fTemp.close Set fTemp = Nothing On Error Resume Next fso.DeleteFile( strListFile & TEMP) On Error GoTo 0 End If End If f.writeline "(" & Now &amp; ") Backup complete." f.close Set f=Nothing End If End If '; Loop fListFile.close Set fListFile = Nothing If blWarning Then WshShell.LogEvent WARNING, TITLE & " Done. Some errors occurred during backup (See log file in '" &amp; strLogFile & "')." Else WshShell.LogEvent SUCCESS, TITLE & " Done." End If 'ESCI Set FSO=Nothing Set WshShell=Nothing 'WScript.Quit (SUCCESS)


Per utilizzare correttamente lo script è necessario creare un list file contenente i percorsi da sottoporre a backup. Se non diversamente specificato il file sarà "c:\backups\install\myBackups.txt".

di seguito un esempio di file valido:


; Server 1 \\192.168.0.1\DIR_1 \\192.168.0.1\DIR_1 \\192.168.0.1\DIR_1 \\192.168.0.1\DIR_1 ; Server 2 \\mioserver\DIR_2\*3 ; Locale c:\Winnt\system32\*1 ; commento


Alcuni path sono seguiti da un '*' (separatore) ed un numero. Tale numero indica quanti backup completi conservare nel repository. Se non specificato il programma conserva gli ultimi 5 completi creati.

Ogni volta che un completo viene creato, tutti i backup incrementali vengono eliminati.

Ricordate che il carattere "\" alla fine del path è fondamentale per il corretto funzionamento dello script.

Anche in questo caso è possibile schedulare un job per avviare le operazioni senza l'intervento di un operatore. (attenzione ai permessi di lettura/scrittura).

28 febbraio 2006

tR1 WinRar Backup (vbscript)

Di seguito riporto il codice sorgente di un piccolo programma scritto in vbscript che, mediante l'impiego di winrar, esegue il backup su una cartella (remota o locale).

WinRar è un ottimo compattatore che possiede una vasta gamma di opzioni a riga di comando. Questo ne consente l'utilizzo all'interno di un programma in grado di effettuare backup di tipo completo, incrementale, differenziale o giornaliero.

Lo script accetta due parametri al prompt dei comandi:
-C : effettua un backup completo
-D : elimina i files incrementali e completi precedenti. (valido solo se è stato specificato -C)

Prima di poter utilizzare il programma è necessario impostare correttamente alcune costanti all'interno del codice sorgente:

WORK_DIR (directory di lavoro)
DEST_DIR (directory di destinazione dei backup)
SUFF_COMPLETO (suffisso da dare al nome del file per i backup completi)
SUFF_GIORNALIERO (suffisso da dare al nome del file per i backup incrementali)
PASSWORD (password di criptazione)

Ricordo che è possibile modificare lo script a piacimento in accordo con quanto stabilito nella GPL.

'
'tR1 WinRar Backup
'Copyright (C) 2004-2005 vittorio benintende <vittorio@lucullo.it>
'This file is distributed under the GPL license
'
Option Explicit
Const WORK_DIR="c:\bkp"
Const DEST_DIR="\\151.92.106.42\kg00172$\backup"
const SUFF_COMPLETO="completo"
CONST SUFF_GIORNALIERO="giornaliero"
const PASSWORD="Daniele_e_1_Grosso"

const SUFF_EXT=".rar"
const ForReading=1
const ForWriting=2
Const ForAppending=8

Dim f, WshShell, FSO
Dim lngResult
Dim strWinRarCmd
Dim blCompleto, blDelete, lngPos
Dim WIN_RAR_CMD, WIN_RAR_CMD2
Dim objArgs

'argomenti
WIN_RAR_CMD = "c:\programmi\winrar\winrar.exe a -ac -ag -dh -hp" & PASSWORD & " -inul -ibck -ilog" & WORK_DIR & "\backup.log -m5 -os -ow -r -t -ts " & DEST_DIR
& "\" & SUFF_COMPLETO & SUFF_EXT & " @c:\bkp\backup_list.txt"
WIN_RAR_CMD2= "c:\programmi\winrar\winrar.exe a -ac -ao -ag -dh -hp" & PASSWORD & " -inul -ibck -ilog" & WORK_DIR & "\backup.log -m5 -os -ow -r -t -ts " &
DEST_DIR & "\" & SUFF_GIORNALIERO & SUFF_EXT & " @c:\bkp\backup_list.txt"
strWinRarCmd=WIN_RAR_CMD2
blDelete=FALSE
Set objArgs = WScript.Arguments
For lngPos = 0 to objArgs.Count - 1
    Select Case UCase(objArgs(lngPos))
        Case "-C"
            strWinRarCmd=WIN_RAR_CMD
            blCompleto=TRUE
        case "-D"
            blDelete=TRUE
    End Select
Next
Set WshShell = WScript.CreateObject( "WScript.Shell" )
Set FSO = CreateObject("Scripting.FileSystemObject")
Set f = fso.OpenTextFile(WORK_DIR & "\backup.log", ForAppending, True)
f.writeline "--------------------------------------------------"
'rinominiamo i files in caso di cancellazione
if blDelete and blCompleto Then
    f.writeline "(" & Now & ") Renaming old files..."
    lngResult=WshShell.Run ("cmd /c ren """ & DEST_DIR & "\" & SUFF_COMPLETO & "*" & SUFF_EXT & """ """ & SUFF_COMPLETO & "*" & SUFF_EXT & "." &
    SUFF_COMPLETO & """" ,1,true)
    If lngResult<>0 Then
        f.writeline "(" & Now & ") error (" & lngResult & ") renaiming files."
        WScript.Quit (1)
    End If
end if
f.writeline "(" & Now & ") [WinRAR] Starting command..."
f.writeline strWinRarCmd
f.close
'consentiamo a winrar di scrivere nel log
Set f = Nothing
lngResult=WshShell.Run (strWinRarCmd ,1,true)
Set f = fso.OpenTextFile(WORK_DIR & "\backup.log", ForAppending, True)
Select Case lngResult
    Case 0
        f.writeline "(" & Now & ") [WinRAR] Done."
        if blDelete and blCompleto then
            f.writeline "(" & Now & ") Deleting old files..."
            lngResult=WshShell.Run ("cmd /c del """ & DEST_DIR & "\*" & SUFF_EXT & "." & SUFF_COMPLETO & """" ,1,true)
            If lngResult<>0 Then
                f.writeline "(" & Now & ") error (" & lngResult & ") deleting old files."
                WScript.Quit (2)
            End If
            'giornaliero
            lngResult=WshShell.Run ("cmd /c del """ & DEST_DIR & "\" & SUFF_GIORNALIERO & "*" & SUFF_EXT & """" ,1,true)
            If lngResult<>0 Then
                f.writeline "(" & Now & ") error (" & lngResult & ") deleting old files."
                WScript.Quit (3)
            End If
        end if
    Case 255
        f.writeline "(" & Now & ") [WinRAR] aborted by user."
    Case Else
        f.writeline vbcrlf & "(" & Now & ") [WinRAR] error (" & lngResult & ")." 'aggiungo un ritorno a capo perché winrar non lo mette.
End Select
'ESCI
f.close
Set f = Nothing
Set FSO=Nothing
Set WshShell=Nothing

Prima di mettere mano al codice consiglio di leggere attentamente la guida in linea di WinRar per riferimento. Quello che non subito salta all'occhio è che il compressore fa uso del parametro '@' per indirare un file di testo contenente i percorsi ed i files da includere nel backup. Nonostante sia possibile modificare la riga di comando da passare a WinRar, l'uso di questo parametro risulta molto utile. Di segiuto riporto un esempio del file in questione:

C:\Documents and Settings\utente\Documenti\*
C:\Documents and Settings\utente\Preferiti\*
C:\Documents and Settings\utente\Desktop\*
C:\Documents and Settings\administrator\Documenti\*
C:\Documents and Settings\administrator\Preferiti\*
C:\Documents and Settings\administrator\Visual Studio Projects\*

//C:\Documents and Settings\administrator\Desktop\*

C:\Inetpub\wwwroot\*
D:\downloads\*

L'utilizzo della riga di comando risulta utile se si intende eseguire i backup tramite il serivizio Task Scheduler di Windows. Ad esempio potremmo impostare un backup completo in un giorno qualunque della settimana e 6 incrementali nei seguenti.

cscript c:\bkp\tR1_backup.vbs -C -D

è un esempio di come sia possibile utilizzarlo dalla console del sistema operativo.