Banana Docet!

Appunti tecnici di un programmatore impazzito …

Personalizzare dinamicamente il MOTD di linux

Ero stanco dei soliti motd (message of the day) di Linux che trovavo sui vari server, così ho deciso di implementare un piccolissimo script che mi permettesse di vedere qualcosa di diverso ad ogni login.

Vediamo come fare.

Questa procedura è stata provata su una debian, ma può essere riprodotta su qualunque sistema unix. Ci occorrerà installare i package cowsay e fortune (se preferiamo quelli con localizzazione italiana e se siamo “audaci” anche quelli un po più spinti)

Installiamo i pacchetti digitando da console:

apt-get install cowsay fortunes-it fortunes-it-off

A questo punto creiamoci un semplicissimo script in bash che chiameremo mymotd e per l’esempio in questione lo posizioniamo sotto /usr/local/bin/.

#!/bin/bash
ALTER=(`echo -n \`/usr/games/cowsay -l\` | awk -F": " ‘{ print $2 }’`)
NUMBER=$[ ($RANDOM % ${#ALTER[@]}) + 1 ]

/usr/games/cowsay -f ${ALTER[$NUMBER]} `/usr/games/fortune`

Diamo i privilegi di esecuzione allo script tramite:

chmod +x /usr/local/bin/mymotd

Per concludere, modifichiamo il file /etc/profile aggiungendo in fondo allo stesso il percorso dello script ed il gioco è fatto. Potrete ottenere risultati simili a quello riportato in figura:

 

 

 

 

 

 

 

Buon divertimento …

PDF    Invia l'articolo in formato PDF   

Aggiornare la cache DNS sotto Linux

Può capitare di aggiornare la propria zona DNS e malgrado tutto al ping risponde ancora l’indirizzo vecchio.
Se controllando tramite il comando nslookup nomeDelServer vediamo che viene risolto con il nuovo indirizzo, allora abbiamo un problema di cache DNS.
Per risolverlo sarà sufficiente fare il reload del demone nscd tramite il comando:

/etc/init.d/nscd reload

Pingando nuovamente il server, vedremo che verrà risolto correttamente.

PDF Creator    Invia l'articolo in formato PDF   

Script per allineare scadenza password tra 389-ds (LDAP) e Samba

Ho creato questo script per risolvere un problema che si è presentato durante la fase di cambio password da computer in un dominio NT4 gestito tramite samba-3 + LDAP (questo in realtà gestito tramite un 389-ds) su una CentOS 5.6.


Sono state applicate le password policies su ldap e su samba.
Ho notato che cambiando la password direttamente dal client Windows, alcune applicazioni che si autenticano tramite LDAP, restituivano degli errori.

Indagando, su cosa cambiasse nella struttura LDAP dell’utente, ho trovato che quando si cambia la password dal client, un campo di LDAP, nello specifico passwordexpirationtime, veniva resettato al valore di default corrispondente al 1 Gennaio 1970.

Dal momento che non è prevedibile sapere quando qualcuno decide di cambiare la password, ho creato questo semplice ma efficace script di shell che viene lanciato via crontab.

#!/bin/bash
source ~/.bash_profile
FILE_REPORT=/var/log/aggiusta_scadenza_pwd.log
ERROR_REPORT=/root/tmp/errori_scadenze_password.log

TEST=0 # 0 -> ESEGUE …. 1 -> TEST
#  
GIORNI_DALLA_SCADENZA=15
# Ripuliamo i nostri files di reportistica
echo "" > $FILE_REPORT
echo "" > $ERROR_REPORT
function convertiMeseNum(){
                # Convertiamo il mese da letterale a numerico
                case $1 in
                        "gen")
                                MESE="01"
                        ;;
                        "feb")
                                MESE="02"
                        ;;
                        "mar")
                                MESE="03"
                        ;;
                        "apr")
                                MESE="04"
                        ;;
                        "mag")
                                MESE="05"
                        ;;
                        "giu")
                                MESE="06"
                        ;;
                        "lug")
                                MESE="07"
                        ;;
                        "ago")
                                MESE="08"
                        ;;
                        "set")
                                MESE="09"
                        ;;
                        "ott")
                                MESE="10"
                        ;;
                        "nov")
                                MESE="11"
                        ;;
                        "dic")
                                MESE="12"
                        ;;
                esac
}

function allineaScadenzaPwd(){
        TMP_LDIF_DIR=/root/tmp
        if [ -d $TMP_FILE_DIR ]
        then
                mkdir -p $TMP_LDIF_DIR
        fi
       
        # Estraiamo la data da samba e rendiamola utilizzabile dal comanda date
        DATA_SCADENZA=`pdbedit -v $1 | grep "Password must change:" | awk -F ": " ‘{ print $2 }’`
        case "$DATA_SCADENZA" in
                # Questo è il caso in cui l’utente non ha una scadenza della password
                "never")
                        echo "L’utente $1 NON ha scadenza password" >> $ERROR_REPORT
                ;;
                # Nel caso in cui non è settata la data di scadenza
                "0")
                        echo "L’utente $1 NON HA IMPOSTATO una data di scadenza!! (Verificare) " >> $ERROR_REPORT
                ;;

                # Case di default
                *)

                        MESE_SCADENZA="`echo $DATA_SCADENZA | awk ‘{ print $3 }’`"
                        GIORNO_SCADENZA="`echo $DATA_SCADENZA | awk ‘{ print $2 }’`"
                        ANNO_SCADENZA="`echo $DATA_SCADENZA | awk ‘{ print $4 }’`"
                        ORARIO_SCADENZA="`echo $DATA_SCADENZA | awk ‘{ print $5 }’`"
               
                        # Estraiamo il mese numerico dal mese di scadenza
                        convertiMeseNum $MESE_SCADENZA
                       
                        # Trasformiamo la data ottenuta in formato unix timestamp      
                        SCADENZA_PASSWORD=`date -d "$ANNO_SCADENZA-$MESE-$GIORNO_SCADENZA $ORARIO_SCADENZA" "+%s"`
                        # Su LDAP il campo di segnalazione scadenza è impostato a 15 giorni prima della scadenza reale dell’account
                        SCADENZA_CALCOLATA=`date -d @$(( $SCADENZA_PASSWORD – $(( $GIORNI_DALLA_SCADENZA * 86400 )) ))`
                        MESE_SCADENZA_1="`echo $SCADENZA_CALCOLATA | awk ‘{ print $2 }’`"
       
                        convertiMeseNum $MESE_SCADENZA_1
       
                        GIORNO_SCADENZA_1="`echo $SCADENZA_CALCOLATA | awk ‘{ print $3 }’`"
                        if [ $((GIORNO_SCADENZA_1)) -lt 10 ]
                        then
                                # Trovato numero minore di 10 per utente $1 … converto
                                GIORNO_SCADENZA_1="0"$GIORNO_SCADENZA_1
                                # echo "Giorno scadenza 1 -> $GIORNO_SCADENZA_1" >> $FILE_REPORT
                        fi
                        ORARIO_SCADENZA_1="`echo $SCADENZA_CALCOLATA | awk ‘{ print $4 }’ | sed ‘s/://g’`"
                        ANNO_SCADENZA_1="`echo $SCADENZA_CALCOLATA | awk ‘{ print $6 }’`"
                        SCADENZA_REALE=$ANNO_SCADENZA_1$MESE$GIORNO_SCADENZA_1$ORARIO_SCADENZA_1
                        SCADENZA_PASSWORD_Z=$SCADENZA_REALE"Z"
                        # echo $1 $DATA_SCADENZA $SCADENZA_CALCOLATA >> $FILE_REPORT
       
                        if [ $SCADENZA_PASSWORD ]
                        then
                                echo "Modifico data di scadenza per $1 -> $DATA_SCADENZA in data $SCADENZA_PASSWORD_Z" >> $FILE_REPORT
                                TMP_LDAP_FILE=$TMP_LDIF_DIR/$1.modify.ldif
                                echo "dn: uid=$1,ou=People,dc=dominio" > $TMP_LDAP_FILE
                                echo "changetype: modify" >> $TMP_LDAP_FILE
                                echo "replace: passwordexpirationtime" >> $TMP_LDAP_FILE
                                echo "passwordexpirationtime: $SCADENZA_PASSWORD_Z" >> $TMP_LDAP_FILE
                                echo "-" >> $TMP_LDAP_FILE
                                echo "changetype: modify" >> $TMP_LDAP_FILE
                                echo "replace: passwordexpwarned" >> $TMP_LDAP_FILE
                                echo "passwordexpwarned: 0" >> $TMP_LDAP_FILE

                                # Se questa non è l’esecuzione di un test, applichiamo le modifiche a LDAP
                                if [ $TEST -eq 0 ]
                                then
                                        /usr/bin/ldapmodify -x -Z -D "cn=Directory Manager" -w lamiapassword -f $TMP_LDAP_FILE
                                fi
                        fi
                ;;
        esac
}

#
# Eseguiamo una scansione sull’albero LDAP ed estraiamo tutti gli utenti di dominio attivi
for uid in `ldapsearch -x -Z -b ou=People,dc=dominio "(&(uid=*)(!(sambaAcctFlags=[DU*]))(passwordexpirationtime=19700101000000Z))" | grep uid: | awk -F ": " ‘{ print $2 }’`
do
        allineaScadenzaPwd $uid
done

L’esecuzione di questo script anche con qualche migliaio di utenti censiti, impiega pochi secondi.

Buon Divertimento.

PDF Creator    Invia l'articolo in formato PDF   

Configurare un syslog server con linux.

Oggi vediamo come si può configurare in maniera molto semplice e veloce un syslog server che utilizzeremo per registrare tutti i log delle nostre macchine in un unico punto.
Per il test abbiamo utilizzato una Debian Squeeze, ma la procedura è ripercorribile con qualunque altra distribuzione senza particolari differenze.

Per la gestione del syslog, utilizzeremo rsyslog che di default viene installato su Debian e rispetto a syslogd presenta una serie di vantaggi, fra i quali la possibilità di lavorare sia in tcp che in udp, è compatibile con syslog, è più facile da configurare rispetto ad un syslog-ng, e possiamo agganciarlo ad un database mysql per una gestione maggiormente semplificata.

Una volta installato rsyslog ed il suo relativo supporto mysql (rsyslog-mysql sotto debian) procediamo alla configurazione del suo database. In questo il debian ci agevola chiedendoci tramite dbconfig-common di configurare l’utente e la password per l’utente rsyslog. Risponderemo si alla domanda se vogliamo configurare il database tramite dbconfig-common e forniremo:

  • La password di root dell’utente mysql
  • La password per l’utente rsyslog

Terminata la procedura avremo creato un database chiamato Syslog ed un utente rsyslog che sarà di fatto l’amministratore del database creato.

Procediamo adesso alla configurazione di rsyslog editando il file /etc/rsyslog.conf

vim /etc/resolv.conf

Decommentiamo le righe relative a

$ModLoad imudp
$UDPServerRun 514

$ModLoad imtcp
$InputTCPServerRun 514

Riavviamo il demone:

service rsyslog restart

In questo modo abiliteremo sia la funzionalità del syslog tramite tcp che tramite udp.

Adesso per abilitare le funzionalità sui client esterni, sarà sufficiente modificare le impostazioni di syslog e indicare nel caso di syslog o rsyslog la sintassi è molto semplice e del tipo:

facility.level destinazione

quindi, nello specifico, invieremo ad esempio tutti i log relativi agli accessi di una nostra macchina (x.x.x.x) al server (x.y.z.x)

auth,authpriv.*                 @x.y.z.x

Riavviamo il servizio di syslog sul client, e a questo punto vedremo arrivare sul server syslog i dati relativi agli accessi sul server da monitorare.
In un prossimo post vedremo come configurare un client che utilizza syslog-ng.


LogAnalyzer

Il vantaggio di poter utilizzare un database per tracciare i dati di syslog è che possiamo anche utilizzare una comoda interfaccia web per gestirlo, e loganalyzer fa proprio al caso nostro.

Possiamo scaricare questa applicazione web, scritta in php, collegandoci a http://loganalyzer.adiscon.com/downloads. Una volta scaricata, decomprimiamola in una cartella del nostro disco rigido e spostiamo il contenuto della cartella src in /var/www/loganalyzer

mv /usr/local/src/loganalyzer-x.y/src /var/www/loganalyzer

Adesso, prima di procedere con l’installazione di loganalyzer, creiamo un database per la gestione della configurazione di loganalyzer.

mysql -u root -p

Al prompt di mysql digitare:

CREATE DATABASE loganalyzer;
CREATE USER loganalyzer IDENTIFIED BY ‘password’;
GRANT ALL PRIVILEGES ON loganalyzer.* TO loganalyzer@localhost IDENTIFIED BY ‘password’;
FLUSH PRIVILEGES;

Passiamo adesso all’installazione del nostro loganalyzer.
Spostiamoci dove abbiamo precendentemente decompresso i sorgenti di loganalyzer e dalla cartella contrib copiamo i file configure.sh e secure.sh.

cp /usr/local/src/loganalyzer-x.y/contrib/configure.sh /var/www/loganalyzer/
cp /usr/local/src/loganalyzer-x.y/contrib/secure.sh /var/www/loganalyzer/

e diamo i permessi di esecuzione ai suddetti files.

chmod +x /var/www/loganalyzer/*.sh
cd /var/www/loganalyzer

e lanciamo

./configure.sh

Colleghiamoci all’indirizzo: http://ipdelserver/loganalyzer/ e procediamo nella wizard di installazione associando quando richiesto le info relativo al database loganalyzer precedentemente creati, ed una volta giunti allo step 7 (configurazione dei log) bisogna dare le seguenti info:

  • Name of the source: Un nome a nostra scelta
  • Source type: Mysql Native
  • Select View: Syslog Fields
  • Table type: MonitorWare
  • Database host: localhost
  • Database name: Syslog
  • Database tablename: SystemEvents
  • Database user: rsyslog
  • Password: passwordUtenteRsyslog
  • Rnable Row Counting: No

Terminata l’installazione possiamo vedere adesso i nostri log collegandoci all’indirizzo http://server/loganalyzer.

Buon divertimento.

PDF    Invia l'articolo in formato PDF   

Failed to get lock on destination repos. Ecco come risolvere.

Ecco lo scenario:
Abbiamo due server subversion che si sincronizzando utilizzando svnsync, come abbiamo visto in un post precedente.
Adesso vediamo che quando cerca di sincronizzarsi con il server remoto, compare questo messaggio:

Failed to get lock on destination repos, currently held by ‘myserver:d27d5a7c-7d79-11e0-b5bd-a5a363c8406c’

Molto probabilmente il problema è stato causato a seguito di una caduta di connessione con la macchina da sincronizzare.


Non disperiamo! Ecco la procedura per risolvere il problema.

svn propdel svn:sync-lock –revprop -r 0 indirizzoTargetRepository

Ovviamente il paramentro indirizzoTargetRepository può essere di tipo svn:// oppure file:/// o anche https:// etc etc.

Non ci resta che attendere lanciare il comando per richiamare il sync, oppure aspettare il prossimo commit.

PDF Creator    Invia l'articolo in formato PDF   

Cambiare editor di default in debian/ubuntu? Semplice!

Abbiamo visto qui come cambiare l’editor di default in gentoo, ed oggi vediamo un semplice trick per modificare l’editor di default in debian e derivate (Ubuntu & Co.)

Basta aprire una console e in Ubuntu digitare:

sudo update-alternatives –config editor

In debian come utente root

update-alternatives –config editor

Basterà digitare il numero corrispondente all’editor che si vuole utilizzare ed il gioco è fatto.


PDF Creator    Invia l'articolo in formato PDF   

Script per eseguire il backup dei nostri repository subversion (svn)

Oggi voglio postarvi un semplice script che possiamo utilizzare per fare il backup dei repository progetti che sono sotto controllo di versioning, e nello specifico che utilizzano svn.

Questo script esegue un controllo su tutta la cartella dei repository di subversion ed esegue un backup di tutti quelli che sono repository validi, che hanno cioè un file format all’interno della cartella del repository.

Dopo di che fa il backup e li sposta in una directory di backup dove il dump viene poi compresso.
Il perchè di questa modalità è semplice. Per subversion la copia fisica del file è deleteria, in quanto poi ci troveremmo costretti a fare un successivo check della struttura stessa del database del repository.


#!/bin/bash
# svn-backup.sh

# Un file di log per il controllo delle operazioni
LOGFILE="/var/log//svn_backup.`date +%Y-%m-%d`.log"

# Programma per mail
# e relativi parametri di configurazione
MAIL_PROGRAM="mailx"
MAIL_DEST="mioindirizzo@mailserver.tld"

# La directory dei nostri repository
DIR_SVN="/var/svn"

# Una directory temporanea dove appoggiare una copia del repository
DIR_TMP="/home/backup/backup_svn/tmp"

# La directory dove salvare il dump compresso del repository

DIR_BACKUP="/home/backup/backup_svn/svn"

# Directory dove salveremo il tar con i nostri repository
DIR_DUMP_TAR="/home/backup/backup_svn"

# Nome del nostro file di backup
BACKUP_FILE="`date +%Y-%m-%d`_backup_repos_svn.tar.gz"

# Se non esiste il file di log, crealo
if [ ! -e "$LOGFILE" ]; then
  touch $LOGFILE
fi

for i in `find $DIR_SVN -name ‘db’`
do
  # Con questa espressione ci facciamo restituire il percorso relativo del repository
  # sul quale andremo a fare il dump dei dati
  # NOTA.
  # Per estrarre la substring la sintassi è
  # ${stringa:punto_partenza:lunghezza}
  # Per estrarre la lunghezza della stringa    
  # ${#stringa}
  REPO=`dirname "${i:${#DIR_SVN}+1:${#i}-${#DIR_SVN}}"`

  echo "`date +%Y-%m-%d` `date +%r` : $REPO" >> $LOGFILE
  echo "`date +%Y-%m-%d` `date +%r` : Creo la cartella $REPO nella dir temporanea " >> $LOGFILE

  mkdir -p $DIR_TMP/svn_backup/$REPO
  echo "`date +%Y-%m-%d` `date +%r` : Creo la cartella del backup per il repository $REPO" >> $LOGFILE
  mkdir -p $DIR_BACKUP/$REPO

  echo "`date +%Y-%m-%d` `date +%r` : Eseguo hotcopy del repository $REPO" >> $LOGFILE

  /usr/bin/svnadmin hotcopy $DIR_SVN/$REPO $DIR_TMP/svn_backup/$REPO

  echo "`date +%Y-%m-%d` `date +%r` : Eseguo il dump del repository $REPO" >> $LOGFILE
  /usr/bin/svnadmin dump "$DIR_TMP/svn_backup/$REPO" > "$DIR_BACKUP/$REPO/dump"

  echo "`date +%Y-%m-%d` `date +%r` : Rimuovo cartella temporanea" >> $LOGFILE
  rm -Rf $DIR_TMP/svn_backup/$REPO
  echo "" >> $LOGFILE
done;

# Compressione dei dump
for i in `find $DIR_BACKUP -name ‘dump’`
do
        bzip2 $i
done

tar -zcf $DIR_DUMP_TAR/$BACKUP_FILE $DIR_BACKUP

# Ripuliamo i dump …
rm -Rf $DIR_BACKUP/*

echo "`date +%Y-%m-%d-%T` … Fine" >> $LOGFILE

case $MAIL_PROG in
        mailx)
                # Su gentoo va decommentata la seguente riga
                uuenview $LOGFILE | mailx -s "Log Backup repository svn" $MAIL_DEST
        #       Questa invece va su debian
        #       uuencode $LOGFILE $LOGFILE | mailx -s "Log Backup repository svn" $MAIL_DEST
        ;;

        mutt)
                echo | mutt -a $LOGFILE -s "Log Backup repository svn" $MAIL_DEST
        ;;
esac

Carichiamo il nostro script in crontab ed il nostro backup è pronto!

Questo è tutto per ora.

PDF    Invia l'articolo in formato PDF   

Come inviare un allegato da console utilizzando mailx

Oggi vediamo come sia possibile utilizzare il comando mailx di linux in modo tale che ci venga inoltrato un allegato.

La procedura è relativamente semplice (una volta che la si conosce :D )

Allo scopo dovremo avere installato sulla macchina sia mailx (uno standard in praticamente tutte le distro) che uuencode che fa parte del pacchetto uudeview (disponibile qui).

A questo punto:

uuencode miofile.ext miofile.ext | mailx -s "Mail di prova" indirizzo@email.tld

In pratica la sintassi utilizzata da uuencode è la seguente:

  • Il primo parametro è il nome del nostro file
  • Il secondo parametro è il nome che il nostro file avrà nella mail

A questo punto se al nostro messaggio volessimo associare del testo, la cosa è abbastanza semplice.

(cat miomessaggio.txt; uuencode miofile.ext miofile.ext) | mailx -s "Mail di prova" indirizzo@email.tld

Fra le limitazioni di quest’approccio, vi è che se avete l’email su un sistema che scarta le email per domini che non riesce a risolvere, non riceverete l’email.

In questo caso, un approccio più semplice lo fornisce il pacchetto sendEmail.pl.


PDF Download    Invia l'articolo in formato PDF   

Debian Squeeze … errori in fase di upgrade di mysql?? Ecco la soluzione!!

Abbiamo eseguito un dist-upgrade da lenny a squeeze … e tutto sembra essere andato per il meglio, tranne per il fatto che mysql è rimasto alla versione precedente.

Ovviamente alcuni software, come php ci dicono che stiamo usando le librerie compilate per mysql-5.1, ma la versione del server installata è ancora la 5.0.

Quindi??
Facciamo l’update di mysql-server!!
Come prima cosa un backup del database non fa mai male tramite:

mysqldump -A –user=root –password=miapassword –add-drop-database –add-drop-table > fulldump.sql

Adesso rimuoviamo i pacchetti della versione precedente.

/etc/init.d/mysql stop
apt-get remove mysql-server mysql-client
apt-get install mysql-server mysql-client


Ma a questo punto ahimè, l’upgrade fallisce miseramente … perchè?

Il perchè è semplice!!
Se apriamo il file my.cnf troviamo:

vim /etc/mysql/my.cnf
#
# * BerkeleyDB
#
# Using BerkeleyDB is now discouraged as its support will cease in 5.1.12.
skip-bdb

Commentiamo quindi la voce skip-bdb di modo che il risultato sia

#
# * BerkeleyDB
#
# Using BerkeleyDB is now discouraged as its support will cease in 5.1.12.
#  skip-bdb

Rilanciamo

apt-get install mysql-server mysql-client

E ritorniamo a sorridere … :D
Un’ultima cosa … l’upgrade dalla versione 5.0 alla versione 5.1 non va presa alla leggera. Leggete prima qui

Word To PDF    Invia l'articolo in formato PDF   

Creare delle esclusioni dai filtri di dansguardian.

Può capitare che dopo aver configurato il proxy server, nel caso visto in precedenza era Squid3, e configurato dansguardian per settare i filtri di navigazione, ci venga chiesto, o abbiamo la necessità di creare un manipolo di utenti che devono essere esclusi dai filtri e devono poter andare ovunque e comunque.

La soluzione offerta da dansguardian, è di una semplicità disarmante.

Ci basta copiare il file con i filtri di defaullt e cambiare il valore di un parametro.

In pratica, copiamo il file dansguardanf1.conf

cp /etc/dansguardian/dansguardianf1.conf /etc/dansguardian/danguardianf2.conf

Adesso apriamo il file copiato e modifichiamolo:

vim /etc/dansguardian/dansguardianf2.conf

In cima al file troviamo la spiegazione di alcuni parametri, ma quello che interessa principalmente a noi da modificare è il parametro groupmode che nello specifico accetta questi 3 valori:

  • 0 = banned (utenti a cui è impedita la navigazione)
  • 1 = filtered (gli utenti standard, appartengono a questa categoria, o comunque se si creano gruppi diversi, si devono assegnare a questa categoria
  • 2 = unfiltered (Queste sono le eccezioni che non subiscono il filtraggio di dansguardian)

Noi quindi non faremo altro che modificare questa direttiva.

groupmode = 2


A questo punto dobbiamo modificare un altro valore all’interno di dansguardian.conf

vim /etc/dansguardian/dansguardian.conf

e modifichiamo

# Nel caso specifico in cui abbiamo 2 gruppi di filtraggio.
filtergroups = 2
filtergrouplist = ‘/etc/dansguardian/lists/filtergroupslist’

Adesso dobbiamo configurare gli utenti che possono accedere a questo filtro.
Facciamo quindi

vim /etc/dansguardian/lists/filtergrouplist

e all’interno del file la sintassi da utilizzare è la seguente:

nomeUtente=filter2
altroUtente=filter2

Riavviamo il servizio, ed il gioco è fatto.

service dansguardian restart

o in alternativa:

/etc/init.d/dansguardian restart

Come abbiamo visto, aggiungere filtri ulteriori, permette con estrema semplicità di incrementare le nostre possibilità di customizzazione.

PDF Download    Invia l'articolo in formato PDF