Mediafire: script Bash per upload di files da console

Di seguito pubblico uno script utile per chi vuole caricare su mediafire uno o più file da console senza dover utilizzare un browser web. Questo script è utile in caso di job notturni o programmi che non richiedono l’intervento dell’utente.

#!/bin/bash

#
# Copyright (c) 2011 vittorio benintende
# (vittorio@lucullo.it - http://www.morzello.com).
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the Site nor the names of its contributors
#    may be used to endorse or promote products derived from this software
#    without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE SITE AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE SITE OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#
# --- PARAMS ---
#
# login and password must be url-encoded!
#

MF_LOGIN='mediafire%40morzello.com'
MF_PWD='mypass'

# --- PARAMS ---
#
# DO NOT MODIFY LINES BELOW
#

MF_FILES="$@"

if [ "z${MF_FILES}" = "z" ]; then
	echo
	echo "No file(s) specified."
	echo
	echo "USAGE: $0 : file1 file2 ..."
	echo

	exit 1
fi

OUTPUT_FILE=$(mktemp)
COOKIE_FILE=$(mktemp)

rdom () { local IFS=\> ; read -d \< E C ;}

wget -q --save-cookies ${COOKIE_FILE} --keep-session-cookies -O /dev/null "https://www.mediafire.com/"

wget -q --load-cookies ${COOKIE_FILE} --save-cookies ${COOKIE_FILE} --keep-session-cookies --referer="https://www.mediafire.com/" \
     --post-data "login_email=${MF_LOGIN}&login_pass=${MF_PWD}&login_remember=on&submit_login.x=97&submit_login.y=18" \
     -O /dev/null "https://www.mediafire.com/dynamic/login.php"

wget -q --load-cookies ${COOKIE_FILE} --save-cookies ${COOKIE_FILE} --keep-session-cookies --referer="https://www.mediafire.com/myfiles.php" \
     -O ${OUTPUT_FILE} "https://www.mediafire.com//basicapi/uploaderconfiguration.php?45144"

UPLOAD_SESSION=$(while rdom; do
    if [[ ${E} = "upload_session" ]]; then
        echo ${C}
        exit
    fi
done < ${OUTPUT_FILE})

# echo "Upload Session = ${UPLOAD_SESSION}"

UKEY=$(while rdom; do
    if [[ ${E} = "ukey" ]]; then
        echo ${C}
        exit
    fi
done < ${OUTPUT_FILE})  

# echo "UKey = ${UKEY}"

TRACKKEY=$(while rdom; do
    if [[ ${E} = "trackkey" ]]; then
        echo ${C}
        exit
    fi
done < ${OUTPUT_FILE})

# echo "Track Key = ${TRACKKEY}"

FOLDERKEY=$(while rdom; do
    if [[ ${E} = "folderkey" ]]; then
        echo ${C}
        exit
    fi
done < ${OUTPUT_FILE})  

# echo "Folder Key = ${FOLDERKEY}"

MFULCONFIG=$(while rdom; do
    if [[ ${E} = "MFULConfig" ]]; then
        echo ${C}
        exit
    fi
done < ${OUTPUT_FILE})  

# echo "MFUL Config = ${MFULCONFIG}"

MF_USER=$(while rdom; do
    if [[ ${E} = "user" ]]; then
        echo ${C}
        exit
    fi
done < ${OUTPUT_FILE})  

# echo "User = ${MF_USER}"

for FILENAME in ${MF_FILES}; do

	SHORT_FILENAME=$(basename "${FILENAME}")
	FILESIZE=$(stat -c%s "${FILENAME}")

	wget -q --load-cookies ${COOKIE_FILE} --save-cookies ${COOKIE_FILE} --keep-session-cookies --referer="https://www.mediafire.com/myfile.php" \
	     --header="Content-Type: application/octet-stream" \
	     --header="X-Filename: ${SHORT_FILENAME}" \
	     --header="X-Filesize: ${FILESIZE}" \
	     --post-file="${FILENAME}" \
	     -O ${OUTPUT_FILE} "https://www.mediafire.com/douploadtoapi/?type=basic&ukey=${UKEY}&user=${MF_USER}&uploadkey=${FOLDERKEY}&filenum=0&uploader=0&MFULConfig=${MFULCONFIG}"

	RESKEY=$(while rdom; do
	    if [[ ${E} = "key" ]]; then
	        echo ${C}
	        exit
	    fi
	done < ${OUTPUT_FILE})

	# echo "${FILENAME} > ${RESKEY}" 

	# get result

	RUN=1

	while [ ${RUN} -eq 1 ]; do
		wget -q --load-cookies ${COOKIE_FILE} --save-cookies ${COOKIE_FILE} --keep-session-cookies --referer="https://www.mediafire.com/myfile.php" \
		     -O ${OUTPUT_FILE} "https://www.mediafire.com/basicapi/pollupload.php?key=${RESKEY}&MFULConfig=${MFULCONFIG}"

		QUICKKEY=$(while rdom; do
		    if [[ ${E} = "quickkey" ]]; then
		        echo ${C}
		        exit
		    fi
		done < ${OUTPUT_FILE})

		FILEERROR=$(while rdom; do
		    if [[ ${E} = "fileerror" ]]; then
		        echo ${C}
		        exit
		    fi
		done < ${OUTPUT_FILE})

		# echo "${QUICKKEY} ; ${FILEERROR}" 

		RUN=0
		if [ "z${FILEERROR}" = "z" ] && [ "z${QUICKKEY}" = "z" ]; then
			RUN=1

		fi

		#
		#..

		#...
		#... File too large. 1 0 
		#... File too small. 2 0 
		#... Archive is bad. 3 0 
		#... Archive is bad or password protected. 4 0 
		#... Virus found. 5 0  
		#... File already uploaded. 13 0  
		#... Archive has an unknown problem. 9 0 
		#... Invalid image. 10 0 
		#... File lost. 6 1 
		#... Error scanning file. 7 1 
		#... Disk error. 8,11 1 
		#... Database error. 12 1 
		#..
		#	

		case "${FILEERROR}" in
			1) FILEERROR=" 1 : File too large."
			;;
			2) FILEERROR=" 2 : File too small."
			;;
			3) FILEERROR=" 3 : Archive is bad."
			;;
			4) FILEERROR=" 4 : Archive is bad or password protected."
			;;
			5) FILEERROR=" 5 : Virus found."
			;;
			13) FILEERROR="13 : File already uploaded."
			;;
			9) FILEERROR=" 9 : Archive has an unknown problem."
			;;
			10) FILEERROR="10 : Invalid image."
			;;
			6) FILEERROR=" 6 : File lost."
			;;
			7) FILEERROR=" 7 : Error scanning file."
			;;
		 8) FILEERROR=" 8 : Disk error."
			;;
			11) FILEERROR="11 : Disk error."
			;;
			12) FILEERROR="12 : Database error."
			;;
			*) FILEERROR="0 : Success."
			;;
		esac

	done 

	echo "${FILEERROR} | ${FILENAME} > ${QUICKKEY}"
done

rm ${OUTPUT_FILE}
rm ${COOKIE_FILE}

Prima di iniziare
Prima di utilizzare lo script è necessario impostare i parametri di login e password in uso su medaifire. Bisogna ricordare che questi paramentri sono url-encoded; questo perchè vengono esposti direttamente nell’url di login. Ad esempio:

mediafile@morzello.com -> mediafire%40morzello.com

Usare lo script
Per utilizzare lo script basta indicare il file o i file da inviare al server:

./mfup.sh myfile.txt all.* /root/repo/*

Ricordate però che non verranno prese in considerazione le sottocartelle.

Alla prossima

BackupPC – backup dell’intero pool su nastro o file

Supponiamo che vogliate migrare una installazione di BackupPc su un’altra macchina o che vogliate fare un backup “dei backup”. Di seguito vi propongo una soluzione molto semplice che il comando dump per copiare il contenuto del pool su nastro o su file.
Perché il codice funzioni correttamente è necessario che il pool sia su un filesystem diverso da quello usato per montare la root “/”. A mio avviso, usare un mountpoint per il pool è utile non solo per il backup ma consente di ripristinare il sistema operativo senza dover spostare i dati.
supponiamo quindi che l’installazione di BackupPc sia fatta usando i percorsi di default ma utilizziamo un link che punti su un mountpoint fuori dal filesystem di root. Supponiamo di avere i seguenti mount point:

[root@morzello ~]# mount
/dev/mapper/VolGroup01-LogVol00 on / type ext3 (rw)
/dev/mapper/vgData-Data on /mnt/data type ext3 (rw)
//server-esterno/repository on /mnt/repository type cifs (rw,mand)
...

la prima cosa da fare è quella di portare l’installazione di BackupPC sotto /mnt/data creando un link simbolico su /var/lib/backuppc:

ln -s /var/lib/backuppc /mnt/data/backuppc
ls -l /var/lib/backuppc
lrwxrwxrwx  1 root  root 18 May 13  2010 backuppc -> /mnt/data/backuppc

Consiglio di creare il link prima di procedere con l’installazione altrimenti dovrete spostare i dati da un filesystem all’altro.

Lo script
Lo script non fa altro che spegnere i servizi che utilizzano il filesystem prima di procedere con il dump della partizione. Nel nostro esempio viene preso in considerazione solo BackupPc ma se ci fossero altri servizi bisogna gestirli correttamente altrimenti il comando mount usato per smontare la partizione fallirebbe:

#!/bin/bash
# Esegue il backup di /mnt/data su nastro.
# Da rirpistinare con restore rf /dev/nst0 nella
# root della partizione 

#MYDIR=$(pwd)
#cd /

echo "Controllo esecuzione backup"
ps U 'backuppc' | grep -e 'BackupPC_' && \
	echo "Impossibile proseguire. Backup in corso." && \
	exit 0

echo "Stop ai servizi che accedono alla partizione"
/sbin/service backuppc stop
/sbin/service backuppc_httpd stop

echo "Smontaggio della partizione"
/bin/umount /mnt/data

echo "Controllo con fsck"
/sbin/fsck.ext3 /dev/vgData/Data

echo "dump della partizione su nastro"

#backup su nastro:
/sbin/dump -0 -a -f /dev/nst0 -b64 -j9 /dev/vgData/Data

#backup su file
#/sbin/dump -0 -a -f /mnt/repository/backuppc-dump.bz -b64 -j9 /dev/vgData/Data

echo "Montaggio della partizione"
/bin/mount /mnt/data

echo "Riavvio dei servizi che accedono alla partizione"
/sbin/service backuppc start
/sbin/service backuppc_httpd start

#cd $MYDIR
echo "Fatto."

Prima di eseguire il dump lo script controlla che non vi siano backup in esecuzione da parte dell’utente backuppc. Anche in questo caso se l’utente fosse diverso è necessario modificare il codice.
Il servizio backuppc_httpd è una istanza di apache modificata proprio per backuppc; per maggiori informazioni visitare questo link:

http://www.morzello.com/index.php/installare-backuppc-su-centos/

Se invece utilizzate l’istanza di default potete sostituire il servizio con httpd.
Per quanto riguarda la destinazione, se non aveste a disposizione una unità a nastro potete cambiare il percorso di destinazione ovunque vogliate. Prendendo come esempio il comando mount indicato in precedenza potremmo ad esempio creare un file sotto /mnt/repository

Alla prossima.

Data remanence con dd e shred, un modo economico e sicuro per cancellare i dati su disco.

Qualche giorno fa un amico mi chiese un parere su alcuni programmi per la cancellazione sicura dei dati perchè aveva un portatile che avrebbe dovuto restituire da li a breve.  Mi chiese anche se la formattazione a basso livello era una opzione oppure no.

Intanto c’è da rilevare che la richiesta è del tutto legittima dal momento che la semplice cancellazione del dato all’interno del sistema operativo è il più delle volte insufficiente. In effetti esiste un problema legato alla persistenza dei dati dopo la cancellazione (Data Remanence). Per maggiori informazioni visitare la wikipedia:

http://en.wikipedia.org/wiki/Data_remanence

Esistono tanti programmi, alcuni anche molto costosi, in grado di riscrivere diverse volte dati arbritari sul disco al fine di eliminare la persistenza dei dati (Overwriting) ma io ho pensato che ancora una volta il comando dd poteva essere utile, veloce e sopratutto gratuito.

Per maggiori informazioni sull’uso di dd potete visitare l’articolo:

http://www.morzello.com/?p=28

L’idea di base è quella di utilizzare dd per sovrascrivere il contenuto dell’intero disco eseguendo il comando diverse volte utilizzando /dev/urandom come input.

/dev/urandom sui sistemi unix-like è un file particolare in grado di generare un flusso binario pseudo casuale che viene utilizzato a vari scopi come ad esempio la crittografia.

A questo punto, per cancellare completamente il contenuto di un disco, potremmo impartire il comando:

dd if=/dev/urandom of=/dev/sdX

dove sdX è il disco in questione.
Ovviamente la soluzione proposta presuppone la cancellazione dei dati sull’intero disco e non consente la sovrascittura in caso di singoli file come ad esempio è possibile fare tramite il comando shred ma è comunque un’idea come un’altra di portare a termine il lavoro a basso costo.

Usare shred
shred invece nasce proprio per sovrascrivere e nascondere o cancellare il contenuto di file. Ovviamente, dato che /dev/sdX è anche esso un file, è possibile ottenere un ottimo risultato impartendo il comando:

shred -n N -zv /dev/sdX

dove N è il numero di scritture da fare mentre -z provvede a fare l’ultima scritura con una serie di zeri al fine di nascondere l’esecuzione del programma (come se fosse stato impartito un semplice dd if=/dev/zero of=/dev/sdX).

Alla prossima.

Creazione di una Certification Authority con CentOS/Fedora (Parte II)

Continuando il discorso iniziato nell’articolo precedente, di seguito riportiamo i comandi necessari per installare una propria Certification Authority creata con OpenSSL.

Quasi tutte le installazioni di Linux (Fedora e CentOS compresi) fanno uso di OpenSSL. Per accertarsi che sia installato è sufficiente scrivere nella shell:

OpenSSL

Se tutto è ok comparirà il prompt dei comandi del programma (per uscire scrivere quit e premere invio).

Chi dovesse installare il pacchetto può scrivere invece:

yum install openssl

A differenza di altre distribuzioni, in Red Hat i files di configurazione di OpenSSL risiedono nella cartella “/etc/pki/tls”. Il primo passo consiste nel creare una nuova directory dove conservare tutti i files necessari alla nostra CA. Per non incorrere in problemi dovuti alle policy di selinux, in questo esempio utilizzeremo la cartella “/etc/pki/CA” (l’utente può usare comunque un altro percorso).

Una volta scelta la destinazione è necessario creare alcune sottocartelle:

  • certs – cartella in cui verranno sistemati i certificati;
  • crl – cartella dedicata alla revoca dei certificati;
  • newcerts – cartella utilizzata da openssl per creare i certificati nella forma non criptata
  • private – cartella contenente le chiavi private. Questa cartella dovrebbe essere di sola lettura e trattata con estrema cura dal momento che contiene la parte più intima della CA.

Oltre alle cartelle, bisogna creare alcuni file:

  • index.txt – file che fungerà da database;
  • serial – file che contiene il numero progressivo dei certificati segnati;
  • crlnumber – (facoltativo) contiene il numero successivo da utilizzare nella lista dei certificati revocati;

Per comodità, di seguito trovate i comandi necessari per creare l’ambiente:

cd /etc/pki/CA
mkdir certs crl newcerts private
touch index.txt
echo "01" > serial
chmod 0755 *

Fatto questo, passiamo alla modifica del file di configurazione openssl.cnf che si trova nella cartella /etc/pki/tls. Prima di procedere oltre però sarebbe bene fare una copia di backup.

[ CA_default ]
  dir = /etc/pki/CA
  x509_extensions = v3_ca
  countryName_default = IT
  stateOrProvinceName_default = Calabria
  0.organizationName_default = Catanzaro

In alto abbiamo riportato solo le righe che sono state modificate.

Per quanto concerne il parametro x509_extensions vi sono alcune considerazioni da fare. Si tratta di un parametro che indica quale sezione del file di configurazione prendere in considerazione quando vengono creati i certificati (relativamente alle estensioni x509). Poichè la sezione usr_cert (valore di default) contiene alcuni parametri che devono essere correttamente impostati per creare certificati validi in ambiente MS-Windows, si è preferito sostituirla con v3_ca che non necessita di personalizzazioni; ricordiamo che questo articolo non tratta tutti gli argomenti relativi al file di configurazione di openssl.

Se non sono state apportate modifiche al file di configurazione diverse da quelle specificate in precedenza, per creare una CA è sufficiente impartire il seguente comando:

openssl req -config /etc/pki/tls/openssl.cnf \
    -new -x509 -days 7200 -keyout /etc/pki/CA/private/cakey.pem \
    -out /etc/pki/CA/cacert.pem

É ovvio che i percorsi indicati nel comando devono rispecchiare la configurazione altrimenti il certificato non verrà utilizzato dal sistema operativo. Il certificato creato avrà una durata di 20 anni, probabilmente è un periodo di tempo eccessivo.

A questo punto viene richiesta una pass phrase ed i campi del certificato:

Generating a 1024 bit RSA private key
.................++++++
.........++++++
writing new private key to '/etc/pki/CA/private/cakey.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [GB]:IT
State or Province Name (full name) [Berkshire]:Catanzaro
Locality Name (eg, city) [Newbury]:Catanzaro
Organization Name (eg, company) [My Company Ltd]:Morzello Blog
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:morzello.com
Email Address []:noreply@morzello.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:ScegliUnaPassword
An optional company name []:Morzello Blog

La pass phrase non deve essere intesa come una password, in effetti viene rischiesta una “frase segreta” che dorà essere custodita con cura.

La challenge password invece viene usata per evitare le la chiave privata venga conservata in chiaro sul disco.

Creazione dei certificati

La creazione dei certificati è relativamente semplice e si compone di due fasi: nella prima viene fatta una richiesta di certificazione mentre nella seconda la richiesta viene segnata digitalmente.

In linea di principio non c’è differenza tra i certificati emessi per un server e quelli emessi per un client; a variare è l’uso che se ne fa del certificato. In genere, la chiave privata del certificato non viene conservata in chiaro ma viene anch’essa sottoposta a crittografia mediante la richiesta di una password. Nel caso di servizi server però questa politica è difficilmente applicabile poichè all’avvio del server tipicamente non vi è nessuno in gradi di digitare una password. Conservare la password in chiaro non ha senso e quindi i certificati per i server non contemplano la crittografia per la chiave privata.

Richiesta di certificati server

OpenSSL può essere utilizzato anche per emettere le richieste di certificazione. Di seguito vediamo un esempio applicabile ai certificati server:

openssl req -config /etc/pki/tls/openssl.cnf -new -nodes -days 730 \
     -keyout /etc/pki/CA/private/new.key \
     -out /etc/pki/CA/newcerts/new_req.pem

Il parametro -nodes evita proprio che il certificato venga sottoposto a crittografia triple des.

Dopo aver eseguito il comando si procederà con la compilazione dei campi necessari:

Generating a 1024 bit RSA private key
........++++++
..........++++++
writing new private key to '/etc/pki/CA/private/new.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [GB]:IT
State or Province Name (full name) [Berkshire]:Italy
Locality Name (eg, city) [Newbury]:Torino
Organization Name (eg, company) [My Company Ltd]:Morzello Blog
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:www.morzello.com
Email Address []:noreply@morzello.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:test
An optional company name []:

Richiesta di certificati client

Per i client la richiesta è del tutto simile ma in questo caso, possiamo usare la crittografia a protezione della chiave privata:

openssl req -config /etc/pki/tls/openssl.cnf -new -days 730 \
     -keyout /etc/pki/CA/private/new.key \
     -out /etc/pki/CA/newcerts/new_req.pem

A titolo esemplificativo riportiamo l’output del comando precedente:

Generating a 1024 bit RSA private key
.++++++
.......++++++
writing new private key to '/etc/pki/CA/private/new.key'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [GB]:IT
State or Province Name (full name) [Berkshire]:Calabria
Locality Name (eg, city) [Newbury]:Catanzaro
Organization Name (eg, company) [My Company Ltd]:Morzello Blog
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:client.morzello.com
Email Address []:noreply@morzello.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:test
An optional company name []:

Come è possibile notare, in questo caso viene richiesta una pass phrase per il certificato.

Firmare digitalmente le richieste

Dopo aver creato la richiesta possiamo passare alla sua firma (sign). Per farlo possiamo usare la nostra CA:

openssl ca -config /etc/pki/tls/openssl.cnf \
     -policy policy_anything \
     -out /etc/pki/CA/certs/new.crt \
     -infiles /etc/pki/CA/newcerts/new_req.pem

Il risultato sarebbe del tutto simile al seguente:

Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for /etc/pki/CA/private/cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: Jun 30 09:18:53 20xx GMT
            Not After : Jun 30 09:18:53 20yy GMT
        Subject:
            countryName               = IT
            stateOrProvinceName       = Calabria
            localityName              = Catanzaro
            organizationName          = Morzello Blog
            commonName                = client.morzello.com
            emailAddress              = noreply@morzello.com
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                0A:AF:2C:D3:55:29:86:33:FC:D2:9A:A4:AF:90:42:AB:BD:17:01:29
            X509v3 Authority Key Identifier:
                keyid:30:16:68:ED:CD:61:20:61:F3:D0:BA:17:35:2A:74:87:E4:D3:A1:32
                DirName:/C=IT/ST=Calabria/L=Catanzaro/O=Vittorio Benintende/CN=client.morzello.com/emailAddress=noreply@morzello.com
                serial:09:DB:34:A3:DA:3F:56:BC

            X509v3 Basic Constraints:
                CA:TRUE
Certificate is to be certified until Jun 30 09:18:53 20xx GMT (365 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

A questo punto possiamo eliminare la richiesta:

rm /etc/pki/CA/newcerts/new_req.pem

Verifiche e test sui certificati

Per visualizzare le informazioni relative ad un certificato basta indicare gli argomenti che interessano, come ad esempio: l’emittente, la data di scadenza, l’hash md5, il fingerprint, …

openssl x509 -noout -subject -issuer -enddate -hash -fingerprint -in /etc/pki/CA/certs/new.crt

Il parametro -noout indica ad openssl che non c’è un output da gestire.

Per verificare la validità di un certificato si può utilizzare il comando:

openssl verify -CAfile /etc/pki/CA/cacert.pem /etc/pki/CA/certs/new.crt
/etc/pki/CA/certs/new.crt: OK

Installare i certificati in Windows

In Windows l’installazione dei certificati merita un po’ di attenzione perchè è necessario fare una conversione se si utilizza l’esempio riportato in alto. Per metabolizzare il certificato infatti Windows ha bisogno del formato PKCS#12. Per ottenere questo possiamo utilizzare il seguente comando:

openssl pkcs12 -export -in /etc/pki/CA/certs/new.crt \
-inkey /etc/pki/CA/private/new.key -out /etc/pki/CA/certs/new.p12 -clcerts

A questo punto viene eventualmente richiesta la password per l’esportazione del certificato.

Per importare i certificati e le CA all’interno del sistema operativo basta cliccare sul file e seguire le istruzioni del wizard proposte a video. Un certificato può essere installato per il singolo utente o per la macchina (con credenziali amministrative).

Se si desidera avere maggior controllo si può invece utilizzare la Microsoft Management Console (mmc.exe)  aggiungendo l’apposito snap-in:

file -> aggiungi/rimuovi snap-in...
aggiungi -> certificati -> account del computer

Dovreste trovarvi in una situazione simile a quella riportata in foto:


Alla prossima.

OpenVPN – NTLM e quel proxy infame

Questo articolo è rivolto a coloro che hanno problemi a far dialogare OpenVPN con proxy che richiedono autenticazione NTLM.

Al momento della stesura di questo articolo, la versione di ovpn è la 2.1.3, versioni successive a questa potrebbero non soffrire dello stesso male.

Utilizzando l’autenticazione di tipo NTLM ho notato che la comunicazione si interrompe subito dopo l’invio del messaggio di tipo 1 da parte del client. In pratica il proxy non si degna di dare una risposta negativa o positiva che sia.

Per maggiori informazioni sulla comunicazione tipo NTLM potete visitare il sito:

http://davenport.sourceforge.net/ntlm.html

Dando uno sguardo al codice sorgente ho notato che la stringa inviata dal client al proxy è la seguente:

TlRMTVNTUAABAAAAAgIAAA==

ed è una costante definita nel file ntlm.c

Dopo aver portato a termine qualche prova con uno sniffer di rete mi sono accorto che altri prorammi come ad esempio firefox, funzionano perfettamente con il proxy così mi sono chiesto quali fossero le differenze. In effetti il messaggio di fase 1 inviato dal browser è sostanzialmente diverso:

TlRMTVNTUAABAAAAB4IIogAAAAAAAAAAAAAAAAAAAAAFASgKAAAADw==

e sembra essere più gradito.

A questo punto ho modificato il codice sorgente nell’unica riga necessaria:

const char *
ntlm_phase_1 (const struct http_proxy_info *p, struct gc_arena *gc)
{
  struct buffer out = alloc_buf_gc (96, gc);
  /* try a minimal NTLM handshake
   *
   * http://davenport.sourceforge.net/ntlm.html
   *
   * This message contains only the NTLMSSP signature,
   * the NTLM message type,
   * and the minimal set of flags (Negotiate NTLM and Negotiate OEM).
   *
   */
  // buf_printf (&out, "%s", "TlRMTVNTUAABAAAAAgIAAA==");
   buf_printf (&out, "%s", "TlRMTVNTUAABAAAAB4IIogAAAAAAAAAAAAAAAAAAAAAFASgKAAAADw==");
  return (BSTR (&out));
}

e dopo aver ricompilato l’eseguibile, tutto funziona correttamente.

Alla prossima.

Pentaho – Avviare il servizio al boot. Uno script per CentOS, Fedora e RHEL

Ho visto che in giro non è ancora stato pubblicato uno script per l’avvio automatico di pentaho su sistemi linux derivati da Red Hat così ho pensato di mettere online il mio:

#!/bin/bash
#
# chkconfig: - 92 36
# description: Starts and stops pentaho.

# Source function library.
. /etc/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0

unset BASH_ENV ENV

PUSER="pentaho"
PENTAHO_HOME="/opt/pentaho/biserver-ce"
JAVA_HOME="/usr/lib/jvm/jre-1.6.0/"
prog=$"Pentaho server"
logfile="${PENTAHO_HOME}/pentaho.log"

if [ -e "${logfile}" ]; then
    rm -f "${logfile}" > /dev/null
fi

cd ${PENTAHO_HOME}
. "${PENTAHO_HOME}/set-pentaho-java.sh"

if [ -d "${PENTAHO_HOME}/jre" ]; then
    setPentahoJava "${PENTAHO_HOME}/jre" >> ${logfile} 2>&1
else
    setPentahoJava >> ${logfile} 2>&1
fi

PENV="export _PENTAHO_JAVA_HOME=${_PENTAHO_JAVA_HOME} && export _PENTAHO_JAVA=${_PENTAHO_JAVA} && export JAVA_OPTS='-Djava.awt.headless=true' && export JAVA_HOME=${_PENTAHO_JAVA_HOME}"

start() {
    echo -n $"Starting $prog: "

    if [ -e "${PENTAHO_HOME}/promptuser.sh" ]; then
        sh "${PENTAHO_HOME}/promptuser.sh" >> ${logfile} 2>&1
        rm "${PENTAHO_HOME}/promptuser.sh"
    fi

    if [ "$?" = 0 ]; then
        /sbin/runuser -l ${PUSER} -c "${PENV} && cd '${PENTAHO_HOME}/data' && sh ./start_hypersonic.sh & " >> ${logfile} 2>&1 && \
        /sbin/runuser -l ${PUSER} -c "${PENV} && cd '${PENTAHO_HOME}/tomcat/bin' && export CATALINA_OPTS='-Xms256m -Xmx768m -XX:MaxPermSize=256m -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000' && sh ./startup.sh" >> ${logfile} 2>&1 && echo "OK" || echo "ERROR"

    fi

}

stop() {
    echo -n $"Shutting down $prog: "

    /sbin/runuser -l ${PUSER} -c "${PENV} && cd '${PENTAHO_HOME}/data' && sh ./stop_hypersonic.sh & "  >> ${logfile} 2>&1 && \
    /sbin/runuser -l ${PUSER} -c "${PENV} && cd '${PENTAHO_HOME}/tomcat/bin' && sh ./shutdown.sh"  >> ${logfile} 2>&1 && echo 'OK' || echo "ERROR"

}

# See how we were called.
case "$1" in
  start)
	start
	;;
  stop)
	stop
	;;
  restart)
	stop
	sleep 3
	start
	;;
  status)
	ps U 'pentaho' | grep -e 'sh ./start_hypersonic.sh' >> /dev/null && echo "$prog is running" || echo "$prog is stopped"
	;;
  *)
	echo $"Usage: $0 {start|stop|restart}"
	exit 1
esac

Ovviamente sarà necessario configurare le variabili in base alla installazione di Pentaho.

Alla prossima.

MySQL – abilitare l’accesso a root dalla rete

Può capitare a volte di voler accedere all’istanza presente su una macchina dalla quale non è possibile utilizzare strumenti visuali quali:

  • MySQL Administrator
  • MySQL Workbench

è ad esempio il caso di CentOS, dove questi strumenti sono difficili da installare. A mio avviso un metodo veloce per arginare il problema è quello di utilizzare il comando mysql in locale per abilitare l’accesso all’utente root dalla rete. Una volta apportate tutte le modifiche del caso, sarà sufficiente ristabilire le restrizioni volute.

Per accedere alla console di mysql basta usare il comando:

mysql -uroot -p

dopo aver digitato la password ci ritroveremo nell’ambiente del db e potremo abilitare l’accesso dall’esterno con due comandi:

grant all privileges on mysql.* to root@"NOMEPC" identified by 'MIA_PASSWORD';
flush privileges;

Dove NOMEPC è l’indirzzo della macchina dalla quale vogliamo accedere (indicando ‘%’ abilitiamo tutta la rete) e MIA_PASSWORD è la password che vogliamo usare per la connessione.

Ora è possibile fare le modifiche del caso da un altro pc.

Alla prossima.

CentOS: accedere alle partizioni NTFS

Capita a volte di dover accedere a partizioni Windows (NTFS) da Linux ma non tutte le distribuzioni supportano nativamente la lettura/scrittura di queste partizioni. CentOS in particolare non ha il supporto a queste partizioni ne dentro il kernel ne dentro il repository ufficiale.

E’ comunque possibile accedere alle partizioni di Windows mediante il pacchetto fuse disponibile sul repository di rpmforge. Per maggiori informazioni su come aggiungere ed abilitare un repository aggiuntivo per CentOS, potete consultare questo link:

http://www.morzello.com/dblog/articolo.asp?articolo=68

Nell’esempio che segue, vedremo come montare una partizione ntfs in una cartella di linux come ad esempio /mnt/usb.

Per prima cosa, verifichiamo la tavola delle partizioni del disco. Nel nostro caso si tratta di un disco usb esterno:

fdisk -l /dev/sdb

Disk /dev/sdb: 250.0 GB, 250059350016 bytes
255 heads, 63 sectors/track, 30401 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1       15298   122881153+   6  FAT16
/dev/sdb2           15299       22947    61440592+   7  HPFS/NTFS

Nel caso volessimo montare la seconda partizione senza supporto, riceveremmo un messaggio simile a questo:

mount /dev/sdb2 /mnt/usb
mount: unknown filesystem type 'ntfs'

Per risolvere il problema procediamo dunque all’installazione dei pacchetti necessari dal repository di rpmforge:

yum install fuse fuse-ntfs-3g
Loaded plugins: fastestmirror, priorities
Determining fastest mirrors
 * addons: ftp.uni-bayreuth.de
 * base: ftp.uni-bayreuth.de
 * extras: ftp.uni-bayreuth.de
 * rpmforge: apt.sw.be
 * updates: ftp.hosteurope.de
addons                                                   |  951 B     00:00
base                                                     | 2.1 kB     00:00
extras                                                   | 2.1 kB     00:00
rpmforge                                                 | 1.1 kB     00:00
updates                                                  | 1.9 kB     00:00
updates/primary_db                                       | 554 kB     00:00
478 packages excluded due to repository priority protections
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package fuse.i386 0:2.7.4-8.el5 set to be updated
---> Package fuse-ntfs-3g.i386 0:2009.11.14-1.el5.rf set to be updated
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package            Arch       Version                     Repository      Size
================================================================================
Installing:
 fuse               i386       2.7.4-8.el5                 base            83 k
 fuse-ntfs-3g       i386       2009.11.14-1.el5.rf         rpmforge       552 k

Transaction Summary
================================================================================
Install      2 Package(s)
Update       0 Package(s)
Remove       0 Package(s)

Total download size: 635 k
Is this ok [y/N]: y
Downloading Packages:
(1/2): fuse-2.7.4-8.el5.i386.rpm                              |  83 kB     00:00
(2/2): fuse-ntfs-3g-2009.11.14-1.el5.rf.i386.rpm              | 552 kB     00:00
--------------------------------------------------------------------------------
Total                                                352 kB/s | 635 kB     00:01
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing     : fuse                                                      1/2
  Installing     : fuse-ntfs-3g                                              2/2

Installed:
  fuse.i386 0:2.7.4-8.el5
  fuse-ntfs-3g.i386 0:2009.11.14-1.el5.rf

Complete!

Ora è possibile ripetere il comando mount come mostrato in precedenza.

Alla prossima.

Usare Ping In Script Batch

Tempo fa avevo presentato un articolo che mostra come utilizzare il comando ping all’interno di un batch script:

http://www.morzello.com/dblog/articolo.asp?articolo=41

Come spiegato, il comando restituisce sempre lo stesso errorlevel, rendendo vano un eventuale tentativo di capire se il ping è andato a buon fine o meno all’interno di uno script.

Oggi presento una variante che consente di ottenere lo stesso risultato senza dover scrivere codice vbscript.

Di seguito trovate un piccolo file .BAT (o .CMD) che potete utilizzare per testare l’esito di un ping:

ping nomeserver | findstr "TTL="
echo %errorlevel%

Mentre il comando ping restituisce sempre lo stesso errorlevel, findstr discrimina l’uscita a seconda che nell’output esista o meno una corrispondenza utile. A questo punto possiamo testare l’uscita del comando findstr invece che di ping.

Alla prossima.

Resize di partizioni LVM

Mi è capitato di recente, di dover migrare un piccolo server Linux su un server ESXi 4. La memoria ram della versione virtualizzata è stata espansa di 512 MB rendendo necessario una espansione della partizione di swap. Come accade per diverse distribuzioni che utilizzano LVM per gestire il file system (CentOS, Fedora,…) per variare le dimensioni di una partizione (resizing) bisogna tenere in considerazione alcuni fattori critici come ad esempio il rischio di perdere dati importanti presenti sul disco.

L’esempio che segue mostra come ridurre la partizione LVM destinata al sistema operativo al fine di estenderne quella di swap. I comandi elencati però possono essere utilizzati ovunque sia necessario fare il resize di partizioni LVM.

Individuare e gestire le partizioni LVM
Nel caso in cui il sistema operativo sia stato installato come consigliato dalla distribuzione, allora i volumi logici presenti sul disco conterranno l’intera distribuzione ad esclusione della partizione di boot. Questo vuol dire che per accedere al disco per fare le opportune modifiche è necessario accedervi dall’esterno. Per fare questo è sufficiente fare il boot da chiavetta usb o da distribuzione live.

A me piace tanto Fedora, di conseguenza, per questo esempio, prenderò in considerazione il cd live di Fedora, disponibile sul sito:

http://fedoraproject.org/get-fedora

Una volta fatto il boot da cdrom avremo la possibilità di verificare l’esistenza di partizioni LVM sul disco fisso. Basta aprire una finestra terminale ed impartire i seguenti comandi con credenziali di root:

[root@localhost liveuser]# su
[root@localhost liveuser]# pvscan
  PV /dev/sda2   VG VolGroup01   lvm2 [79.88 GB / 0    free]
  Total: 1 [79.88 GB] / in use: 1 [79.88 GB] / in no VG: 0 [0   ]

[root@localhost liveuser]# vgscan
  Reading all physical volumes.  This may take a while...
  Found volume group "VolGroup01" using metadata type lvm2

[root@localhost liveuser]# lvscan
  ACTIVE            '/dev/VolGroup01/LogVol00' [78.88 GB] inherit
  ACTIVE            '/dev/VolGroup01/LogVol01' [1.00 GB] inherit

Si tratta di un disco da 80 GB  (sda) con due partizioni fisiche: sda1 per il boot ed sda2 per LVM.
Dai comandi impartiti si evince che il dispositivo /dev/sda2 contiene un gruppo logico (VolGroup01) con due partizioni (LogVol00 per il sistema operativo e LogVol01 per lo swap).

Prima di procedere con il resize delle partizioni logiche bisogna essere certi che non vi siano dati nella parte finale del primo volume (LogVol00) altrimenti questi saranno irrimediabilmente persi. Questa considerazione va fatta dal momento che per aggiungere un numero variabile di byte alla partizione di swap, bisogna prima sottrarli a quella del sistema operativo. Ovvio che se la partizione del SO è piena, il resize non sarà possibile.

Il resize delle partizioni logiche
Poichè LogVol00 è di tipo ext3, possiamo deframmentare l’unità in modo da lasciare libero lo spazio in coda (shrinking):

[root@localhost liveuser]# e2fsck -f /dev/VolGroup01/LogVol00
e2fsck 1.41.9 (22-Aug-2009)
Adding dirhash hint to filesystem.

Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information

/dev/VolGroup01/LogVol00: ***** FILE SYSTEM WAS MODIFIED *****
/dev/VolGroup01/LogVol00: 107628/20676608 files (1.3% non-contiguous), 1409699/20676608 blocks

Fatto questo procediamo con il resize della partizione ext3

[root@localhost liveuser]# resize2fs /dev/VolGroup01/LogVol00 77880M
resize2fs 1.41.9 (22-Aug-2009)
Resizing the filesystem on /dev/VolGroup01/LogVol00 to 19937280 (4k) blocks.
The filesystem on /dev/VolGroup01/LogVol00 is now 19937280 blocks long.

Con il comando precedente abbiamo tolto alla partizione 1 G definendo le nuove dimensioni (77880M)

Adesso finalmente possiamo contrarre la partizione logica del primo volume ed estendere la seconda:

[root@localhost liveuser]# lvresize /dev/VolGroup01/LogVol00 --size -1G
  WARNING: Reducing active logical volume to 77.88 GB
  THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce LogVol00? [y/n]: y
  Reducing logical volume LogVol00 to 77.88 GB
  Logical volume LogVol00 successfully resized

[root@localhost liveuser]# lvresize /dev/VolGroup01/LogVol01 --size +1G
  Extending logical volume LogVol01 to 2.00 GB
  Logical volume LogVol01 successfully resized

In questo caso abbiamo utilizzato valori relativi (-/+1 G)

Per finire, possiamo procedere con la formattazione della nuova partizione di swap

[root@localhost ~]# mkswap /dev/VolGroup01/LogVol01
Setting up swapspace version 1, size = 2147479 kB

Dopo un reboot tutto è pronto.
Alla prossima.