Archivi tag: Linux

tux-banner

Come consentire la scrittura di un file di sistema ad un utente ordinario

Più che di svelare chissà quale segreto, l’intento di questo post è di costituire un quasi memorandum per amministratori (e non solo).

Parliamo di scrittura, non necessariamente di condivisione della proprietà del file: pertanto sono esclusi gruppi più o meno esoterici, ACL o altri sistemi basati su privilegi su filesystem.

Ovviamente la soluzione residua è un’assegnazione di diritti amministrativi al processo di scrittura, e quindi una soluzione basata su sudoers.

Naturalmente occorre trovare una mediazione tra rispetto della sicurezza del resto del sistema e una certa flessibilità del meccanismo.

La sicurezza la imponiamo fissando nella lista comandi della regola sudoers il nome assoluto del particolare file di sistema su cui delegare il privilegio di scrittura.

La flessibilità del meccanismo la otteniamo considerando la sorgente dei dato non originante da altro argomento di un comando da attivare con sudo (vedi cp), ma invero dallo standard input del comando da attivare, implicando quindi un ulteriore processo di delega.

Per ragioni di opportunità e di semplicità di realizzazione in termini di sintassi sudoers la scelta del comando ricade su /usr/bin/tee.

Ponendo in /etc/sudoers la seguente:

utente ALL = (root) NOPASSWD: /usr/bin/tee /file/protetto

l’utente ordinario potrà modificare il file di sistema (protetto) assumendo temporaneamente i privilegi amministrativi; dovrà  quindi scrivere:

cat /file/sorgente | sudo '/usr/bin/tee /file/protetto' >/dev/null

Ovviamente la cosa potrà estendersi oltre il contesto locale con:

cat /file/sorgente/locale | ssh -t utente@host.remoto sudo /usr/bin/tee /file/protetto/su/host/remoto

dove opzione -t è fondamentale perché ssh possa lavorare in pipe eseguendo un sudo remotamente.

Speriamo di aver fornito un contributo per risolvere uno dei più  classici problemi di sicurezza di un sistema.

diversamenteArte

Diversamente Arte (Parte II)

Partendo dalle specifiche del formato file per la trascrizione musicale dettate nel precedente post costruire un programma (script) capace di trasformare la nostra partitura in sequenze di comandi beep (o sequenza di argomenti per lo stesso) é cosa assai semplice.

La scelta del linguaggio di programmazione é ovviamente orientata alla omogeneità con l’ambiente di utilizzo del risultato, ovvero shell (in particolare bash >4.0), ma nulla vieta di realizzare il nostro programma per BeepMusic con altra tecnologia.

II nostro prototipo é capace di produrre varie forme di BeepMusic secondo la compatibilità con le possibili implementazioni del comando beep (Linux e FreeBSD).

Il cuore del software è il calcolo della durata delle note in ragione delle impostazioni metriche della partitura:

duration_in_millisec = n * 60000 / BPM / x;

dove n è il numeratore della frazione che indica la divisione di tempo (time signature) ed x è il denominatore della frazione che rappresenta la singola durata della nota. Questo viene calcolato per tutte le possibili durate di nota, ossia 1 2 4 8 16 32 64 128.

Le frequenze per le note sono semplicemente estratte da un array
pre-calcolato e posto in un file accessorio (potete “accordare” a piacimento lo “strumento” beep).

Qualche accorgimento per produrre output compatibile con le differenti implementazioni di beep ed il gioco é fatto!

Il software completo é scaricabile da GitHub (https://github.com/andrea-tassotti/beepmusic).

Buon ascolto!

diversamenteArte

Diversamente Arte (prima parte)

Arte ed Informatica si sono incontrate piú volte dalla nascita di quest’ultima.

L’Informatica ha creato nel tempo strumenti a supporto dell’Arte parlando la lingua dell’Arte (dalla conservazione per via digitale di capolavori alla creazione di nuovi strumenti); ma ha saputo dare all’Arte (o meglio agli artisti) anche nuovi linguaggi (e i conseguenti strumenti).

Molti strumenti sono divenuti di uso quotidiano in molte realtà ove l’Arte é anche industria (si pensi agli strumenti di fotoritocco, di modellazione 3D o per la produzione audio-video); altri sono rimasti pura sperimentazione o passatempo per informatici estrosi (e con molto tempo libero).

Di questa “diversa Arte” o “Arte diversa” vogliamo parlare in questo post.

Avrete certo visto forme di ASCII Art, ossia immagini create in documenti testo da caratteri la cui forma e posizione fanno credere a differenti livelli di tono tanto da illudere a sufficienza l’osservatore. Per lo più realizzate con carattere tipografo a corpo fisso (come nella “old school” in voga nel mondo Amiga) o nelle forme piú estreme con corpo variabile e colori (addirittura video con la AAlib di Linux), queste forme d’arte hanno abbellito, decorato o commentato manuali, programmi e quant’altro.

Da notare che anche gli emoticons noti ai piú nascono come forma minimalista di Ascii Art:

:-)

Su YouTube potreste trovare “composizioni per aghi e carta” (avete letto bene!): c’é chi ha “accordato” la propria stampante a matrice di aghi per eseguire composizioni musicali.

Ci sono artisti che amano creare Photographic Mosaic (o Photomosaic), ossia usare immagini come punti per una immagine piú grande frutto di questa composizione; oppure ce ne sono altri un po’ retro’ che si cimentano nella Pixel Art (puntillismo), ossia disegnano un pixel alla volta, con pazienza infinita.

Esistono programmi che consentono a musicisti di generare suoni o musiche a partire da una immagine, o consentono di imprimere il  volto dell’autore nello spettro audio di una composizione (in modo cioé che uno spettrogramma riproduca una immagine di tale volto: è un vezzo questo che si è concesso I’artista Aphex Twin (al secolo Richard David James).

Molti piú dettagli e molte altri modi di fare arte con i computer possono essere approfonditi cercando il termine “demoscene” su Wikipedia.

E veniamo all’esempio di “diversa arte” di cui vogliamo ampliare la conoscenza.

Non tutti sanno che le motherboard di PC e Server sono dotate di beeper (emettitore acustico tipicamente piezoelettrico). Spesso la sua presenza è rilevabile solo nelle fasi pre-boot, nell’accesso al BIOS, e altre “fasi hardware”.

Per sistemisti (o utenti) UNIX il “beep” è una presenza immanente, sin dai tempi dei terminali “telescriventi”: ma anche tra questi sono pochi a conoscere che il beeper può essere “accordato” ad emettere suono di altezza e lunghezza differenti dal classico “beep” (tipicamente 750Hz per 200msec).

Pochi non vuol dire nessuno: utilizzando il comando beep, sia su sistemi FreeBSD, sia su sistemi Linux (con differenti implementazioni), “diversamente artisti” hanno potuto sequenziare l’emissione sonora e temporale del beeper per eseguire musica, benché monofonica (una sola voce) e monotimbrica (un solo colore).

Tra questi artisti, molti lavorano direttamente sui parametri del comando beep (frequenza in Hz e tempo in msec (o cent sec nel caso FreeBSD).
I piú raffinati tentano un approccio con convertitori da MIDI SMF a sequenza di comandi beep (o sequenza di suoi parametri nella implementazione Linux).

Entrambi gli approcci hanno dei problemi: il primo è certamente un metodo “innaturale” e “complicato”; il secondo si deve scontrare con il limite monofonico (innaturale nelle trascrizioni MIDI di musica) e con i problemi della quantizzazione del tempo che può tradursi in una caotica quantità di esecuzioni di comandi beep (o suoi parametri) per mimare il timing degli eventi MIDI.

Il sistema MIDI si basa infatti sulla successione di eventi note on e note off, nell’ottica di una meccanica key pressed (on) e key released (off): questo metodo é perfetto per “registrare” esattamente l’esecuzione di un brano da parte di un musicista su uno strumento di input MIDI (come una keyboard): la riproduzione sarà esattamente uguale (con precisione molto, molto elevata): in questo é cruciale il riferimento temporale (relativo tra due eventi o assoluto).

Il comando beep non ha un sistema di riferimento temporale: il suono viene emesso nel momento di esecuzione del comando e per il tempo indicato (durata): nella versione Linux in cui si può istruire un solo comando ad eseguire piú note e si può indicare anche una latenza temporale tra due note (pausa), ma sempre in termini di durata.

Per i piú ferrati in musica si riconoscerà in questo un approccio più simile al metodo musicale della divisione del tempo, in cui è fondamentale il concetto di durata (e altezza) della nota.
Vogliamo quindi fornire un nuovo strumento per questa Beep Art (o meglio Beep Music), che sia semplice e piú”musicale” possibile.
Proponiamo di scrivere in un semplice file testo una nota per riga (come un “rullo musicale”), espressa con altezza, durata naturale e modificatori, tre campi separati da carattere colon (:). Questo file testo sarà la nostra partitura che un software (che andremo a costruire) provvederà a convertire in una sequenze di comandi beep.

Esistono sistemi di Music Engraving che si basano su file testo molto semplice (vedi abc),
quindi non si consideri banale questo metodo: solo prototipale.

L’altezza sarà espressa in notazione anglosassone e con estensione come dettata anche dallo standard MIDI dalla MMA (da C-2 a G8, ossia dal Do ben 2 ottave sotto la nota piú bassa del pianoforte, fino a 127 semitoni sopra).
La durata sarà espressa in termini di divisione musicale, esprimendo la componente a denominatore. Come modificatori saranno supportati il punto (singolo, doppio e triplo, e i gruppi (irregolari) espressi da un semplice numero.
Le pause saranno espresse da note con altezza “P”, con durata e modificatori come per le note.

E’ evidente che in questo modo la durata e posizione delle note nel tempo musicale é garantita dalla divisione del tempo tra note e pause (come é nelle notazione classica e come é pure per il comando beep.

A completare la sintassi introduciamo indicazioni sulla divisione con il metadato tsig (indicata in modo canonico con una frazione), ed indicazione sul tempo (velocità di esecuzione), con un numero che esprima i bpm (beat for measure) ossia il numero di pulsazioni (note di lunghezza indicate dal denominatore delle tsig: per un 3/4 una nota di 1/4) al minuto.
Questi parametri altro non fanno che produrre il rapporto tra le durate di note e pause in termini di tempo assoluto (secondi o frazionamenti).

Se volessimo realizzare un metronomo per una divisione 4/4 avremo:

A5:4:
A4:4:
A4:4:
A4:4:

Ma questo andrebbe bene se il generatore di toni fosse di natura impulsiva e le note poste all’inizio dei quarti della misura decadessero in ampiezza prima di esaurire la loro durata (caso tipico di una partitura MIDI per un drum kick).

Questo non é quasi mai valido in generale, e non é assolutamete vero nel caso di beep ché si comporta come un generatore di tono ideale (potendo assumere altezza e durata arbitrari).

Per questo la giusta partitura potrebbe essere:

A5:16:
A4:16:
A4:16:
A4:16:

Dato che questo è poco intuitivo per un musicista, introduciamo un meccanismo di “umanizzazione” indicando nella “partitura” i portamenti “legato” (comportamanto naturale) e “staccato” (meccanismo per emulare suoni di natura impulsiva). Questo sintatticamente verrà collocato all’interno di una riga di commento. La riga di commento potrà essere inoltre utilizzata per indicare l’inizio della “misura” (o battuta). Questo potrà essere d’ausilio nella verifica (anche automatica) della trascrizione.

Come si può intuire trascrivere musica da spartito originale con questa notazione risulta assai facile.

Vedremo nel prossimo post come anche la trasformazione in Beep Music sia altrettanto facile.

(Fine prima parte)

20150212-215729.jpg

Salvataggio e ripristino di una VM libvirt (parte III)

Concludiamo questa serie di articoli fornendo il codice per il ripristino e qualche suggerimento che renda la nostra implementazione di un sistema di backup pratica e portabile.

Iniziamo con la procedura di ripristino.
Dato il nome del file di archivio, iniziamo ad espanderlo (con utenza amministrativa): questo collocherà i files dei dischi virtuali nel percorso originale (ripristiniamo il percorso assoluto collocando la radice delle operazioni di tar con l’opzione -C) ed il file XML di definizione della macchina virtuale in /tmp (per costruzione del backup).

tar xz -C / -f "$1"

Il nome del file di descrizione è il nome della macchina virtuale (ancora per costruzione del backup) ed è parte del nome dell’archivio: quindi estraiamo da questo il nome della macchina virtuale che stiamo ripristinando e con questo ricaviamo il nome del file di descrizione:

fname="$(basename $1)"
vmname=${fname%%.tar.gz}

Quindi se confermiamo l’esistenza del file di descrizione possiamo importare la macchina inviando l’XML allo stdout della console amministrativa di libvirt (virsh):

	if [ -f /tmp/${fname}.xml ]
	then
		echo define /tmp/${name%%.tar.gz}.xml | virsh
        fi

Questo rende nuovamente disponibile la macchina virtuale.

Come vi avevo promesso, ora qualche suggerimento per rendere il tutto un prodotto.

Dapprima racchiudiamo in funzioni la procedura di salvataggio e ripristino: chiamiamole backup() e restore().
Il codice presentato in queste puntate non necessita di modifiche, ed i parametri che dovevano essere per un ipotetico comando saranno ora per le funzioni: nome di macchina per backup(), nome file archivio per restore().

A questo punto creiamo un file per la nostra applicazione; diciamo libvirt-utils.sh.
Poniamo in questo le nostre funzioni e aggiungiamo il seguente codice:

case $(basename $0) in
virbackup)
  backup "$1"
  ;;
virestore)
  restore "$1"
  ;;
*)
  [ ! -f /sbin/virbackup ] && cp $0 /sbin/virbackup
  [ ! -f /sbin/virestore ] && ln /sbin/virbackup /sbin/virestore 
  ;;
esac

Lanciate almeno una volta lo script senza parametri come amministratore: avrete installati due nuovi programmi: virbackup e virestore ! Lo script originale potrà anche essere rimosso o meglio collocato nella vostra “cassetta degli attrezzi”.

Buona virtualizzazione e buon salvataggio e ripristino a tutti !

20150116-221004.jpg

Salvataggio e ripristino di una VM libvirt (parte II)

Torniamo per completare quanto lasciato in sospeso nella precedente puntata.

Cominciamo con la definizione del metodo per eseguire il backup (seguirà quello per il ripristino) di una specifica VM individuata per id di dominio. Collocheremo questo (e quello per il ripristino) in una funzione bash che invocheremo nel programma principale che costruiremo attorno a questo nucleo applicando una qualche interfaccia per avere lista di domini su cui operare e così invocare ciclicamente la funzione.

Per operare il backup di una VM dobbiamo considerare la sua definizione e ogni immagine disco: nel caso più semplice avremo almeno due files: il file di definizione e una immagine disco. Ipotizzando di voler usare tar quale sistema di archiviazione è opportuno costruire un file con elencate tutte queste sorgenti (files) da sottoporre a l’opzione -T. Questo metodo è il più efficiente nell’ipotesi di utilizzo del comando tar, in quanto operazioni di aggiunta successiva di file in archivio su file compresso non sono consentite direttamente e comunque queste operazioni necessitano la rilettura dell’intero archivio per il posizionamento in coda dei nuovi elementi. Intollerabile.

Quindi cominciano con il produrre il file di definizione di un dominio:

virsh dumpxml "$1" > /tmp/${1}.xml

Nell’ipotesi di collocare questo in una funzione, $1 rappresenta l’unico argomento fornito a questa. Adottiamo /tmp come storage per pulizia.

Aggiungiamo questo file al costruendo file-elenco per tar:

echo "/tmp/${1}.xml" >/tmp/backup.files

Sfruttiamo il file di definizione del dominio per ritrovare i percorsi e nomi dei file di immagini disco appartenenti al dominio, e aggiungiamo questi nel file-elenco:

	grep 'source file=' /tmp/${1}.xml | egrep 'img|vdi|vmkd|qcow|qcow2' | cut -d\' -f2 >>/tmp/backup.files

A questo punto non ci resta che procedere ad archiviare il tutto sfruttando il nome del dominio come nome dell’archivio e soprattutto usando il file-elenco preparato prima:

	tar cz -f ${1}.tar.gz -T /tmp/backup.files

Non ci resta che pulire i files temporanei:

	rm /tmp/${1}.xml /tmp/backup.files

Ed il backup è concluso.

Nella prossima parte descriveremo il processo inverso e qualche suggerimento per costruire un buon programma principale per eseguire il tutto nel mondo reale.

20141231-181722.jpg

Salvataggio e ripristino di una VM libvirt (parte I)

Con l’adozione definitiva da parte di Red Hat e altri vendor di kvm/qemu quale piattaforma di virtualizzazione con hypervisor l’evoluzione software a contorno di questa tecnologia ha fatto grandi passi, consentendo ad oggi di ottenere una perfetta architettura di virtualizzazione di livello enterprise anche a casa vostra gratuitamente (mediante distro quali Ubuntu, Fedora, ecc).
La scalabilità dell’architettura viene garantita dalla infrastruttura costruita a partire dalla libvirt: un demone per il controllo anche remoto dell’hypervisor, una interfaccia amministrativa grafica e una testuale e altro a corollario.

20141231-181855.jpg

Da questa complessa architettura risulta ancora assente uno strumento integrato e completo per il salvataggio e ripristino delle VM.

Assenza però non significa impossibilità: con strumenti disponibili e standard si può realizzare un semplice ma efficace e sicuro software per la realizzazione di procedure di salvataggio e ripristino automatico di VM gestite da libvirt.

Questo sarà oggetto di questa serie di articoli.

Gli strumenti disponibili
La console amministrativa virsh ha i comandi dumpxml e define atti a salvare e ripristinare la definizione di una VM (un dominio, nella nomenclatura libvirt). Questo è un buon punto di partenza.
Quello che manca è il salvataggio della componente storage della VM. Questa è descritta nel file XML di definizione, ed in ogni caso è uno o più file collocati nel percorso /var/lib/libvirt/images/.
Questo percorso è accessibile solo da utente amministratore (l’hypervisor che ne gestisce l’accesso è un servizio di sistema), e questo diviene un requisito per una costruenda procedura automatica.

Il salvataggio di una VM è dunque la copia della sua definizione e dei file delle immagini disco.
Per realizzarlo è sufficiente dunque copiare questi files in un archivio (magari compresso) su un supporto esterno.

Vedremo della prossima puntata il codice (script shell) con cui realizzare questo compito.

Defrag_icon

Deframmentare Linux ?

Non vogliamo tirarla lunga con un articolo accademico sulla frammentazione e sulle tecniche implementate per minimizzarla sui filesystem della famiglia ext*.

Vogliamo solo farvi giocare concretamente con questo concetto/problema che sfugge all’attenzione degli utenti (e sistemisti Linux) per un assunto ben poco esatto ma comunque in concreto valido: “Linux non soffre di problemi di frammentazione”.

In realtà questo, come abbiamo detto, non è “esattamente” vero (e non vogliamo tediarvi con questioni tecniche), ma è altrettanto vero che il filesystem ext2 (e successori) ha dei buoni anticorpi per risolvere l’influenza della deframmentazione.

Il primo giocattolo per poter cominciare a saggiare con mano l’esistenza di questa realtà è il comando filefrag. Questo è disponibile nel pacchetto e2fsprogs (disponibile sia su distribuzioni RedHat like che Debian like).

Questo comando è capace di rilevare la frammentazione di un file indicato, in numero e identità dei blocchi di indirezione (extents).

A partire da questo e considerando che tra gli artifici del filesystem ext2 (e successori) per evitare la framentazione vi è la tecnica di allocare sequenzialmente i blocchi di un file in fase di creazione, possiamo porre le basi per un nuovo giocattolo.

Prendiamo ora il seguente nuovo assunto: “per deframmentare un file basta copiarlo”.
La nuova copia (per via del modo di allocazione blocchi) sarà “probabilmente” deframmentato. Il “probabilmente” è dovuto al fatto che i blocchi contigui devono essere disponibili. Ecco perché nell’implementazione provvediamo a copiare il file su un filesystem di appoggio (di base /tmp), liberiamo spazio sul filesystem sorgente (per aumentare la probabilità di trovare blocchi consecutivi) e ricopiamo nuovamente il file.

Dato che “repetita iuvant”, ripetere questa operazione quando la deframmentazione non è stata pienamente possibile potrà renderla possibile (a patto che il filesystem sia nel frattempo mutato rendendo disponibile nuove sequenze di blocchi contigui).

Ed ecco il nostro defrag per Linux:

#!/bin/bash
#
#
[ "$USER" != "root" ] && echo Must be root && exit 1

TEMPFILE=`mktemp`
trap 'rm -f $TEMPFILE' EXIT 1 15

echo -n "Raccolgo elenco file(s) ... "
find ${1:-.} -type f 2>/dev/null | grep -v $TEMPFILE >$TEMPFILE
echo fatto
NFILES=`cat $TEMPFILE | wc -l`
echo "Trovati $NFILES file(s)"

exec 3<> $TEMPFILE
declare -i i
declare -i defrag

i=0
defrag=0
read <&3
while [ -n "$REPLY" ]
do
EXTENTS=`filefrag "$REPLY" | cut -d: -f2 | awk '{ print $1 }'`
if [ ${EXTENTS:-0} -gt 2 ] 2>/dev/null; then
# Usare mktemp -p /altrodisco (se server più spazio)
TEMP=`mktemp`
cp -dp $REPLY $TEMP
rm -f $REPLY
cp $TEMP $REPLY
rm -f $TEMP
defrag=$(( defrag + 1 ))
fi
i=$((i + 1))
echo -en "\r$i/$NFILES ($(( 100 * i / NFILES ))%)"
read <&3
done
echo
exec 3>&-
echo "Processati $i file(s)"
echo "Deframmentati $defrag file(s)"
trap '' 1 15
exit 0

Ovviamente, in quanto giocattolo, non possiamo chiedervi di provarlo in ambienti di produzione. Pur essendo (crediamo) esente da problemi, non è consigliato soprattutto per il suo tempo di esecuzione, che è legato proporzionalmente alla dimensione e numero dei files da ottimizzare.

Non è il migliore degli approcci, ma è capace di ottenere il suo scopo. Soprattutto è capace di mostrarci il motivo nascosto del perché in Linux abbiamo pochi problemi di frammentazione (la copia dei file che ogni tanto avviene o la creazione degli stessi sono alla base della deframmentazione che avviene fuori dal nostro sguardo)

A noi bastava fornire una fascinazione riguardo il problema.

 

200px-X11.svg

GDM: Niente panico !

Se la nostra sessione grafica si rifiuta di autenticarci attraverso Gnome Display Manager, e ci ritroviamo di nuovo una bella richiesta di credenziali, niente panico !

Prima di tutto vediamo di accedere in console testo: premiamo la combinazione di tasti “Ctrl+Alt+F1” ed inseriamo le nostre credenziali.

Se la registrazione delle nostre credenziali va a buon fine e accediamo alla nostra sessione testo, allora il panico deve rimanere un lontano ricordo. Siamo ad un passo dalla soluzione.

Una rapida occhiata al log potrebbe rilevare il seguente messaggio:

lightdm: pam_succeed_if(lightdm:auth): requirement "user ingroup nopasswdlogin" not met by user "mioutente"

Ottimo!

Nel 99.99% dei casi il problema è dovuto alla corruzione del file ~/.Xauthority.

I motivi possono essere diversi, ma nella maggioranza dei casi è una interruzione di alimentazione del sistema durante una sessione grafica in corso (avete ritrovato il vostro sistema spento?).

Il file ~/.Xauthority è parte del metodo di autorizzazione “cookie-based” utilizzato dal server X; dei diversi schemi di autorizzazione supportati dal server X il GDM supporta solo lo schema MIT-MAGIC-COOKIE-1.

Il “biscotto magico” (magic cookie) è un arbitrario insieme di dati definiti (dal comando xauth) per un server X che ciascun programma client deve dimostrare di conoscere (inviandone una copia).

Per una configurazione workstation, in cui il server X è disponibile per una singola sessione utente, il cookie viene generato all’avvio del server X dedicato alla sessione del singolo utente, pertanto copia del cookie viene posta nella home directory dell’utente nel file .Xauthority.

utente@ubuntu01:~$ od -c .Xauthority
0000000 001  \0  \0  \b   u   b   u   n   t   u   0   1  \0 001   1  \0
0000020 022   M   I   T   -   M   A   G   I   C   -   C   O   O   K   I
0000040   E   -   1  \0 020 340 224 367 025   F   8 034   z 343 205 177
0000060 311   m   s   _ 225 001  \0  \0  \b   u   b   u   n   t   u   0
0000100   1  \0 001   0  \0 022   M   I   T   -   M   A   G   I   C   -
0000120   C   O   O   K   I   E   -   1  \0 020   3 341 203 317 206 207
0000140 212   }   }   {   s 331   : 355 262 343
0000152

E se non si riesce ad entrare in sessione testo?

Allora PANICO ! …  😯

no, si scherza! 😆

Questo lo vedremo in un prossimo post.

cilindro2

crypt-à-porter

Tutti usano SSL nella vita digitale quotidiana: nell’utilizzo della posta elettronica, nell’accesso ai siti web, nei propri certificati digitali e, perfino a nostra insaputa, in mille altre appliances del nascente campo “internet-of-things”, quindi facilmente recuperabile onboard sui diversi sistemi embedded (O_o).

Se hai bisogno di crittografare velocemente un file on-the-fly in maniera simmetrica, non è necessario ricorrere a complesse architetture o a programmi addizionali, o impazzire con le migliaia di salse in cui è possibile interagire con openssl. Basta digitare da semplice riga di comando:

$ openssl enc -in <fileA> -out <fileB> -e -aes256 -k <mypass>

e, altrettanto semplicemente, decrittografare con:

$ openssl enc -in <fileB> -out <fileA> -d -aes256 -k <mypass>

Ovviamente, funziona anche sul tuo Mac  😉

tux-banner

BASH: il problema del costrutto while e OpenSSH

Capita spesso in BASH di realizzare un costrutto che iteri il comando OpenSSH; capita spesso che questo avvenga a partire da una WHILE READ in quanto questo non è altrimenti sostituibile con un FOR o con un parallel-ssh (es. il file di forma tabellare fornisce più di un parametro a OpenSSH).

Esempio

while read HOST USER CMD; do ssh $USER@$HOST "$CMD"; done < lista

Ebbene, quello che otteniamo è l’esecuzione dell’OpenSSH solo in corrispondenza della prima riga del file senza alcun tipo di evidenza di errore. Nella magiorparte dei casi viene data la colpa al costrutto WHILE o al comando READ.
Nulla di più falso!

Cosa accade in realtà?

Nella realtà accade che il comando OpenSSH legge da STDIN, e il corpo istruzioni del costrutto WHILE READ non maschera lo standard input del costrutto, pertanto i comandi all’interno del corpo istruzioni possono attingere al medesimo STDIN. Quindi alla prima esecuzione di OpenSSH, questo consuma l’intero STDIN, lasciando la successiva iterazione priva di altri dati, portandola conseguentemente a corretta conclusione.

Soluzione 1
Utilizzare l’opzione -n del comando OpenSSH

while read HOST USER CMD
do
ssh -n $USER@$HOST "$CMD"
done < lista

Soluzione 2 (valida per somandi anche differenti da OpenSSH)

while read HOST USER CMD
do
ssh $USER@$HOST "$CMD" < /dev/null
done < lista