<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mia mamma usa Linux! &#187; Software</title>
	<atom:link href="http://www.miamammausalinux.org/category/software/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.miamammausalinux.org</link>
	<description>Perché niente è impossibile da capire... Se lo spieghi bene !</description>
	<lastBuildDate>Mon, 02 Jan 2012 11:31:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Incron: monitorare directory e rispondere ad eventi specifici</title>
		<link>http://www.miamammausalinux.org/2011/10/monitorare-directory-e-rispondere-ad-eventi-specifici/</link>
		<comments>http://www.miamammausalinux.org/2011/10/monitorare-directory-e-rispondere-ad-eventi-specifici/#comments</comments>
		<pubDate>Mon, 31 Oct 2011 09:13:15 +0000</pubDate>
		<dc:creator>Matteo Cappadonna</dc:creator>
				<category><![CDATA[Generale]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Utility]]></category>

		<guid isPermaLink="false">http://www.miamammausalinux.org/?p=1488</guid>
		<description><![CDATA[Con questo articolo vedremo come, utilizzando un tool che dialoga direttamente con il kernel Linux, monitorare un particolare path e rispondere ad alcuni eventi lanciando diversi comandi. Come al solito mi piace analizzare una problematica reale per far comprendere meglio il problema e la soluzione che andremo ad implementare. Immaginiamo di avere una macchina Linux [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.miamammausalinux.org/wp-content/uploads/2011/10/inotify.png" alt="inotify" title="inotify" width="137" height="50" class="size-full wp-image-1499" /></p>
<p>Con questo articolo vedremo come, utilizzando un tool che dialoga direttamente con il kernel Linux, monitorare un particolare path e rispondere ad alcuni eventi lanciando diversi comandi.</p>
<p>Come al solito mi piace analizzare una problematica reale per far comprendere meglio il problema e la soluzione che andremo ad implementare.</p>
<p>Immaginiamo di avere una macchina Linux (in questo caso specifico andremo ad utilizzare un server CentOS) attestata sulla rete perimetrale/pubblica della nostra azienda.</p>
<p>Questa macchina ha delle directory utente che vengono utilizzate, da procedure automatiche presenti su server remoti di altre aziende, per caricare dei file che la nostra azienda ha necessità di elaborare.</p>
<p>La soluzione &#8220;quick &amp; dirty&#8221; sarebbe quella di accordarsi con l&#8217;azienda che caricherà il file sul nostro sistema sull&#8217;ora e definire una seguente procedura:</p>
<ul>
<li>Alle ore 00:00 viene avviato il trasferimento del file (di dimensione variabile) tramite scp</li>
<li>Alle ore 01:00 viene avviato tramite cron un job che prende il file e lo elabora</li>
</ul>
<p>Questa soluzione tendenzialmente può funzionare, ma possono verificarsi diversi problemi che possono bloccare la nostra procedura. Per esempio:</p>
<ul>
<li>Un problema sulle procedure dell&#8217;azienda remota tardano o falliscono, facendo slittare l&#8217;upload del file di più di un&#8217;ora. In questo caso il nostro job in partenza alle 01:00 fallirà poiché non troverà il file caricato.</li>
<li>Sempre un problema sulle procedure dell&#8217;azienda remota fa tardare l&#8217;avvio dell&#8217;upload del file. In questo caso, quando il nostro job parte, potrebbe tentare di elaborare un file non ancora completo</li>
<li>Le procedure partono correttamente ma, un lag di rete dato da N possibili motivi, fa allungare il tempo di trasferimento del file. Anche qui il nostro job potrebbe tentare di elaborare un file non ancora completamente trasferito.</li>
<li>Delle modifiche alle procedure remote fanno variare il nome del file (che era stato precedentemente accordato). In questo caso, anche se il trasferimento è completo, il nostro script (se non correttamente ingegnerizzato) potrebbe non trovare il file semplicemente perché non si chiama come ci si aspetterebbe</li>
<li>Sempre per modifiche alle procedure remote, il file potrebbe arrivare non normalizzato (quindi con permission sballate, etc.). In questo caso, magari, il nostro script potrebbe non essere in grado di leggere/scrivere o, più in generale, di elaborare il file</li>
</ul>
<p>Come appare evidente, le problematiche possono essere molteplici!!!<br />
Fortunatamente stiamo lavorando su linux e, il più delle volte, ci viene data la possibilità di risolvere i nostri problemi con un po&#8217; di ingegno!</p>
<p><strong>inotify</strong></p>
<p>inotify è un sottosistema del kernel linux che lavora a livello di filesystem e ci permette, a fronte di alcuni eventi catturati, di notificare le variazioni all&#8217;applicazione.<br />
E&#8217; stato incluso nel mainstream del kernel linux con la versione 2.6.13 (rilasciata a Giugno 2005), ma può essere compilato con la versione 2.6.12 (e precedenti), tramite l&#8217;utilizzo di una patch.</p>
<p>In poche parole, dato un path, il sottosistema ne controlla gli inode puntati, e reagisce ad uno o più eventi su essi. A fronte dello scatenarsi di un evento (definito <strong>mask</strong> &#8211; maschera), possono essere eseguite delle operazioni.</p>
<p>Alcuni eventi che possono essere monitorati sono i seguenti:</p>
<ul>
<li><strong>IN_ACCESS</strong> &#8211; E&#8217; stato fatto un&#8217;accesso in lettura ad un file</li>
<li><strong>IN_MODIFY</strong> &#8211; E&#8217; stata eseguita una modifica ad un file</li>
<li><strong>IN_ATTRIB</strong> &#8211; E&#8217; stata eseguita una modifica agli attributi di un file</li>
<li><strong>IN_OPEN</strong> &#8211; Un file è stato aperto</li>
<li><strong>IN_CLOSE_WRITE</strong> &#8211; Un file, aperto in scrittura, è stato chiuso</li>
<li><strong>IN_CLOSE_NOWRITE</strong> &#8211; Un file, aperto NON in scrittura, è stato chiuso</li>
<li><strong>IN_MOVED_FROM</strong> e <strong>IN_MOVED_TO</strong> &#8211; Un file è stato spostato o copiato</li>
<li><strong>IN_DELETE</strong> &#8211; Un file/directory è stato cancellato</li>
<li><strong>IN_CREATE</strong> &#8211; Un file/directory è stato creato</li>
<li><strong>IN_DELETE_SELF</strong> &#8211; Il file/directory monitorato è stato cancellato</li>
</ul>
<p><strong>incrond</strong></p>
<p>incrond è un demone che funziona in maniera molto simile a quello che è l&#8217;ormai conosciutissimo demone cron; la differenza sta nel fatto che, se cron lavora con giorni ed orari, incrond lavora invece con inotify.</p>
<p>Quello che possiamo fare per rendere la nostra procedura &#8220;intelligente&#8221; è andare a monitorare il path in cui l&#8217;azienda remota esegue l&#8217;upload del file e, al termine dell&#8217;upload, lanciare il job che elabora il file.<br />
Questo ci permette di evitare di legarsi a gli orari, e di lanciare il nostro job ogni volta che un file viene caricato, indipendentemente dall&#8217;ora o dal nome del file. Esattamente quello che ci interessa.</p>
<p>Intanto andiamo ad installare il demone, operazione estremamente semplice:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># yum install incrond</pre></div></div>

<p>A questo punto, la prima cosa da fare è creare il file /etc/incrond.allow contenente la lista degli utenti abilitati all&#8217;uso di incrond. Nel nostro caso abilitiamo l&#8217;utente <em>root</em> e l&#8217;utente <em>matteo</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># cat &gt; /etc/incrond.allow &lt;&lt;EOF
&gt;root
&gt;matteo
&gt;EOF
# cat /etc/incrond.allow
root
matteo</pre></div></div>

<p>Avviamo il demone ed assicuriamoci che sia abilitato per l&#8217;avvio automatico al boot della macchina:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># service incrond start
Starting incrond:                                          [  OK  ]
# chkconfig --list incrond
incrond        	0:off	1:off	2:off	3:off	4:off	5:off	6:off
# chkconfig incrond on</pre></div></div>

<p>Ok, adesso siamo pronti per il definire il nostro monitoraggio.</p>
<p>Poniamo, nel nostro esempio, che l&#8217;utente <em>matteo</em> sia l&#8217;utente che carica il file, e che lo carica nel path /home/matteo/uploads.</p>
<p>Iniziamo a definire la incrontab (vedrete che l&#8217;assonanza con cron non è solo nelle definizioni, ma anche nei comandi) per l&#8217;utente matteo. Il comando è semplicissimo:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># su - matteo
$ incrontab -e</pre></div></div>

<p>Questo apre il nostro editor di default e ci permette di compilare la incrontab.<br />
Questa incrontab è composta da 3 campi (che vedremo di seguito) separati da spazio</p>
<p><strong>ATTENZIONE</strong> &#8211; I campi DEVONO essere separati dal carattere di spaziatura. Separare i campi con il consueto TAB porta a problemi di interpretazione della incrontab da parte del demone incrond (dai, è tutto molto bello, un piccolo difetto lo possiamo anche concedere <img src='http://www.miamammausalinux.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ).</p>
<p>I tre campi sono, nell&#8217;ordine:</p>
<ul>
<li><strong>path</strong> &#8211; Il path ASSOLUTO che si desidera monitorare</li>
<li><strong>mask</strong> &#8211; L&#8217;evento che si vuole monitorare. Sono supportati tutte le maschere che sono state descritte prima, più la maschera IN_ALL_EVENTS che, semplicemente, cattura tutti gli eventi (ottima per il debugging)</li>
<li><strong>command</strong>- Il comando da eseguire quando viene catturato l&#8217;evento. Da notare che in questo comando possiamo utilizzare delle variabili di inotify che ci vengono passate direttamente dal demone. Queste variabili sono:
<ul>
<li><strong>$@</strong> &#8211; Il path monitorato</li>
<li><strong>$#</strong> &#8211; Il file sul quale si è scatenato l&#8217;evento</li>
<li><strong>$%</strong> &#8211; L&#8217;evento, in forma testuale, che si è verificato</li>
<li><strong>$&amp;</strong> &#8211; L&#8217;evento, in forma numerica, che si è verificato</li>
<li><strong>$$</strong> &#8211; Il carattere $</li>
</ul>
</li>
</ul>
<p>Semplice, non trovate?</p>
<p>Allora, torniamo all&#8217;esempio. Il nostro job si trova nella directory /home/matteo/scripts/, si chiama <em>elaborazione.sh</em> ed accetta come parametro il nome del file da elaborare.</p>
<p>Facciamo un&#8217;attimo il punto della situazione. In un certo momento (non sappiamo quale), la procedura remota andrà a caricare, con scp, il nostro file.<br />
Una volta effettuata la connessione con successo, il file verrà in primo luogo creato (IN_CREATE), aperto in scrittura (IN_OPEN), scritto (una sequenza di IN_MODIFY) ed infine chiuso (IN_CLOSE_WRITE, visto che era stato aperto in scrittura).</p>
<p>Quindi, l&#8217;evento che andrà a determinare la fine del trasferimento è IN_CLOSE_WRITE. Andiamo quindi a compilare la incrontab dell&#8217;utente matteo:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">/home/matteo/uploads IN_CLOSE_WRITE /home/matteo/scripts/elaborazione.sh $@/$#</pre></div></div>

<p>Salviamo usciamo ed assicuriamoci che la nuova incrontab sia stata letta ed interpretata dal sistema:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">table updated
$ exit
# tail -1 /var/log/cron
Oct 27 10:30:39 myserver incrond[889]: table for user matteo changed, reloading</pre></div></div>

<p>Possiamo testare se funziona caricando un dummy file (supponiamo che i file contenti il testo &#8220;dummy&#8221; vengano ignorati dal nostro script) da una macchina remota:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">client$ cat &gt; dummyfile &lt;&lt;EOF
&gt;dummy
&gt;EOF
client$ cat dummyfile
dummy
client$ scp dummyfile matteo@myserver:uploads/
Password:</pre></div></div>

<p>Torniamo sul server e, dal log di cron, vediamo che incrond ha catturato l&#8217;evento ed ha eseguito il nostro elaboratore:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># tail -1 /var/log/cron
Oct 27 10:35:43 myserver incrond[889]: (matteo) CMD (/home/matteo/scripts/elaborazione.sh /home/matteo/uploads/dummyfile)</pre></div></div>

<p>&nbsp;</p>
<p><strong>Conclusioni</strong></p>
<p>Abbiamo visto come installare e configurare incrond per monitorare il cambio di stato di un file in una directory.<br />
Questa è una possibile soluzione pratica ad un problema che, tendenzialmente, si verifica abbastanza di frequente in ambienti enterprise, in cui ci sono flussi di lavoro locali/remoti che devono lavorare in relazione gli uni con gli altri.</p>
<p>In realtà, gli utilizzi di inotify sono estremamente ampi; per esempio, è il sistema che viene normalmente utilizzato dagli indicizzatori di filesystem su linux (per esempio, Beagle di SUSE).<br />
Andando a monitorare l&#8217;intero filesystem (/) ed avendo le notifiche sulle modifiche di qualsiasi file al suo interno, l&#8217;indicizzatore può aggiornare i suoi database senza doversi rileggere l&#8217;intero filesystem.</p>
<p>Un&#8217;altro utilizzo può essere quello di monitorare il file di log di un&#8217;applicazione. Quando questa applicazione andrà a loggare qualcosa, possiamo mandare una mail contenente il file di configurazione a qualcuno.</p>
<p>Il limite è il vostro ingegno <img src='http://www.miamammausalinux.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.miamammausalinux.org/2011/10/monitorare-directory-e-rispondere-ad-eventi-specifici/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Configurare Nagios per ricevere Trap SNMP</title>
		<link>http://www.miamammausalinux.org/2011/09/configurare-nagios-per-ricevere-trap-snmp/</link>
		<comments>http://www.miamammausalinux.org/2011/09/configurare-nagios-per-ricevere-trap-snmp/#comments</comments>
		<pubDate>Tue, 20 Sep 2011 12:58:38 +0000</pubDate>
		<dc:creator>Matteo Cappadonna</dc:creator>
				<category><![CDATA[Debian]]></category>
		<category><![CDATA[Nagios]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.miamammausalinux.org/?p=1454</guid>
		<description><![CDATA[Per sua stessa natura, Nagios funziona generalmente in maniera &#8220;attiva&#8221;, andando ad eseguire lui stesso i check verso gli host remoti, tramite script già forniti o custom, oppure interrogando direttamente un demone NRPE presente sulla macchina remota, e che in genere esegue check locali. Nagios, però, può essere configurato per eseguire dei check &#8220;passivi&#8221;, ovvero [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.miamammausalinux.org/wp-content/uploads/2009/01/nagios.png" alt="nagios" width="100" class="alignnone size-full wp-image-174" /></p>
<p>Per sua stessa natura, Nagios funziona generalmente in maniera &#8220;attiva&#8221;, andando ad eseguire lui stesso i check verso gli host remoti, tramite script già forniti o custom, oppure interrogando direttamente un demone NRPE presente sulla macchina remota, e che in genere esegue check locali.</p>
<p>Nagios, però, può essere configurato per eseguire dei check &#8220;passivi&#8221;, ovvero fare in modo che un check che giri, possa essere messo in stati particolari da programmi estetrni. Questo è quello che normalmente succede quando si lavora sull&#8217;interfaccia web e si imposta, per esempio, un Acknowledge su un servizio, o si disabilitano le notifiche.</p>
<p>La cosa interessante che andremo a fare in questo tutorial è un&#8217;ulteriore step. In pratica faremo in modo che non solo il server su cui gira Nagios possa ricevere delle trap SNMP, ma che Nagios stesso reagisca, in maniera predeterminata, a queste trap.</p>
<p>Facciamo un&#8217;esempio pratico (sarà poi quello utilizzato nel tutorial, e che è stato personalmente testato da me): un bilanciatore hardware F5 è stato configurato per lanciare delle trap verso una macchina Nagios. Questo bilanciatore invia non solo trap relative al suo stato, ma anche delle trap che indicano lo stato di un host reale bilanciato.<br />
In pratica, quello che si otterrà è il seguente flusso di eventi:</p>
<ol>
<li>L&#8217;host reale ha qualche problema, e va in down (fisicamente, o anche il solo servizio bilanciato dall&#8217;F5)</li>
<li>Il bilanciatore se ne accorge, disabilita il reale dal pool legato al VIP (Virtual IP)</li>
<li>Il bilanciatore manda una trap verso il server su cui gira Nagios, identificando che un particolare host va in down</li>
<li>Il server cattura la trap, la interpreta, ed inietta direttamente in Nagios un comando</li>
<li>Nagios mette un particolare servizio in stato CRITICO, scatenando anche le notifiche del caso</li>
</ol>
<p>In questo caso vediamo che non ci sono latenze dovute al timeslice di check di Nagios, ma la notifica è immediata alla verifica del problema.</p>
<p>Prima di entrare nel vivo del tutorial, tengo a precisare non verrà trattata l&#8217;installazione e/o la configurazione di Nagios (se non per quanto riguarda le parti relative al tutorial stesso), e l&#8217;ambiente su cui è stato testato il tutto gira attualmente con questo OS/questi software:</p>
<ul>
<li>Debian GNU/Linux 6.0</li>
<li>Nagios3 presente sui repository Debian (Nagios 3.2.1-2)</li>
</ul>
<p>Quindi farò riferimento ai path di default di questo sistema.<br />
Bando alle ciance, andiamo ad incominciare <img src='http://www.miamammausalinux.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>&nbsp;</p>
<p><strong>Configurare il sistema per ricevere le trap SNMP</strong></p>
<p>Il primo passo è quello di far si che il nostro server (sul quale già sta girando Nagios) possa ricevere delle trap SNMP.<br />
Niente di più semplice, dovreste avere già installato il pacchetto snmpd, nel caso in cui non lo fosse, un semplice</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># apt-get install snmpd</pre></div></div>

<p>vi risolverà il problema.<br />
Questo pacchetto contiene un demone in grado di ricevere delle trap snmp. Per configurarlo editate il file /etc/default/snmpd aggiungendo/modificando le seguenti variabili:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">TRAPDRUN=yes
TRAPDOPTS='-On -u snmptt -p /var/run/snmptrapd.pid'</pre></div></div>

<p>Facendola breve diciamo di far partire il demone per le trap (TRAPDRUN=yes) e lo facciamo lanciare con le seguenti opzioni:</p>
<ul>
<li><strong>-On</strong>     Fa si che il demone usi gli OID in formato numerico, ed evita che il traduttore debba eseguire la traduzione dal formato testuale a quello numerico</li>
<li><strong>-u snmptt</strong>     Fa girare il demone con l&#8217;utente snmptt</li>
<li><strong>-p /var/run/snmptrapd.pid</strong>     Definisce il PIDfile in cui andare a scrivere il pid del processo</li>
</ul>
<p>Andiamo quindi a definire cosa il demone snmptrapd deve fare alla ricezione di una trap. Modifichiamo quindi il file<br />
/etc/snmp/snmptrapd.conf inserendo le seguenti direttive alla fine:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">disableAuthorization yes
traphandle default /usr/sbin/smptt</pre></div></div>

<p>In questo caso, diciamo al demone di disattivare l&#8217;autenticazione per l&#8217;invio delle trap (per questo tutorial useremo il metodo KISS: Keep It Simple and Stupid), e diciamo al demone di prendere tutte le trap e girarle al software /usr/sbin/smptt (di cui parleremo a breve).<br />
Aspettiamo a riavviare il demone poiché dobbiamo prima assicurarci di aver installato SNMPTT.</p>
<p>&nbsp;</p>
<p><strong>Configurare il traduttore di trap SNMPTT</strong></p>
<p>Il traduttore è una parte fondamentale. E&#8217; quel software che si occupa, una volta ricevuta la trap, di interpretarla, tradurla e scriverla da qualche parte.<br />
La traduzione viene fatta utilizzando dei file .MIB che altro non sono che dizionari contenenti un riferimento TRAP -&gt; MESSAGGIO.<br />
Praticamente tutti i produttori di hardware che emettono trap SNMP forniscono i file .MIB necessari alla traduzione, e la F5 non è da meno.</p>
<p>Intanto installiamo il traduttore:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># apt-get install snmptt</pre></div></div>

<p>Una volta installato, andiamo a modificare il file di configurazione /etc/snmp/snmptt.ini con i seguenti parametri:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">mode = standalone          # Questo perché viene invocato da snmptrapd e non deve girare come demone
dns_enable = 0             # Evitiamo che risolva l'hostname per ogni trap che gli arriva
strip_domain = 0           # Diciamogli di non rimuovere il dominio dall'eventuale hostname
net_snmp_perl_enable = 1   # Può utilizzare il perl la traduzione
translate_value_oids = 1   # Traduce gli OID in formato testuale leggibile breve
translate_enterprise_oid_format = 1   # come sopra
translate_trap_oid_format = 1         # come sopra
translate_varname_oid_format = 1      # come sopra
log_enable = 1             # Abilita il logging delle trap
syslog_enable = 1          # Abilita il logging delle trap sul syslog
syslog_level = info        # Definisce il livello di logging per le trap su syslog</pre></div></div>

<p>A questo punto portiamo sulla macchina i vari files .MIB relativi all&#8217;hardware che andrà a scatenare le trap e traduciamo questi file in formato comprensibile con snmptt. Nulla di più semplice:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># mkdir /etc/snmp/mibs    # In questa directory metteremo tutti i mib tradotti
# snmpttconvertmib --in=F5-BIGIP-COMMON.mib --out=F5-BIGIP-COMMON.conf
# mv F5-BIGIP-COMMON.conf /etc/snmp/mibs/</pre></div></div>

<p>&nbsp;</p>
<p>Lanciamo il comando per tutti i MIB che ci fornisce il produttore.<br />
A questo punto, riapriamo il file di configurazione di snmptt (/etc/snmp/snmptt.ini) e terminiamo la configurazione aggiungendo/modificando alla fine:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">snmptt_conf_files = &amp;lt;&amp;lt;END
/etc/snmp/snmptt.conf
/etc/snmp/mibs/F5-BIGIP-COMMON.conf
END</pre></div></div>

<p>Riga per riga, andiamo a mettere tutti i file .conf che abbiamo generato con smpttconvertmib. A questo punto possiamo restartare il demone SNMPD (così da far partire il gestore di trap) e verificare che sia effettivamente partito:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># /etc/init.d/snmpd restart
# cat /var/run/snmptrapd.pid
7464</pre></div></div>

<p>Perfetto, mettiamoci in tali sul file del syslog (per default il /var/log/messages) e dovremmo iniziare a veder passare le trap:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># tail -f /var/log/messages
Sep 20 11:23:40 nagios-mi snmptt[111]: .1.3.6.1.4.1.3375.2.4.0.29 Normal &quot;Status Events&quot; 192.168.0.1 - The system is in an unusable situation. AUDIT - user admin - RAW: httpd(mod_auth_pam): user=admin(admin) partition=[All] level=Administrator tty=1 host=10.10.0.1 attempts=1 start=\&quot;Tue Sep 20 11:03:00 2011\&quot; end=\&quot;Tue Sep 20 11:23:30 2011\&quot;.</pre></div></div>

<p>Ottimo, riceviamo le trap, ora dobbiamo trovare il modo di dire a Nagios che questa trap ha un significato, dirgli quale, e di scatenare un evento… procediamo <img src='http://www.miamammausalinux.org/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>&nbsp;</p>
<p><strong>Catturare le trap</strong></p>
<p>Ci viene in aiuto un&#8217;ottimo tool di nome SEC. Questo tool, in maniera generale, permette di analizzare live il contenuto di un file (quindi resta in ascolto ed analizza i nuovi contenuti) e di eseguire determinate operazioni a verificarsi di particolari eventi.<br />
Nel nostro caso, lo metteremo in ascolto sul file in cui vengono slogate le trap /var/log/messages e, con il match su di una particolare RegExp, viene lanciato uno script con determinati parametri.<br />
SEC è uno script in perl, ma ne esiste comunque una versione pacchettizzata per debian, dunque:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># apt-get install sec</pre></div></div>

<p>Una volta installato, andiamo a modificare il file di configurazione /etc/sec.conf, inserendo i seguenti parametri:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">type=Single
ptype=RegExp
pattern=.*(Normal|INFORMATIONAL|MINOR|WARNING|SEVERE|MAJOR|CRITICAL)\ \&quot;Status Events\&quot;\ (\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b)\ \-\ (A service is detected (UP|DOWN)\.\ Pool\ member\ (\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b)(.*)|(.*))
desc=snmptrap received from $2
action=shellcmd /usr/lib/nagios/eventhandlers/snmptraphandling.sh $2 $1 &quot;$3&quot; $4 $5</pre></div></div>

<p>In pratica viene detto a SEC di eseguire la &#8220;action&#8221; quando un testo fa match con la regular expression definita in pattern. Senza stare li a parlare di regular expression (potremmo andare avanti per giorni e giorni), se arriva una trap SNMP con il seguente testo:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">Sep 20 11:23:40 nagios-mi snmptt[111]: .1.3.6.1.4.1.3375.2.4.0.29 Normal &quot;Status Events&quot; 192.168.0.1 - The system is in an unusable situation. AUDIT - user admin - RAW: httpd(mod_auth_pam): user=admin(admin) partition=[All] level=Administrator tty=1 host=10.10.0.1 attempts=1 start=\&quot;Tue Sep 20 11:03:00 2011\&quot; end=\&quot;Tue Sep 20 11:23:30 2011\&quot;.</pre></div></div>

<p>otteniamo in output le seguenti variabili:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">$1 = Normal
$2 = 192.168.0.1
$3 = The system is in an unusable situation. AUDIT - user admin - RAW: httpd(mod_auth_pam): user=admin(admin) partition=[All] level=Administrator tty=1 host=10.10.0.1 attempts=1 start=\&quot;Tue Sep 20 11:03:00 2011\&quot; end=\&quot;Tue Sep 20 11:23:30
$4 =
$5 =</pre></div></div>

<p>Come vediamo le ultime due variabili sono vuote. Nel caso, invece, ci arrivi una trap formata in quest&#8217;altra maniera (che indica lo stato UP/DOWN di un server fisico controllato dal bilanciatore):</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">Sep 20 11:47:33 nagios-mi snmptt[111]: .1.3.6.1.4.1.3375.2.4.0.10 Normal &quot;Status Events&quot; 192.168.0.1 - A service is detected DOWN. Pool member 192.168.0.100:18009 monitor status down. 192.168.0.100 18009</pre></div></div>

<p>otteniamo, invece, in output le seguenti variabili:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">$1 = Normal
$2 = 192.168.0.1
$3 = A service is detected DOWN. Pool member
$4 = DOWN
$5 = 192.168.0.100</pre></div></div>

<p>In quest&#8217;altro caso le ultime due variabili sono valorizzate ed identificano, rispettivamente, lo stato del reale (UP o DOWN) ed il reale in question (192.168.0.100).</p>
<p>Ovviamente, questa RegExp è stata costruita in funzione di come SNMPTT, con i MIB forniti da F5, traduce le trap. Hardware differente, con MIB differenti, tradurranno le trap in maniera differente, e sarà quindi necessario andare a trovare una RegExp funzionante per quella casistica.</p>
<p>Ne approfitto per segnalare il link <a href="http://gskinner.com/RegExr/" target="_blank">http://gskinner.com/RegExr/</a> veramente molto comodo per scrivere e testare le RegExp.</p>
<p>Quindi, abbiamo intercettato le trap con SEC, ed eseguiamo questo script /usr/lib/nagios/eventhandlers/snmptraphandling.sh passandogli le 5 variabili ottenute dalla RegExp, siano esse valorizzate o meno. Ma cosa fa questo script?</p>
<p>&nbsp;</p>
<p><strong>snmptraphandling.sh</strong></p>
<p>Ho scritto personalmente questo script, basandomi su un&#8217;idea di Francois Meehan, autore di uno script python simile ma meno specializzato.</p>
<p>Potete scaricarlo da qui: <a href="http://www.miamammausalinux.org/wp-content/uploads/2011/09/snmptraphandling.zip">snmptraphandling.zip</a></p>
<p>Questa versione in bash accetta in ingresso le seguenti variabili (nel seguente ordine):</p>
<p>HOST: Obbligatoria, identifica l&#8217;host che ha inviato la trap<br />
SEVERITY: Obbligatoria, identifica il &#8220;peso&#8221; della trap (Normal, critical, etc.) così come viene definita da F5<br />
&#8220;DATA&#8221;: Obbligatoria dentro i doppi apici. Contiene un testo che identifica meglio la trap, una descrizione<br />
UP|DOWN: Opzionale, identifica lo stato di un reale<br />
ALARMEDHOST: Opzionale, identifica l&#8217;host al quale viene applicata la variabile precedente.</p>
<p>Intanto lo script definisce, a seconda della SEVERITY, che valori applicare al Nagios.<br />
Inoltre, nel caso vengano specificate anche le ultime due variabili, esegue operazioni differenti per scatenare allarmi specifici.</p>
<p>Ma come dialoga con Nagios? Semplicissimo, costruisce un comando ad-hoc interpretabile da Nagios, e lo inetta nel file</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">/var/lib/nagios3/rw/nagios.cmd</pre></div></div>

<p>Questo file è specializzato per inviare segnali a Nagios e fargli eseguire operazioni particolari.</p>
<p>In pratica, all&#8217;arrivo di una trap viene scatenato un evento indirizzato all&#8217;host $HOST, per un servizio chiamato:</p>
<p>snmp_trap_handling_$HOST-…. Nel caso in cui non siano specificate le ultime 2 variabili<br />
snmp_trap_handling_$ALARMED_HOST Nel caso in cui siano specificate le ultime 2 variabili.</p>
<p>Ma prendiamo in mano un&#8217;esempio completo, così da essere più chiari.<br />
Ci arriva dal bilanciatore, per esempio, una trap SNMP che ci identifica che un&#8217;host è andato giù; all&#8217;interno del file<br />
/var/log/messages verrà scritto (da SNMPTT) il seguente messaggio:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">Sep 20 11:47:33 nagios-mi snmptt[111]: .1.3.6.1.4.1.3375.2.4.0.10 Normal &quot;Status Events&quot; 192.168.0.1 - A service is detected DOWN. Pool member 192.168.0.100:18009 monitor status down. 192.168.0.100 18009</pre></div></div>

<p>SEC vedrà che questo testo fa match con la RegExp che gli abbiamo applicato, e lancerà questo comando:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">/usr/lib/nagios/eventhandlers/snmptraphandling.sh 192.168.0.1 Normal \
&quot;A service is detected DOWN. Pool member&quot; DOWN 192.168.0.100</pre></div></div>

<p>Lo script prenderà questi valori, li andrà ad elaborare (per esempio, cercando nelle configurazioni di nagios, andrà a tradurre 192.168.0.1 con bil-f5, che altro non è che il nome dell&#8217;host specificato in nagios) ed inietterà il seguente testo nel file<br />
/var/lib/nagios3/rw/nagios.cmd:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">[1316513822] PROCESS_SERVICE_CHECK_RESULT;bil-f5;snmp_trap_handling_192.168.0.100;2;A service is detected DOWN. Pool member 192.168.0.100:18009 monitor status down. 192.168.0.100</pre></div></div>

<p>Questo testo fa si che il servizio &#8220;snmp_trap_handling_192.168.0.100&#8243; venga applicato lo stato 2, ovvero il CRITICAL per Nagios.</p>
<p><strong>Configurare Nagios</strong></p>
<p>Per configurare il Nagios, andremo a creare 3 strutture nuove: la prima è un servizio template che funziona in passivo e che viene usato per creare qualsiasi servizio relativo alle trap snmp; la seconda è l&#8217;host che identifica il bilanciatore; la terza è il servizio vero e proprio che verrà messo in critical o meno all&#8217;arrivo della trap.<br />
Quindi:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">define service {
name generic-snmptrap
active_checks_enabled 1
passive_checks_enabled 1 ; Passive service checks are enabled
is_volatile 1
initial_state o
check_period never
notification_interval 120
notification_options w,u,c,r
notification_period 24x7
check_command return-ok
max_check_attempts 1
check_freshness 0
stalking_options o,w,u,c
register 0 ; Not register. Its just a template
}</pre></div></div>

<p>Notiamo alcune configurazioni particolari:</p>
<p>passive_checks_enabled 1 Determina che il servizio risponde a check passivi</p>
<p>active_checks_enabled 1 Attiva anche i check attivi. Questo è stato fatto solo perché personalmente trovo che<br />
Nagios debba sempre mostrare uno stato completamente verde. Disattivando i<br />
check attivi, nel TacticalOverview di Nagios avremmo un host segnalato in rosso.</p>
<p>check_period never Non vengono mai schedati check per questo servizio (questo perché il servizio<br />
risponde a delle trap e non esegue direttamente i check)</p>
<p>check_command return-ok Attivando i check attivi, è necessario definite un check_command. Ho usato<br />
return-ok che è un check standard di Nagios che ritorna sempre un stato OK</p>
<p>stalking_options o,w,u,c Questo serve per evitare che mille trap dello stesso tipo vadano a saturare il<br />
Nagios</p>
<p>A questo punto definiamo l&#8217;host:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">define host{
use generic-host
host_name bil-f5
alias bil-f5
address 192.168.0.1
}</pre></div></div>

<p>ed infine il servizio:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">define service{
use generic-snmptrap
host_name bil-f5
service_description snmp_trap_handling_192.168.0.100
}</pre></div></div>

<p>Vediamo quindi che, il match che esegue il Nagios, è sulla descrizione del servizio.</p>
<p>&nbsp;</p>
<p><strong>Conclusioni</strong></p>
<p>Abbiamo infine visto il giro del fumo. Sembrano tante parole ed il tutto molto complicato, ma vi assicuro che, una volta implementato, va tutto liscio come l&#8217;olio.</p>
<p>Buon lavoro <img src='http://www.miamammausalinux.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.miamammausalinux.org/2011/09/configurare-nagios-per-ricevere-trap-snmp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Evoluzione dell&#8217;alta affidabilità su Linux: creare un cluster Tomcat utilizzando la soluzione nativa, Heartbeat e Pacemaker</title>
		<link>http://www.miamammausalinux.org/2011/01/evoluzione-dellalta-affidabilita-su-linux-creare-un-cluster-tomcat-utilizzando-la-soluzione-nativa-heartbeat-e-pacemaker/</link>
		<comments>http://www.miamammausalinux.org/2011/01/evoluzione-dellalta-affidabilita-su-linux-creare-un-cluster-tomcat-utilizzando-la-soluzione-nativa-heartbeat-e-pacemaker/#comments</comments>
		<pubDate>Mon, 24 Jan 2011 11:31:36 +0000</pubDate>
		<dc:creator>Raoul Scarazzini</dc:creator>
				<category><![CDATA[Clustering]]></category>
		<category><![CDATA[Heartbeat]]></category>
		<category><![CDATA[Linux HA]]></category>
		<category><![CDATA[Pacemaker]]></category>
		<category><![CDATA[Tomcat]]></category>
		<category><![CDATA[Alta affidabilità]]></category>
		<category><![CDATA[Cluster]]></category>

		<guid isPermaLink="false">http://www.miamammausalinux.org/?p=1241</guid>
		<description><![CDATA[&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Tomcat è un Application Server: un contenitore di applicazioni sviluppate attraverso il linguaggio di programmazione Java. Tomcat viene impiegato generalmente per l&#8217;esposizione di web service e questa sua attitudine, in caso di applicazioni critiche per importanza, deve essere obbligatoriamente associata all&#8217;alta affidabilità. Esso nativamente supporta un modello di cluster, che consente a diverse istanze [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.miamammausalinux.org/wp-content/uploads/2011/01/tomcat.png" alt="" title="tomcat" width="100" height="63" />&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.miamammausalinux.org/wp-content/uploads/2009/01/linux-ha.png" alt="" title="linux-ha" width="100" height="100" />&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.miamammausalinux.org/wp-content/uploads/2009/11/pacemaker.png" alt="" title="pacemaker" width="100" height="100" /></p>
<p>Tomcat è un Application Server: un contenitore di applicazioni sviluppate attraverso il linguaggio di programmazione Java. Tomcat viene impiegato generalmente per l&#8217;esposizione di web service e questa sua attitudine, in caso di applicazioni critiche per importanza, deve essere obbligatoriamente associata all&#8217;alta affidabilità. Esso nativamente supporta un modello di cluster, che consente a diverse istanze di condividere le sessioni, in modo da garantire la sopravvivenza del servizio: se quindi un&#8217;istanza smette di funzionare, il suo ruolo viene assunto dall&#8217;istanza sopravvissuta.<br />
Ma chi si occupa del controllo delle istanze stesse?<br />
Questo articolo descrive un caso di studio relativo ad un cluster nativo Tomcat le cui istanze vengono gestite da Heartbeat attraverso il Cluster Resource Manager Pacemaker.</p>
<p><strong>Installazione di Java</strong></p>
<p>Java è essenziale per il funzionamento di Tomcat ed è anche il primo software da configurare per ottenere il risultato prefissato in questo articolo. Per prima cosa quindi sarà necessario scaricare il pacchetto di installazione dal sito ufficiale di SUN presso il link <a href="http://www.java.com/it/download/linux_manual.jsp?locale=it&#038;host=www.java.com">http://www.java.com/it/download/linux_manual.jsp?locale=it&#038;host=www.java.com</a>.<br />
Ottenuto il file <em>jre-6u23-linux-i586.bin</em>, il cui nome potrà variare a seconda della versione, questo va eseguito:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># chmod +x jre-6u23-linux-i586.bin 
# ./jre-6u23-linux-i586.bin</pre></div></div>

<p>L&#8217;esecuzione del file creerà una cartella nominata <em>jre1.6.0_23</em> che sarà possibile spostare in un path consono, ad esempio <em>/usr/local</em>, per il quale potrà essere creato un link simbolico:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># mv jre1.6.0_23 /usr/local
# ln -s /usr/local/jre1.6.0_23 /usr/local/java</pre></div></div>

<p>In questo modo sarà possibile far riferimento al path <em>/usr/local/java</em> per il raggiungimento degli eseguibili java ed inoltre, in caso di installazioni di versioni diverse di Java, basterà cambiare il puntamento del link simbolico.</p>
<p><strong>Installazione di Tomcat</strong></p>
<p>L&#8217;installazione di Tomcat viene descritta in maniera generalista, indipendente quindi dalla distribuzione utilizzata.<br />
Per prima cosa quindi è necessario scaricare l&#8217;ultima versione dell&#8217;application server Tomcat, andando sul sito ufficiale di Tomcat (<a href="http://tomcat.apache.org/download-70.cgi">http://tomcat.apache.org/download-70.cgi</a>) oppure scaricando il pacchetto da uno dei mirror:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># wget http://it.apache.contactlab.it/tomcat/tomcat-7/v7.0.6/bin/apache-tomcat-7.0.6.tar.gz -o /tmp/apache-tomcat-7.0.6.tar.gz</pre></div></div>

<p>una volta terminato lo scaricamento, è possibile decomprimere il pacchetto in un path di sistema, ad esempio (e per convenzione) <em>/usr/local</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># cd /usr/local
# tar -xzvf /tmp/apache-tomcat-7.0.6.tar.gz
# ln -s apache-tomcat-7.0.6 tomcat</pre></div></div>

<p>L&#8217;ultimo comando lanciato crea un link simbolico, in modo che in futuro per accedere alla directory di Tomcat sarà sufficiente utilizzare il percorso <em>/usr/local/tomcat</em>.</p>
<p><strong>Installazione di Heartbeat e Pacemaker</strong></p>
<p>L&#8217;installazione dell&#8217;apparato cluster offerto dal progetto <em>Linux-ha</em> non verrà descritta in questo articolo, in quanto ampiamente trattata nei precedenti articoli della serie, in particolare nella puntata <a href="http://www.miamammausalinux.org/2010/06/evoluzione-dellalta-affidabilita-su-linux-confronto-pratico-tra-heartbeat-classico-ed-heartbeat-con-pacemaker/">confronto pratico tra Heartbeat classico ed Heartbeat con Pacemaker</a>.</p>
<p><strong>Configurazione di Tomcat</strong></p>
<p>La configurazione prevede due fasi: la prima relativa alle credenziali di accesso, la seconda relativa alle impostazioni per il clustering.<br />
All&#8217;interno del file <em>/usr/local/tomcat/conf/tomcat-users.xml</em> sono definite le utenze di accesso alle diverse componenti dell&#8217;application server, in particolare, per permettere all&#8217;utente <em>tomcat</em> di gestire l&#8217;installazione di nuove applicazioni attraverso l&#8217;interfaccia web disponibile, il contenuto del file dovrà essere il seguente:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">'1.0'</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">'utf-8'</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;tomcat-users<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;role</span> <span style="color: #000066;">rolename</span>=<span style="color: #ff0000;">&quot;tomcat&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;role</span> <span style="color: #000066;">rolename</span>=<span style="color: #ff0000;">&quot;manager-gui&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;user</span> <span style="color: #000066;">username</span>=<span style="color: #ff0000;">&quot;tomcat&quot;</span> <span style="color: #000066;">password</span>=<span style="color: #ff0000;">&quot;tomcat&quot;</span> <span style="color: #000066;">roles</span>=<span style="color: #ff0000;">&quot;manager,manager-gui,tomcat&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/tomcat-users<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Inutile dire come il campo password debba essere modificato in base alla password scelta.<br />
L&#8217;abilitazione del cluster Tomcat, data la natura introduttiva dell&#8217;articolo, verrà fatta nella modalità più semplice, così come illustrato dalla documentazione ufficiale di Tomcat (<a href="http://tomcat.apache.org/tomcat-7.0-doc/cluster-howto.html">http://tomcat.apache.org/tomcat-7.0-doc/cluster-howto.html</a>), abilitando cioè la seguente riga all&#8217;interno del file <em>/usr/local/tomcat/conf/server.xml</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Cluster</span> <span style="color: #000066;">className</span>=<span style="color: #ff0000;">&quot;org.apache.catalina.ha.tcp.SimpleTcpCluster&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span></pre></div></div>

<p>La configurazione preliminare dell&#8217;application server è così completa.</p>
<p><strong>Configurazione di Heartbeat e Pacemaker</strong></p>
<p>Appena avviato il demone Heartbeat:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># /etc/init.d/heartbeat start</pre></div></div>

<p>è possibile definire le configurazioni preliminari del cluster:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># crm configure property stonith-enabled=&quot;false&quot;
# crm configure property no-quorum-policy=&quot;ignore&quot;
# crm configure primitive ping ocf:pacemaker:ping params host_list=&quot;192.168.0.254&quot; name=&quot;ping&quot; op monitor interval=&quot;10s&quot; timeout=&quot;60s&quot; op start timeout=&quot;60s&quot; op stop timeout=&quot;60s&quot;
# crm configure clone ping_clone ping meta globally-unique=&quot;false&quot;</pre></div></div>

<p>Come spiegato nei precedenti articoli queste configurazioni preliminari indicano di non utilizzare <em>stonith</em>, ignorare l’assenza di quorum e creare una risorsa <em>ping</em> che controlli la connettività in entrambi i nodi attraverso il <em>clone</em> della risorsa stessa.<br />
Maggiori informazioni e spiegazioni approfondite si trovano nella <a href="http://www.miamammausalinux.org/2010/06/evoluzione-dellalta-affidabilita-su-linux-confronto-pratico-tra-heartbeat-classico-ed-heartbeat-con-pacemaker/">seconda parte del secondo articolo della serie</a>.<br />
In particolare l&#8217;ultima definizione, ossia la risorsa clonata per il controllo della connettività, favorisce lo spunto per la configurazione della risorsa Tomcat per la quale esiste un resource agent apposito: <a href="http://www.linux-ha.org/doc/re-ra-tomcat.html">http://www.linux-ha.org/doc/re-ra-tomcat.html</a>. Essendo obiettivo del progetto la gestione per mezzo di Pacemaker delle istanze di Tomcat, ed essendo le istanze di Tomcat in tutto e per tutto simili su entrambi nodi, queste potranno essere assimilate ad un&#8217;unica risorsa clonata.<br />
Nel dettaglio, la configurazione sarà la seguente:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="console" style="font-family:monospace;">crm configure primitive cluster_tomcat ocf:heartbeat:tomcat params java_home=&quot;/usr/local/java/&quot; catalina_home=&quot;/usr/local/tomcat/&quot; op monitor interval=&quot;60s&quot; timeout=&quot;30s&quot; op start interval=&quot;0&quot; timeout=&quot;60s&quot; op stop interval=&quot;0&quot; timeout=&quot;120s&quot;
crm configure clone cluster_tomcat_clone cluster_tomcat meta globally-unique=&quot;false&quot; target-role=&quot;Started&quot;
crm configure location cluster_tomcat_on_connected_node cluster_tomcat_clone -inf: not_defined ping or ping lte 0</pre></td></tr></table></div>

<p>Nel dettaglio:</p>
<ol>
<li>Viene definita la risorsa <em>cluster_tomcat</em> i cui parametri sono il path in cui è installato Java (<em>java_home</em>) ed il path di tomcat stesso (<em>catalina_home</em>);</li>
<li>La risorsa <em>cluster_tomcat</em> viene clonata dalla nuova risorsa <em>cluster_tomcat_clone</em>. Così come per la risorsa <em>ping_clone</em> che risiederà su ciascun nodo definito, anche questa avrà lo stesso comportamento;</li>
<li>Viene definita una <em>location</em>, ossia un vincolo che obbliga la risorsa clonata a funzionare unicamente sui nodi la cui connettività è comprovata (nodi su cui cioè la risorsa ping esiste e restituisce un risultato positivo);</li>
</ol>
<p>A questo punto, la situazione del cluster dovrebbe essere la seguente:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">============
Last updated: Mon Jan 24 10:17:05 2011
Stack: Heartbeat
Current DC: tomcatcluster-nodo2 (b091eddc-aa64-4d7d-8407-65a7dddafbdf) - partition with quorum
Version: 1.0.10-da7075976b5ff0bee71074385f8fd02f296ec8a3
2 Nodes configured, unknown expected votes
2 Resources configured.
============
&nbsp;
Online: [ tomcatcluster-nodo1 tomcatcluster-nodo2 ]
&nbsp;
 Clone Set: ping_clone
     Started: [ tomcatcluster-nodo1 tomcatcluster-nodo2 ]
 Clone Set: cluster_tomcat_clone
     Started: [ tomcatcluster-nodo1 tomcatcluster-nodo2 ]</pre></div></div>

<p>Ed entrambe le istanze di Tomcat dovrebbero essersi avviate su ciascun nodo. E&#8217; possibile verificarlo provando ad accedere all&#8217;interfaccia web di amministrazione presente su ciascun nodo:</p>
<p><a href="http://tomcatcluster-nodo1:8080/manager/html">http://tomcatcluster-nodo1:8080/manager/html</a><br />
<a href="http://tomcatcluster-nodo2:8080/manager/html">http://tomcatcluster-nodo2:8080/manager/html</a></p>
<p>Entrambi link dovrebbero essere funzionanti e richiedere uno username con password per accedervi. Una volta inserite le credenziali definite in fase di configurazione di Tomcat, sarà visibile l&#8217;interfaccia di amministrazione delle applicazioni.</p>
<p><strong>Analisi dei log</strong></p>
<p>L&#8217;avvio dei servizi Tomcat da parte del cluster può essere seguito dai file di log dell&#8217;application server stesso, all&#8217;interno dei quali è possibile verificare se il cluster nativo di Tomcat viene attivato correttamente.</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># cat /usr/local/tomcat/logs/catalina.out
...
INFO: Cluster is about to start
...
INFO: Setting cluster mcast soTimeout to 500
...
INFO: Server startup in 3153 ms
...
21-gen-2011 17.05.47 org.apache.catalina.ha.tcp.SimpleTcpCluster memberAdded
INFO: Replication member added:org.apache.catalina.tribes.membership.MemberImpl[tcp://{192, 168, 0, 1}:4000,{192, 168, 0, 2},4000, alive=1259, securePort=-1, UDP Port=-1, id={101 64 89 59 2 -44 67 123 -73 23 4 -50 -57 105 8 58 }, payload={}, command={}, domain={}, ]
...</pre></div></div>

<p>Il server è avviato e certamente ha considerato la configurazione, includendo l&#8217;host (<em>memberAdded</em>) <em>192.168.0.52</em> nel cluster.</p>
<p><strong>Configurazione applicazione di Test</strong></p>
<p>La configurazione può dirsi completa. E&#8217; possibile quindi installare una semplice applicazione di test per verificare nell&#8217;effettivo il funzionamento delle sessioni condivise. Per fare ciò è sufficiente creare un&#8217;applicazione configurata con il parametro &#8220;<distributable/>&#8221; che indica al cluster di sfruttare la configurazione cluster per la condivisione delle sessioni.<br />
L&#8217;applicazione <em>TestSession</em>, scaricabile dal portale è stata configurata proprio a questo scopo:</p>
<p><a href='http://www.miamammausalinux.org/wp-content/uploads/2011/01/TestSession.war'>TestSession</a></p>
<p>Una volta scaricato il file <em>TestSession.war</em>, attraverso la console Tomcat e su ciascun nodo, sarà possibile installare l&#8217;applicazione nella sezione &#8220;WAR file to deploy&#8221;, selezionando il fie &#8220;war&#8221; scaricato e premendo il tasto &#8220;deploy&#8221;. Se l&#8217;esito sarà &#8220;OK&#8221;, entrambe le applicazioni saranno disponibili attraverso l&#8217;indirizzo:</p>
<p><a href="http://tomcatcluster-nodo1:8080/TestSession">http://tomcatcluster-nodo1:8080/TestSession</a><br />
<a href="http://tomcatcluster-nodo2:8080/TestSession">http://tomcatcluster-nodo2:8080/TestSession</a></p>
<p>E&#8217; possibile dunque avviare i test.</p>
<p><strong>Test di funzionamento</strong></p>
<p>Il principio di funzionamento del cluster è quello di rispondere alle richieste. Generalmente in questo tipo di architettura, gli Application Server risiedono dietro a <em>bilanciatori</em>, cioè apparati hardware o software che distribuiscono il carico attraverso batterie di macchine che offrono servizi.<br />
L&#8217;architettura di test predisposta non prevede l&#8217;utilizzo di un bilanciatore, a per simulare il bilanciamento del carico tra i due host sarà sufficiente inserire nel file <em>/etc/hosts</em> della propria macchina queste due righe:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">192.168.0.1 tomcatcluster
#192.168.0.2 tomcatcluster</pre></div></div>

<p>Come scritto in precedenza quindi, l&#8217;applicazione potrà essere chiamata come segue, senza far riferimento all&#8217;IP:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">http://tomcatcluster:8080/TestSession/</pre></div></div>

<p>Il test funzionerà in modo che chiamato l&#8217;url relativo al quale si passa un parametro, ad esempio:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">http://tomcatcluster:8080/TestSession/session.jsp?aaa=111</pre></div></div>

<p>la pagina visualizzi quanto segue:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">Server info
&nbsp;
    * Name: tomcatcluster-nodo1
    * Address: 192.168.0.1
&nbsp;
Session Attributes
&nbsp;
    * aaa = 111</pre></div></div>

<p>Ovviamente le chiamate successive con parametri differenti aggiungeranno nuovi attributi.<br />
Nella fattispecie, chiamare:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">http://tomcatcluster:8080/TestSession/session.jsp?bbb=222</pre></div></div>

<p>produrrà:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">Server info
&nbsp;
    * Name: tomcatcluster-nodo1
    * Address: 192.168.0.1
&nbsp;
Session Attributes
&nbsp;
    * aaa = 111
    * bbb = 222</pre></div></div>

<p>Il test a questo punto è semplicissimo, modificando il file /etc/hosts in modo che appaia come segue:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">#192.168.0.1 tomcatcluster
192.168.0.2 tomcatcluster</pre></div></div>

<p>Di fatto il secondo nodo ora sarà quello attivo. Richiamando nuovamente lo script:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">http://tomcatcluster:8080/TestSession/session.jsp?ccc=333</pre></div></div>

<p>Si otterrà il seguente output:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">Server info
&nbsp;
    * Name: tomcatcluster-nodo2
    * Address: 192.168.0.2
&nbsp;
Session Attributes
&nbsp;
    * aaa = 111
    * bbb = 222
    * ccc = 333</pre></div></div>

<p>Da notare come nel Server info ora il nodo sia tomcatcluster-nodo2, mentre i dati di sessione sono stati mantenuti.</p>
<p>Il corretto funzionamento è verificabile anche accedendo singolarmente a ciascun tomcat ai link presenti nella pagina manager nella colonna &#8220;Sessions&#8221;, dove vengono elencate le sessioni, che ovviamente hanno lo stesso codice su entrambi gli Application server.</p>
<p><strong>Conclusioni</strong></p>
<p>Terminata questa carrellata di concetti e test una cosa è chiara: come sempre questo è solo l&#8217;inizio. Sono moltissimi gli ambiti in cui soluzioni come (o simili) a quella presentata possono essere messe in produzione per ottenere infrastrutture stabili, sicure e funzionali. Sempre e comunque altamente affidabili.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.miamammausalinux.org/2011/01/evoluzione-dellalta-affidabilita-su-linux-creare-un-cluster-tomcat-utilizzando-la-soluzione-nativa-heartbeat-e-pacemaker/feed/</wfw:commentRss>
		<slash:comments>41</slash:comments>
		</item>
		<item>
		<title>Samba: installazione di un fileserver gestito con gruppi di accesso locali</title>
		<link>http://www.miamammausalinux.org/2010/12/samba-installazione-di-un-fileserver-gestito-con-gruppi-di-accesso-locali/</link>
		<comments>http://www.miamammausalinux.org/2010/12/samba-installazione-di-un-fileserver-gestito-con-gruppi-di-accesso-locali/#comments</comments>
		<pubDate>Fri, 31 Dec 2010 16:10:57 +0000</pubDate>
		<dc:creator>Raoul Scarazzini</dc:creator>
				<category><![CDATA[Samba]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.miamammausalinux.org/?p=1207</guid>
		<description><![CDATA[Questo articolo illustra come ottenere un&#8217;installazione coerente di un fileserver Linux basato su SAMBA, che amministri l&#8217;accesso alle condivisioni attraverso utenti che appartengano a gruppi di sistema, gestiti in una forma riconoscibile. Gli utenti, pur essendo a tutti gli effetti parte del sistema, avranno permessi di accesso unicamente attraverso il protocollo CIFS, gestito dalle macchine [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.miamammausalinux.org/wp-content/uploads/2009/01/samba.png"><img src="http://www.miamammausalinux.org/wp-content/uploads/2009/01/samba.png" alt="" title="samba" class="alignnone size-full wp-image-196" /></a></p>
<p>Questo articolo illustra come ottenere un&#8217;installazione coerente di un fileserver Linux basato su SAMBA, che amministri l&#8217;accesso alle condivisioni attraverso utenti che appartengano a gruppi di sistema, gestiti in una forma riconoscibile.<br />
Gli utenti, pur essendo a tutti gli effetti parte del sistema, avranno permessi di accesso unicamente attraverso il protocollo CIFS, gestito dalle macchine <em>Microsoft Windows</em>.</p>
<p><strong>Installazione di SAMBA</strong></p>
<p>La procedura descritta fa riferimento al sistema operativo <em>Ubuntu Server 10.4</em>, ed all&#8217;ultima release stabile disponibile in esso per il progetto libero SAMBA, la versione 3.4.7.<br />
L&#8217;installazione per Ubuntu ed i sistemi Debian, può essere effettuata come di consueto:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># apt-get install samba</pre></div></div>

<p>mentre nei sistemi che fanno uso di rpm e di yum il comando sarà invece:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># yum install samba</pre></div></div>

<p>Prima di effettuare qualsiasi operazione è bene salvare il file di configurazione originale di SAMBA:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># cd /etc/samba
# mv smb.conf smb.conf.org</pre></div></div>

<p>nel corso dell&#8217;articolo partiremo da un file completamente vuoto, per sottolineare come sia possibile impostare pochi parametri per essere operativi nel minor tempo possibile.</p>
<p><strong>Configurazione di SAMBA (impostazioni globali)</strong></p>
<p>Le configurazioni descritte fanno hanno come presupposto il fatto che l&#8217;utente con cui si sta operando all&#8217;interno del sistema sia &#8220;root&#8221;. Attraverso l&#8217;editor preferito sarà possibile creare un nuovo file smb.conf:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># sudo su -
# vi /etc/samba/smb.conf</pre></div></div>

<p>All&#8217;interno del quale dovranno essere impostati i seguenti parametri:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">[global]
   security = user
   workgroup = NETWORK.LOCAL
   server string = %h server (Samba, Ubuntu) 
&nbsp;
   wins support = yes 
   dns proxy = no 
&nbsp;
   log file = /var/log/samba/log.%m 
   max log size = 1000 
   syslog = 0 
&nbsp;
   encrypt passwords = true 
   passdb backend = tdbsam
&nbsp;
   directory mask = 2770 
   create mask = 0660</pre></div></div>

<p>Le configurazioni indicano che il server è di tipo <em>standalone</em> (<em>security = user</em>), ossia non collegato a sistemi di autenticazione centralizzati. Il server è parte del gruppo di lavoro “NETWORK.LOCAL” (opzione <em>workgroup</em>, che andrà modificata a seconda delle impostazioni relative propria rete <em>Microsoft Windows</em>) e funzionerà da server WINS (<em>wins support = yes</em>) in modo da gestire la risoluzione dei nomi <em>Microsoft Windows</em> per la rete, ma non controllerà però i nomi effettuando query sul server dns di sistema (<em>dns proxy = no</em>).<br />
Il sistema registrerà un log per ciascuna macchina che si collegherà (<em>log file = /var/log/samba/log.%m</em>), tale log non potrà eccedere un megabyte di grandezza (<em>max log size = 1000</em>). Inoltre nessuna informazione verrà registrata nel file <em>/var/log/syslog</em> (<em>syslog = 0</em>), il file di log generale relativo al sistema. Tutte le informazioni relative all&#8217;esecuzione del demone saranno reperibili all&#8217;interno del file <em>/var/log/samba/log.smbd</em>.<br />
Il sistema di autenticazione cripterà le password (<em>encrypt passwords</em>) ed utilizzerà il backend <em>tdbsam</em> (opzione <em>passdb backend</em>), ossia il database locale.<br />
Le ultime due opzioni indicate definiscono la maschera attraverso la quale verranno create le directory (<em>directory mask = 2770</em>) ed i file (<em>create mask = 0660</em>). Le directory verranno quindi create con permessi di lettura, scrittura ed esecuzione per il proprietario ed il gruppo, mentre per tutti gli altri saranno inaccessibili. I file verranno creati con i medesimi permessi ad eccezione dell&#8217;esecuzione.<br />
Particolarità aggiuntiva della modalità di creazione delle cartelle è quella di possedere il bit <em>setgid</em> (<a href="http://it.wikipedia.org/wiki/Setuid_e_setgid">http://it.wikipedia.org/wiki/Setuid_e_setgid</a>) che impone l&#8217;appartenenza al gruppo della cartella padre per tutti i file e le cartelle create al suo interno. Questo significa che chiunque appartenga al gruppo della cartella padre potrà creare file e cartelle al suo interno, tali file e cartelle apparterranno al gruppo della cartella padre. In questo modo i permessi specifici di accesso per i gruppi definiti nelle cartelle governeranno la totalità degli accessi.</p>
<p><strong>Configurazione di un gruppo</strong></p>
<p>Ciascun gruppo di accesso verrà nominato in questo modo:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># groupadd samba_rwx_Amministrazione</pre></div></div>

<p>Il criterio con cui i gruppi vengono creati e nominati è ottenibile scomponendo il nome attraverso i caratteri &#8220;_&#8221; (underscore), dove &#8220;samba&#8221; indica che il gruppo è inerente al servizio samba, &#8220;rwx&#8221; indica il tipo di accesso che può essere appunto &#8220;rwx&#8221; (permessi di lettura e scrittura) o &#8220;rx&#8221; (sola lettura), mentre &#8220;Amministrazione&#8221; indica il nome della condivisione a cui il gruppo si riferisce.</p>
<p><strong>Aggiunta di un&#8217;utenza</strong></p>
<p>Ogni utenza creata nel sistema che farà riferimento al servizio samba, avrà come gruppo primario samba, con identificativo &#8220;999&#8243;, creato con il seguente comando:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># groupadd -g 999 samba</pre></div></div>

<p>In questo modo, la separazione degli ambiti operativi sarà oltre che configurata nel sistema, anche ben visibile.<br />
Per aggiungere un&#8217;utenza al sistema i passi da compiere sono quindi i seguenti:</p>
<ol>
<li>Lanciare il comando:

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># useradd -g samba -s /bin/false -d -c &quot;Utente di test&quot; user1</pre></div></div>

<p>In cui <em>user1</em> rappresenta il nome attraverso il quale l&#8217;utente dovrà accedere alle condivisioni. A <em>user1</em> viene assegnato il gruppo primario &#8220;samba&#8221; (<em>-g samba</em>), una shell di login nulla in modo che non possa mai effettuare il login nel sistema (<em>-s /bin/false</em>) ed una breve descrizione dell&#8217;utenza (<em>-d</em>, generalmente nome e cognome, oppure un indicativo della funzione svolta).
</li>
<li>L&#8217;utente creato va poi aggiunto al database locale SAMBA, attraverso questo comando:

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># smbpasswd -a user1</pre></div></div>

<p>indicando per due volte la password scelta, che può essere anche omessa nel caso in cui lo si decida (è sempre consigliabile inserirne una).
</li>
<li>L&#8217;utente va quindi aggiunto ad uno dei gruppi disponibili. Aggiungere utenti al gruppo è possibile con il seguente comando:

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># adduser user1 samba_rwx_Amministrazione</pre></div></div>

</li>
</ol>
<p>Per controllare quali utenti appartengono al gruppo è sufficiente digitare il seguente comando:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># cat /etc/group | grep &quot;samba_rwx_Amministrazione&quot;
samba_rwx_Amministrazione:user1,user2,user3</pre></div></div>

<p>Mentre per controllare un singolo utente a quali gruppi appartiene, il comando sarà invece:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># groups user1
user1 : samba samba_rwx_Amministrazione</pre></div></div>

<p><strong>Aggiunta di una condivisione</strong></p>
<p>Ciascuna condivisione fa riferimento ad un path locale, nel caso descritto viene creata una cartella /share:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># mkdir /share</pre></div></div>

<p> al di sotto della quale tutte le cartelle condivise verranno create:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="console" style="font-family:monospace;"># mkdir /share/Amministrazione
# chgrp samba_rwx_Amministrazione /share/Amministrazione
# chmod 2770 /share/Amministrazione</pre></td></tr></table></div>

<p>Queste operazioni andranno eseguite per ciascuna nuova condivisione creata e si riassumono come segue:</p>
<ol>
<li>Creazione effettiva della cartella;</li>
<li>Assegnazione della cartella al gruppo creato;</li>
<li>Impostazione del permesso <em>setgid</em> (vedi sopra) ricorsivo sulla cartella appena creata;</li>
</ol>
<p>Le condivisioni verranno definite nel file di configurazione <em>smb.conf</em> in coda alle dichiarazioni globali, in un formato simile al seguente:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">[Amministrazione] 
comment = Amministrazione 
read only = no 
write list = @samba_rwx_Amministrazione
read list = 
path = /share/Amministrazione</pre></div></div>

<p>Il codice illustrato definisce una condivisione denominata “Amministrazione” a cui possono accedere in scrittura nella directory “/share/Amministrazione” unicamente gli utenti appartenenti al gruppo “samba_rwx_Amministrazione”.</p>
<p>Pertanto, per aggiungere una condivisione sarà quindi sufficiente eseguire la creazione e l&#8217;assegnazione dei permessi come descritto sopra ed inserire all&#8217;interno del file <em>/etc/samba/smb.conf</em> una dichiarazione seguendo il modello indicato:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">[&lt;NOMECONDIVISIONE&gt;] 
comment = &lt;Descrizione condivisione&gt;
read only = no 
write list = @&lt;gruppo con permessi di scrittura&gt;
read list = @&lt;gruppo con permessi di lettura&gt;
path = &lt;path della condivisione&gt;</pre></div></div>

<p>Nel caso l&#8217;accesso venga deciso unicamente in lettura o unicamente in scrittura, è possibile omettere le righe relative (write list o read list) dalla dichiarazione.</p>
<p><strong>Attivazione delle configurazioni</strong></p>
<p>Per applicare le nuove configurazioni, il servizio SAMBA necessita di essere ricaricato:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># service smbd reload</pre></div></div>

<p>Da questo momento in poi sarà possibile utilizzare una qualsiasi macchina Microsoft Windows per testare l&#8217;effettivo successo delle configurazioni impostate.</p>
<p><strong>Note</strong></p>
<p>Quanto descritto consente di configurare SAMBA affinché possa interagire con client o server <em>Microsoft Windows</em> come se fosse un file e print server <em>Microsoft</em>.<br />
E&#8217; possibile variare le configurazioni in modo che SAMBA agisca da Primary Domain Controller (PDC), Backup Domain Controller o prendere parte ad un dominio Active Directory.<br />
Sul portale tecnico sono disponibili diversi articoli che approfondiscono questi argomenti:</p>
<p>Realizzare un Primary Domain Controller con SAMBA, Openldap e smbldap-tools : (<a href="http://www.miamammausalinux.org/2008/01/realizzare-un-primary-domain-controller-con-samba-openldap-e-smbldap-tools-1-di-6/">1 di 6</a>)<br />
Realizzare un Primary Domain Controller con SAMBA, Openldap e smbldap-tools : (<a href="http://www.miamammausalinux.org/2008/01/realizzare-un-primary-domain-controller-con-samba-openldap-e-smbldap-tools-2-di-6/">2 di 6</a>)<br />
Realizzare un Primary Domain Controller con SAMBA, Openldap e smbldap-tools : (<a href="http://www.miamammausalinux.org/2008/01/realizzare-un-primary-domain-controller-con-samba-openldap-e-smbldap-tools-3-di-6/">3 di 6</a>)<br />
Realizzare un Primary Domain Controller con SAMBA, Openldap e smbldap-tools : (<a href="http://www.miamammausalinux.org/2008/01/realizzare-un-primary-domain-controller-con-samba-openldap-e-smbldap-tools-4-di-6/">4 di 6</a>)<br />
Realizzare un Primary Domain Controller con SAMBA, Openldap e smbldap-tools : (<a href="http://www.miamammausalinux.org/2008/01/realizzare-un-primary-domain-controller-con-samba-openldap-e-smbldap-tools-5-di-6/">5 di 6</a>)<br />
Realizzare un Primary Domain Controller con SAMBA, Openldap e smbldap-tools : (<a href="http://www.miamammausalinux.org/2008/02/realizzare-un-primary-domain-controller-con-samba-openldap-e-smbldap-tools-6-di-6/">6 di 6</a>)</p>
<p>Samba e Active Directory (1 di 3): <a href="http://www.miamammausalinux.org/2009/04/samba-e-active-directory-1-di-3-diventare-parte-di-un-dominio/">diventare parte di un Dominio</a><br />
Samba e Active Directory (2 di 3): <a href="http://www.miamammausalinux.org/2009/05/samba-e-active-directory-2-di-3-interrogare-il-dominio/">interrogare il dominio</a><br />
Samba e Active Directory (3 di 3): <a href="http://www.miamammausalinux.org/2009/05/samba-e-active-directory-3-di-3-configurare-pam-per-lautenticazione-locale/">configurare pam per l&#8217;autenticazione locale</a></p>
<p>In attesa quindi di saggiare le meraviglie dell&#8217;annunciato SAMBA 4, che conterrà un motore interno volto ad eguagliare l&#8217;efficienza e la funzionalità di <em>Microsoft Active Directory</em>, è chiaro come sia già possibile adottare SAMBA in ambiti produttivi di svariato genere, con successo, e senza costi di licenza.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.miamammausalinux.org/2010/12/samba-installazione-di-un-fileserver-gestito-con-gruppi-di-accesso-locali/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Evoluzione dell’alta affidabilità su Linux: realizzare un NAS con Pacemaker, DRBD ed exportfs</title>
		<link>http://www.miamammausalinux.org/2010/09/evoluzione-dellalta-affidabilita-su-linux-realizzare-un-nas-con-pacemaker-drbd-ed-exportfs/</link>
		<comments>http://www.miamammausalinux.org/2010/09/evoluzione-dellalta-affidabilita-su-linux-realizzare-un-nas-con-pacemaker-drbd-ed-exportfs/#comments</comments>
		<pubDate>Mon, 20 Sep 2010 19:40:13 +0000</pubDate>
		<dc:creator>Raoul Scarazzini</dc:creator>
				<category><![CDATA[Clustering]]></category>
		<category><![CDATA[DRBD]]></category>
		<category><![CDATA[Heartbeat]]></category>
		<category><![CDATA[Linux HA]]></category>
		<category><![CDATA[NFS]]></category>
		<category><![CDATA[Pacemaker]]></category>
		<category><![CDATA[Alta affidabilità]]></category>
		<category><![CDATA[Cluster]]></category>

		<guid isPermaLink="false">http://www.miamammausalinux.org/?p=1128</guid>
		<description><![CDATA[&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Nel precedente articolo è stato effettuato un confronto tra le tipologie possibili di utilizzo relativo ad Heartbeat, nella modalità classica ed in quella mediante CRM (Cluster Resource Manager) per l&#8217;erogazione in alta affidabilità del servizio Apache. In quest&#8217;ultimo articolo verrà proposto un vero case study relativo alla configurazione di un cluster erogante uno storage [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.miamammausalinux.org/wp-content/uploads/2009/01/linux-ha.png" alt="linux-ha" title="linux-ha" width="100" height="100" class="alignnone size-full wp-image-259" />&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.miamammausalinux.org/wp-content/uploads/2009/11/pacemaker.png" alt="Pacemaker" title="pacemaker" width="100" height="100" class="size-full wp-image-872" />&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.miamammausalinux.org/wp-content/uploads/2010/09/drbd.png" alt="" title="drbd" width="100" height="100" class="alignnone size-full wp-image-1190" /></p>
<p>Nel precedente articolo è stato effettuato un confronto tra le tipologie possibili di utilizzo relativo ad Heartbeat, nella modalità classica ed in quella mediante <em>CRM</em> (<em>Cluster Resource Manager</em>) per l&#8217;erogazione in alta affidabilità del servizio <em>Apache</em>.<br />
In quest&#8217;ultimo articolo verrà proposto un vero case study relativo alla configurazione di un cluster erogante uno <em>storage</em> NFS in alta affidabilità i cui dati verranno ridondati via <em>DRBD</em> (<em>Network Raid 1</em>), mediante la configurazione di <em>Pacemaker</em>.<br />
Peculiarità del progetto sarà l&#8217;utilizzo per l&#8217;erogazione delle directory NFS di entrambi i nodi, in modo da sfruttare tutte le macchine presenti, per un cluster di tipo <em>active-active</em>.</p>
<p><strong>Il progetto</strong></p>
<p>Quanto si propone di realizzare è un sistema in alta affidabilità che consenta di impiegare tutte le macchine presenti all&#8217;interno del cluster per rendere disponibile spazio all&#8217;interno di una rete. In altre parole, un <em>Network Attached Storage</em> (<em>NAS</em>), un&#8217;entità composta da due macchine collegate alla rete che consentano a dei client di montare le partizioni e fruire dello spazio reso disponibile.<br />
Le componenti impiegate all&#8217;interno del progetto saranno:</p>
<ol>
<li><em>Heartbeat e Pacemaker</em>: per la gestione del cluster;</li>
<li><em>DRBD</em>: per la replica dei dati fra le due macchine attraverso un <em>network raid 1</em>;</li>
<li><em>NFS</em>: per la condivisione attraverso la rete dello spazio;</li>
</ol>
<p>Il progetto si rifà nelle sue fondamenta a quanto illustrato nella <a href="http://www.miamammausalinux.org/2010/06/evoluzione-dellalta-affidabilita-su-linux-confronto-pratico-tra-heartbeat-classico-ed-heartbeat-con-pacemaker/">seconda parte del precedente articolo</a> e, se non lo si è ancora fatto, è bene dare una rapida lettura in modo da poter applicare i concetti lì illustrati senza perplessità.<br />
Il cluster verrà costruito su due sistemi (<em>debian-lenny-nodo1</em> e <em>debian-lenny-nodo2</em>) collegati ciascuno alla rete locale (<em>192.168.1.0/24</em>) e l’uno all&#8217;altro da un cavo cross (<em>10.0.0.0/24</em>, connessione necessaria per realizzare <em>il network raid 1</em> con <em>DRBD</em>), lo spazio locale verrà esportato attraverso il protocollo <em>NFS</em>. In particolare verranno definite due condivisioni distinte, corrispondenti a due cartelle locali chiamate <em>/share-a</em> e <em>/share-b</em>.<br />
Obiettivo ultimo è quello di ottenere ciascuna condivisione esportata da un nodo, in modo da avere (a regime ed in condizioni ottimali) un cluster in cui nessun nodo risulti passivo.<br />
Unico requisito richiesto sui nodi è la presenza dei pacchetti <em>heartbeat</em> e <em>pacemaker</em> (la cui installazione è descritta nell&#8217;articolo precedente) e del demone <em>NFS</em>. Nei sistemi Debian ed Ubuntu sarà quindi necessario installare il pacchetto <em>nfs-kernel-server</em> mentre in RedHat/SuSe il pacchetto sarà <em>nfs</em>.</p>
<p><strong>La gestione locale dei dati: device, md, LVM o tutti e tre?</strong></p>
<p>Prima di iniziare a configurare il cluster è bene decidere come verranno gestiti sulle macchine i dati che andranno esposti. Questa scelta, la più delicata poiché intacca direttamente le performance, va fatta sulla base dell&#8217;hardware disponibile, partendo da tre ambiti operativi:</p>
<ul>
<li><em>device</em>: partizioni fisiche (ad esempio /dev/sda3, /dev/sda4 e via dicendo);</li>
<li><em>md (Multiple Disk)</em>: gestione locale dei raid, i dati sono ridondati sulle singole macchine (oltre che in rete);</li>
<li><em>LVM (Logical Volume Manager)</em>: volumi logici, per una gestire più elastica dello spazio locale;</li>
</ul>
<p>Partendo dal presupposto che l&#8217;utilizzo dei <em>device</em> è indispensabile (visto che si sta parlando di dischi locali), scegliere se configurare raid locali o <em>LVM</em> dipende da quanto si dispone.<br />
Se le macchine utilizzate possiedono una <a href="http://it.wikipedia.org/wiki/RAID#Hardware_o_software">controller RAID hardware</a>, allora si potrà evitare di configurare i dispositivi <em>md</em>, così come se si ritiene la ridondanza locale superflua (del resto i dati verranno comunque ridondati in rete).<br />
Se il sistema necessiterà di frequenti variazioni in termini di spazio sulle partizioni esposte sarà doveroso impiegare volumi logici in modo da gestire con facilità operazioni di ridimensionamento. Inoltre la gestione dei volumi logici potrebbe essere preferita dai più, proprio per la semplicità con cui è possibile apportare variazioni allo spazio disponibile, soprattutto in situazioni complesse.<br />
Lampante è come più livelli di complessità si aggiungono, maggiore sarà il carico che graverà sul sistema operativo e maggiore dovrà essere la capacità di gestire eventuali malfunzionamenti.<br />
Come sempre quindi, la libertà di scelta è totale e dipende unicamente dell&#8217;utente.<br />
Nel caso illustrato la scelta è caduta sull&#8217;impiego di LVM su due partizioni (/dev/sda3 e /dev/sdb3), in quanto le macchine su cui la soluzione viene implementata possiedono una <em>controller RAID</em> integrata che si occupa di ridondare i due dischi disponibili.<br />
Su entrambe le macchine sono stati definiti due <em>Physical Volume</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># pvcreate /dev/sd[ab]3</pre></div></div>

<p>Ai quali è stato associato un <em>Volume Group</em> denominato <em>vg_share</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># vgcreate vg_share /dev/sd[ab]3</pre></div></div>

<p>Ed infine sono stati creati due <em>Logical Volume</em>, denominati <em>lv_drbd0</em> ed <em>lv_drbd1</em>, i quali rappresenteranno le due condivisioni relative ai device drbd che verranno in seguito creati:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># lvcreate -n lv_drbd0 -L 1G vg_share
# lvcreate -n lv_drbd1 -L 1G vg_share</pre></div></div>

<p>l&#8217;opzione &#8220;-L&#8221; definisce lo spazio massimo occupabile dal volume logico, chiaramente essendo un progetto con fini puramente didattici lo spazio è stato ridotto per facilitare e velocizzare le operazioni di creazione ed aggiornamento.<br />
All&#8217;interno della cartella /dev/mapper/ saranno quindi visibili i seguenti file:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># ls -la /dev/mapper/
totale 0
drwxr-xr-x  2 root root     100 2010-09-14 12:15 .
drwxr-xr-x 17 root root    3700 2010-09-14 12:15 ..
crw-rw----  1 root root  10, 59 2010-09-14 12:15 control
brw-rw----  1 root disk 251,  0 2010-09-14 12:15 vg_share-lv_drbd0
brw-rw----  1 root disk 251,  1 2010-09-14 12:15 vg_share-lv_drbd1</pre></div></div>

<p>a dimostrazione che i volumi logici sono pronti ad essere utilizzati.</p>
<p><strong>Configurazione preliminare di Heartbeat</strong></p>
<p>La configurazione preliminare di Heartbeat si rifà totalmente a quanto illustrato nel <a href="http://www.miamammausalinux.org/2010/06/evoluzione-dellalta-affidabilita-su-linux-confronto-pratico-tra-heartbeat-classico-ed-heartbeat-con-pacemaker/">precedente articolo</a> al paragrafo &#8220;Configurazione di Heartbeat in modalità CRM con Pacemaker&#8221;:</p>
<p><em>/etc/ha.d/ha.cf</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">autojoin none
keepalive 1
deadtime 10
warntime 5
initdead 20
mcast eth0 239.0.0.43 694 1 0
bcast eth1
node    debian-lenny-nodo1
node    debian-lenny-nodo2
crm respawn</pre></div></div>

<p><em>/etc/ha.d/authkeys</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">auth 1
1 crc</pre></div></div>

<p>Quindi una volta avviato Heartbeat:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># /etc/init.d/heartbeat start</pre></div></div>

<p>è possibile definire le configurazioni preliminari del cluster:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># crm configure property stonith-enabled=&quot;false&quot;
# crm configure property no-quorum-policy=&quot;ignore&quot;
# crm configure primitive ping ocf:pacemaker:ping params host_list=&quot;192.168.1.1&quot; name=&quot;ping&quot; op monitor interval=&quot;10s&quot; timeout=&quot;60s&quot; op start timeout=&quot;60s&quot; op stop timeout=&quot;60s&quot;
# crm configure clone ping_clone ping meta globally-unique=&quot;false&quot;</pre></div></div>

<p>In breve viene disabilitato lo <em>stonith</em>, viene imposto al cluster di ignorare l&#8217;assenza di <em>quorum</em> e viene definita una risorsa <em>ping</em> che controlla la connettività in entrambi i nodi attraverso il <em>clone</em> della risorsa stessa.<br />
La situazione del cluster viene così riassunta:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># crm status
============
Last updated: Tue Sep 14 12:17:29 2010
Stack: Heartbeat
Current DC: debian-lenny-nodo1 (1627f3ec-ec7e-4f0c-b69e-e9729933a2cc) - partition with quorum
Version: 1.0.8-042548a451fce8400660f6031f4da6f0223dd5dd
2 Nodes configured, unknown expected votes
1 Resources configured.
============
&nbsp;
Online: [ debian-lenny-nodo1 debian-lenny-nodo2 ]
&nbsp;
 Clone Set: ping_clone
     Started: [ debian-lenny-nodo1 debian-lenny-nodo2 ]</pre></div></div>

<p>Per qualsiasi dubbio in merito alle configurazioni sopra riportate, come già detto, è bene far riferimento al <a href="http://www.miamammausalinux.org/2010/06/evoluzione-dellalta-affidabilita-su-linux-confronto-pratico-tra-heartbeat-classico-ed-heartbeat-con-pacemaker/">precedente articolo</a>.</p>
<p><strong>Configurazione preliminare di DRBD</strong></p>
<p>In questa fase del progetto è necessario configurare i due volumi logici creati in precedenza affinché possano essere utilizzati con DRBD. Per prima cosa il sistema deve essere predisposto per supportare DRBD, il che significa che vanno installati i pacchetti relativi al <em>modulo</em> che verrà inserito all&#8217;interno del <em>kernel</em>. Come sempre tutto dipende dalla distribuzione che si sta utilizzando, nel caso illustrato Debian offre il meta pacchetto <em>drbd8-modules-2.6-686</em> che si occupa di installare la corretta versione associata al kernel utilizzato:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">apt-get install drbd8-modules-2.6-686 drbd8-utils</pre></div></div>

<p>Con Ubuntu è sufficiente installare il pacchetto <em>drbd8-utils</em> che risolverà le dipendenze ed installerà il modulo, stesso dicasi per SuSe, mentre per RedHat è necessario utilizzare i pacchetti Extra di CentOS.<br />
Maggiori informazioni sulle versioni disponibili sono qui: <a href="http://www.drbd.org/download/packages/">http://www.drbd.org/download/packages/</a>.</p>
<p>Installato il modulo, per configurare i due volumi logici i passi da seguire sono semplicissimi. In prima istanza va modificato il file /etc/drbd.conf come segue:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">global { usage-count no; }
&nbsp;
common { protocol C; syncer { rate 100M; } }
&nbsp;
resource r0 {
        device /dev/drbd0;
        meta-disk internal;
        disk /dev/mapper/vg_share-lv_drbd0;
&nbsp;
        on debian-lenny-nodo1 {
                address 10.0.0.1:7788;
        }
&nbsp;
        on debian-lenny-nodo2 {
                address 10.0.0.2:7788;
        }
}
&nbsp;
resource r1 {
        device /dev/drbd1;
        meta-disk internal;
        disk /dev/mapper/vg_share-lv_drbd1;
&nbsp;
        on debian-lenny-nodo1 {
                address 10.0.0.1:7789;
        }
&nbsp;
        on debian-lenny-nodo2 {
                address 10.0.0.2:7789;
        }
}</pre></div></div>

<p>Le dichiarazioni presenti nel file sono auto esplicative: Il tipo di algoritmo con cui verrà gestita la sincronizzazione è C (replicazione sincrona, standard, <a href="http://www.drbd.org/users-guide/s-replication-protocols.html">qui i dettagli sui diversi protocolli disponibili</a>), mentre la velocità a cui i dati verranno sincronizzati è 100 Mega (<a href="http://www.drbd.org/users-guide/s-resync.html">qui come calcolare la corretta velocità di sincronizzazione</a>).<br />
sono state definite due risorse (<em>resource</em>) che poggeranno su volumi logici interni (<em>disk</em>) e registreranno i meta-dati relativi alla sincronizzazione internamente (<em>meta-disk</em>), ciascuna risorsa farà viaggiare le informazioni per la sincronizzazione sull&#8217;interfaccia locale relativa alla rete 10.0.0.0 (<em>address</em>) ad una porta differente (<em>7788</em> e <em>7789</em>).</p>
<p>A questo punto i volumi logici vanno inizializzati in modo che il sistema possa iniziare a servirsi dei device. Le operazioni da compiere in sequenza, su entrambi i nodi, sono le seguenti:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="console" style="font-family:monospace;"># modprobe drbd
# drbdadm create-md r0
# drbdadm create-md r1
# drbdadm up r0
# drbdadm up r1</pre></td></tr></table></div>

<p>Linea per linea, ecco quanto fatto:</p>
<ol>
<li>Caricamento del modulo drbd: il sistema è in grado di supportare dispositivi drbd;</li>
<li>Creazione del <em>meta-device</em> sopra il volume logico r0, così come dichiarato nel file di configurazione, il volume /dev/mapper/vg_share-lv_drbd0 viene inizializzato;</li>
<li>Creazione del <em>meta-device</em> sopra il volume logico r1, così come dichiarato nel file di configurazione, il volume /dev/mapper/vg_share-lv_drbd1 viene inizializzato;</li>
<li>Attivazione del <em>meta-device</em>, da questo momento il sistema &#8220;vede&#8221; /dev/drbd0;</li>
<li>Attivazione del <em>meta-device</em>, da questo momento il sistema &#8220;vede&#8221; /dev/drbd1;</li>
</ol>
<p>Come ultima fase per l&#8217;inizializzazione dei dispositivi è necessario effettuare la prima sincronizzazione in modo che i volumi remoti vengano allineati. Per far ciò è necessario lanciare il seguente comando su uno solo dei due nodi:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># drbdadm -- --overwrite-data-of-peer primary all</pre></div></div>

<p>Il comando forza lo stato primario del nodo su cui è stato lanciato ed avvia nel contempo la prima sincronizzazione, al termine della quale lo stato dei meta-device drbd sarà il seguente:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># cat /proc/drbd 
version: 8.3.7 (api:88/proto:86-91)
GIT-hash: ea9e28dbff98e331a62bcbcc63a6135808fe2917 build by root@debian-lenny-nodo1, 2010-09-13 18:03:02
 0: cs:Connected ro:Secondary/Secondary ds:UpToDate/UpToDate C r----
    ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0
 1: cs:Connected ro:Secondary/Secondary ds:UpToDate/UpToDate C r----
    ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0</pre></div></div>

<p>Per concludere la configurazione preliminare di drbd andrà creato un filesystem su ciascuno dei device creati:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># mkfs.ext3 /dev/drbd0
# mkfs.ext3 /dev/drbd1</pre></div></div>

<p>E rimosso l&#8217;avvio automatico del demone dal sistema, poiché questo verrà gestito totalmente dal cluster. Per Debian ed Ubuntu il comando da lanciare sarà:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># update-rc.d -f drbd remove</pre></div></div>

<p>mentre nel caso di RedHat/CentOS/SuSe:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># chkconfig --level 123456 drbd off</pre></div></div>

<p>E&#8217; giunto il momento di configurare lo storage condiviso.</p>
<p><strong>Configurazione di Heartbeat e DRBD</strong></p>
<p>Prima implementare l&#8217;esposizione dello spazio che abbiamo creato via NFS è necessario configurare il cluster affinché gestisca i dispositivi DRBD e ne amministri lo stato. Come stabilito in precedenza infatti, il controllo di tali componenti sarà totalmente nelle mani del cluster e non del sistema operativo. In altre parole i due componenti DRBD non saranno gestiti come demoni, ma come due risorse distinte.<br />
DRBD, rispetto a quanto illustrato sinora, non è una risorsa standard: non è assimilabile infatti alle risorse comuni poiché necessità di risiedere su (almeno) due nodi, questa peculiarità però non permette comunque di creare un clone della risorsa da ripartire sulle altre macchine, poiché in ciascuno dei nodi su cui essa sarà attiva questa dovrà assumere uno stato differente.<br />
Per questa ragione, dopo aver definito le risorse standard associate ai dispositivi DRBD in precedenza creati (r0 ed r1):</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># crm configure primitive drbd0 ocf:linbit:drbd params drbd_resource=&quot;r0&quot; op monitor interval=&quot;20s&quot; timeout=&quot;40s&quot; op start interval=&quot;0&quot; timeout=&quot;240s&quot; op stop interval=&quot;0&quot; timeout=&quot;100s&quot;
# crm configure primitive drbd1 ocf:linbit:drbd params drbd_resource=&quot;r1&quot; op monitor interval=&quot;20s&quot; timeout=&quot;40s&quot; op start interval=&quot;0&quot; timeout=&quot;240s&quot; op stop interval=&quot;0&quot; timeout=&quot;100s&quot;</pre></div></div>

<p> è necessario configurare due risorse <em>multi-state</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># crm configure ms ms-drbd0 drbd0 meta master-max=&quot;1&quot; notify=&quot;true&quot;
# crm configure ms ms-drbd1 drbd1 meta master-max=&quot;1&quot; notify=&quot;true&quot;</pre></div></div>

<p>I due comandi, ciascuno relativo ad una risorsa DRBD, definiscono una risorsa <em>multi-state</em> che può avere un solo nodo master (<em>master-max</em>) il quale una volta assunto il proprio stato (master o slave che sia) deve notificare il successo agli altri nodi (<em>notify</em>), in modo che la risorsa sia in uno stato coerente su entrambi i nodi.<br />
Dopo qualche secondo sarà possibile osservare all&#8217;interno dello stato del cluster quanto realizzato:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">============
Last updated: Wed Sep 15 20:16:44 2010
Stack: Heartbeat
Current DC: debian-lenny-nodo1 (1627f3ec-ec7e-4f0c-b69e-e9729933a2cc) - partition with quorum
Version: 1.0.8-042548a451fce8400660f6031f4da6f0223dd5dd
2 Nodes configured, unknown expected votes
3 Resources configured.
============
&nbsp;
Online: [ debian-lenny-nodo1 debian-lenny-nodo2 ]
&nbsp;
 Clone Set: ping_clone
     Started: [ debian-lenny-nodo1 debian-lenny-nodo2 ]
 Master/Slave Set: ms-drbd0
     Masters: [ debian-lenny-nodo1 ]
     Slaves: [ debian-lenny-nodo2 ]
 Master/Slave Set: ms-drbd1
     Masters: [ debian-lenny-nodo1 ]
     Slaves: [ debian-lenny-nodo2 ]</pre></div></div>

<p>Come si evince dall&#8217;output mostrato il nodo master per entrambe le risorse è <em>debian-lenny-nodo1</em>.</p>
<p>Ora che il cluster controlla i dispositivi è necessario esporli. Per fare ciò sono necessarie tre componenti:</p>
<ol>
<li>Indirizzo IP: ossia l&#8217;indirizzo di riferimento per l&#8217;intera rete a quela specifica condivisione;</li>
<li>Filesystem: ovvero il <em>mount</em> del filesystem relativo alla risorsa DRBD in modo che ci si possa scrivere sopra;</li>
<li>NFS: in modo da esporre la condivisione con il protocollo NFS e permettere il mount da parte di client di rete;</li>
</ol>
<p>Esisteranno quindi due gruppi di risorse contenenti le tre risorse descritte, tali gruppi verranno nominati come le cartelle che dovranno esporre, così come definito in fase di studio del progetto: <em>share-a</em> e <em>share-b</em>.</p>
<p><em>Indirizzo IP</em></p>
<p>La configurazione degli indirizzi IP è identica a quanto illustrato nel precedente articolo:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># crm configure primitive share-a-ip ocf:heartbeat:IPaddr2 params ip=&quot;192.168.1.33&quot; nic=&quot;eth0&quot; op monitor interval=&quot;20s&quot; timeout=&quot;40s&quot;
# crm configure primitive share-b-ip ocf:heartbeat:IPaddr2 params ip=&quot;192.168.1.34&quot; nic=&quot;eth0&quot; op monitor interval=&quot;20s&quot; timeout=&quot;40s&quot;</pre></div></div>

<p>al gruppo che eroga <em>share-a</em> pertanto verrà associato l&#8217;indirizzo 192.168.1.33 mentre a <em>share-b</em> 192.168.1.34, entrambe le risorse sono gestite dal il <em>resource agent IPAddr2</em>.</p>
<p><em>Filesystem</em></p>
<p>Il dispositivo <em>/dev/drbd0</em> verrà associato a <em>share-a</em> ed alla directory <em>/share-a</em>, così come <em>share-b</em> monterà <em>/dev/drbd1</em> sulla directory <em>/share-b</em>.<br />
Andranno quindi create le directory per i mount su entrambi i nodi:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># mkdir /share-a
# mkdir /share-b</pre></div></div>

<p>Ed infine configurate le risorse attraverso il <em>resource agent Filesystem</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># crm configure primitive share-a-fs ocf:heartbeat:Filesystem params device=&quot;/dev/drbd0&quot; directory=&quot;/share-a&quot; fstype=&quot;ext3&quot; op monitor interval=&quot;20s&quot; timeout=&quot;40s&quot; op start interval=&quot;0&quot; timeout=&quot;60s&quot; op stop interval=&quot;0&quot; timeout=&quot;60s&quot; meta is-managed=&quot;true&quot; 
# crm configure primitive share-b-fs ocf:heartbeat:Filesystem params device=&quot;/dev/drbd1&quot; directory=&quot;/share-b&quot; fstype=&quot;ext3&quot; op monitor interval=&quot;20s&quot; timeout=&quot;40s&quot; op start interval=&quot;0&quot; timeout=&quot;60s&quot; op stop interval=&quot;0&quot; timeout=&quot;60s&quot; meta is-managed=&quot;true&quot;</pre></div></div>

<p><em>NFS</em></p>
<p>Per permettere l&#8217;esportazione di ciascuna share in maniera indipendente, fermo restando che su ogni sistema il demone NFS deve essere in esecuzione, è possibile utilizzare un <em>resource agent</em> denominato <em>exportfs</em>.<br />
Questo <em>resource agent</em> creato da <em>Holger Teutsch</em>, potrebbe non essere disponibile se non si possiede una versione recente di Heartbeat (successiva al marzo 2010). In questo caso il problema è facilmente risolvibile installando il resource agent su entrambi i nodi come segue:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># cd /usr/lib/ocf/resource.d/heartbeat/
# wget http://hg.linux-ha.org/agents/raw-file/c8d8b1126ffd/heartbeat/exportfs
# chmod +x exportfs</pre></div></div>

<p>In questo modo sarà possibile dichiarare due risorse exportfs affinché espongano le due cartelle:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># crm configure primitive share-a-exportfs ocf:heartbeat:exportfs params directory=&quot;/share-a&quot; clientspec=&quot;192.168.1.0/24&quot; options=&quot;rw,async,no_subtree_check,no_root_squash&quot; fsid=&quot;1&quot; op monitor interval=&quot;10s&quot; timeout=&quot;30s&quot; op start interval=&quot;0&quot; timeout=&quot;40s&quot; op stop interval=&quot;0&quot; timeout=&quot;40s&quot;
# crm configure primitive share-b-exportfs ocf:heartbeat:exportfs params directory=&quot;/share-b&quot; clientspec=&quot;192.168.1.0/24&quot; options=&quot;rw,async,no_subtree_check,no_root_squash&quot; fsid=&quot;2&quot; op monitor interval=&quot;10s&quot; timeout=&quot;30s&quot; op start interval=&quot;0&quot; timeout=&quot;40s&quot; op stop interval=&quot;0&quot; timeout=&quot;40s&quot;</pre></div></div>

<p>Il <em>resource agent exportfs</em> si occupa di aggiornare in tempo reale lo stato delle export NFS di sistema, utilizzando appunto il comando <em>exportfs</em>.<br />
Come è facile notare la dichiarazione del resource agent si rifà totalmente alla sintassi del comando exportfs, o più semplicemente al contenuto del file <em>/etc/exports</em> (ossia il file di configurazione di NFS), in particolare:</p>
<ul>
<li><em>directory</em> definisce la directory locale che verrà esportata;</li>
<li><em>client_spec</em> definisce quali client potranno accedere alla condivisione;</li>
<li><em>options</em> contiene le opzioni di esportazione: lettura/scrittura (<em>rw</em>), l&#8217;allineamento del filesystem sarà asincrono (<em>async</em>) e tutto il volume verrà esportato senza controllo alle sotto directory (<em>no_subtree_check</em>), infine sarà possibile per l&#8217;utente root del client remoto avere privilegi di root sulla condivisione (no_root_squash);</li>
<li><em>fsid</em> definisce un identificatore univoco per la condivisione;</li>
</ul>
<p><em>Raggruppare le risorse create</em></p>
<p>Ora che è terminata la creazione delle risorse, è facile notare come queste abbiano nomi riconducibili al loro utilizzo, ma  siano in realtà slegate le une dalle altre. Necessitano quindi, per una corretta gestione, di essere raggruppate. Pacemaker permette di creare quindi gruppi di risorse, la cui definizione sequenziale stabilisce anche l&#8217;ordine con cui le risorse verranno avviate:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># crm configure group share-a share-a-fs share-a-exportfs share-a-ip
# crm configure group share-b share-b-fs share-b-exportfs share-b-ip</pre></div></div>

<p>Sono stati quindi definiti due gruppi <em>share-a</em> e <em>share-b</em> che avvieranno innanzitutto il filesystem, seguito dall&#8217;export dello stesso via NFS ed infine l&#8217;indirizzo IP. Chiaramente in fase di stop l&#8217;ordine sarà logicamente invertito, garantendo in caso di disservizi ai client remoti in prima istanza di perdere connettività con il server (i client non rilevando più l&#8217;indirizzo del server tratterranno le connessioni esistenti in stato di attesa, <em>TIME_WAIT</em>) e, una volta che le risorse saranno ripristinate sul nodo attivo, di continuare a scrivere senza alcuna perdita di dati.</p>
<p><em>Collocazione, ordinamento e controllo connettività delle risorse</em></p>
<p>La configurazione del cluster non è però ancora completa. Le risorse <em>drbd</em> ed i gruppi <em>share</em> al momento non sono correlati. Infatti per come è stato configurato il sistema su un nodo potrebbe avviarsi <em>share-a</em>, ma non esserci la risorsa <em>drbd0</em> promossa allo stato di <em>master</em>, quindi non utilizzabile come mount point, né scrivibile.<br />
Per ovviare a questa potenziale situazione, è necessario associare i gruppi <em>share</em> ai nodi su cui la risorsa <em>drbd</em> è <em>master</em>.<br />
Pacemaker gestisce queste operazioni attraverso le <em>colocation</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># crm configure colocation share-a_on_ms-drbd0 inf: share-a ms-drbd0:Master
# crm configure colocation share-b_on_ms-drbd1 inf: share-b ms-drbd1:Master</pre></div></div>

<p>Viene definita per entrambi i gruppi <em>share</em> una <em>colocation</em> di peso infinito (<em>inf</em>, quindi senza possibilità di variazione) per cui il gruppo si avvierà solo laddove la risorsa <em>multi-state</em> è in stato <em>master</em>.</p>
<p>E&#8217; necessaria un&#8217;altra condizione per aggiungere coerenza alla configurazione e riguarda l&#8217;ordinamento nell&#8217;avvio delle risorse. Chiaramente ciascun gruppo <em>share</em> non ha ragione di avviarsi se non dopo che il dispositivo <em>drbd</em> è attivo. Pacemaker gestisce la cosa attraverso le definizioni <em>order</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># crm configure order share-a_after_ms-drbd0 inf: ms-drbd0:promote share-a:start
# crm configure order share-a_after_ms-drbd1 inf: ms-drbd1:promote share-b:start</pre></div></div>

<p>Viene definita una <em>order</em> di peso infinito in cui l&#8217;operazione di promozione a <em>master</em> della risorsa <em>multi-state</em> vincola l&#8217;avvio del gruppo <em>share</em>.</p>
<p>A completamento della configurazione non rimane che associare le risorse ai nodi con connettività, facendo riferimento alla risorsa <em>ping</em> dichiarata in precedenza e clonata in tutti i nodi:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># crm configure location share-a_on_connected_node share-a rule -inf: not_defined ping or ping lte 0
# crm configure location share-b_on_connected_node share-b rule -inf: not_defined ping or ping lte 0</pre></div></div>

<p>Viene definita una <em>location</em> relativa ai gruppi <em>share</em> la cui regola di peso meno infinito (<em>-inf</em>) si verifica in assenza di connettività: la risorsa ping non è definita oppure restituisce un valore negativo.<br />
In questo modo quando un nodo che ospita un gruppo perderà la connettività Pacemaker tenterà di effettuare uno <em>switch</em> del gruppo su un altro nodo attivo.</p>
<p><em>Cleanup finale</em></p>
<p>Ora che la configurazione del cluster è completa è facile immaginare come tutte le operazioni effettuate possano aver falsato lo stato generale del cluster, quindi, al fine di partire da una situazione pura, è possibile lanciare i seguenti comandi:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># crm resource cleanup share-a
# crm resource cleanup share-b</pre></div></div>

<p>L&#8217;operazione di cleanup della risorsa come dice il nome, azzera il conteggio degli errori per le risorse e le riavvia ordinatamente in modo da, come detto, partire da zero a vagliare eventuali problemi.<br />
Lo stato del cluster a configurazione ultimata dovrebbe essere quindi il seguente:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># crm status
============
Last updated: Fri Sep 17 14:33:16 2010
Stack: Heartbeat
Current DC: debian-lenny-nodo1 (1627f3ec-ec7e-4f0c-b69e-e9729933a2cc) - partition with quorum
Version: 1.0.8-042548a451fce8400660f6031f4da6f0223dd5dd
2 Nodes configured, unknown expected votes
5 Resources configured.
============
&nbsp;
Online: [ debian-lenny-nodo1 debian-lenny-nodo2 ]
&nbsp;
 Clone Set: ping_clone
     Started: [ debian-lenny-nodo1 debian-lenny-nodo2 ]
 Master/Slave Set: ms-drbd0
     Masters: [ debian-lenny-nodo2 ]
     Slaves: [ debian-lenny-nodo1 ]
 Master/Slave Set: ms-drbd1
     Masters: [ debian-lenny-nodo1 ]
     Slaves: [ debian-lenny-nodo2 ]
 Resource Group: share-a
     share-a-fs (ocf::heartbeat:Filesystem):    Started debian-lenny-nodo1
     share-a-exportfs   (ocf::heartbeat:exportfs):      Started debian-lenny-nodo1
     share-a-ip (ocf::heartbeat:IPaddr2):       Started debian-lenny-nodo1
 Resource Group: share-b
     share-b-fs (ocf::heartbeat:Filesystem):    Started debian-lenny-nodo2
     share-b-exportfs   (ocf::heartbeat:exportfs):      Started debian-lenny-nodo2
     share-b-ip (ocf::heartbeat:IPaddr2):       Started debian-lenny-nodo2</pre></div></div>

<p><strong>Creare una configurazione active active</strong></p>
<p>Il progetto iniziale prevede che nessun nodo, in condizioni normali, sia passivo. Pertanto per completare la configurazione del cluster è necessario assegnare ciascun gruppo <em>share</em> ad uno specifico nodo.<br />
Tale risultato è ottenibile mediante l&#8217;aggiunta di due ulteriori regole di tipo <em>location</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">location cli-prefer-share-a share-a rule inf: #uname eq debian-lenny-nodo1
location cli-prefer-share-b share-b rule inf: #uname eq debian-lenny-nodo2</pre></div></div>

<p>In questo modo, la regola creata impone che <em>share-a</em> venga associata al nodo <em>debian-lenny-nodo1</em> mentre <em>share-b</em> al nodo <em>debian-lenny-nodo2</em>: i due nodi saranno entrambi operativi, completando così l&#8217;obiettivo deciso in fase di progettazione.</p>
<p><em>Considerazioni sulla stickiness</em></p>
<p>La politica del cluster in merito al posizionamento di una risorsa dipende dal peso che questa ha. Il peso viene stabilito in base alle condizioni del cluster e della risorsa stessa. Molte delle regole relative a definizioni di <em>location</em> e <em>order</em> fanno infatti riferimento a pesi infiniti in modo che se queste si verificano lo stato del cluster DEVE variare.<br />
Lo <em>stickiness</em> di una risorsa rappresenta il peso necessario al suo spostamento dalla posizione attuale nel momento in cui il cluster subisce variazioni.</p>
<p><em>Ad esempio&#8230;</em></p>
<p>Il valore di default della <em>stickyness</em> è 0.  se una risorsa viene migrata a mano, il cluster aggiunge una regola di <em>location</em> come quelle descritte poco sopra. Se il nodo che eroga la risorsa perde di connettività, allora questa, per la sua sopravvivenza, verrà migrata sul nodo attivo. Quando però il nodo originale tornerà a vivere, la risorsa, per via della regola impostata, verrà nuovamente migrata in quanto non ha vincoli (la <em>stickiness</em> è 0) che la legano al nodo attuale. Questo significa che nel giro i poco tempo si assisterà a due <em>switch</em> della risorsa, assimilabili a due interruzioni di servizio.<br />
Facile capire come non sempre questo possa essere il comportamento desiderato. Basti pensare al caso di database Oracle, ed a tutti i problemi che comporta uno <em>switch</em>.<br />
Inutile dire che meno sono, meglio è.<br />
Fortunatamente Pacemaker consente di impostare il valore di default di <em>stickiness</em> a infinito:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">crm configure property default-resource-stickiness=INFINITY</pre></div></div>

<p>In questo modo se una risorsa associata ad un nodo migra, alla ricomparsa del nodo questa rimarrà dov&#8217;è, limitando ulteriori disservizi.<br />
A seconda della decisione presa in merito alla stickiness, si dovrà quindi scegliere se questa dovrà rimanere al suo valore di default o avere altri valori (numeri maggiori di zero per arrivare ad <em>INFINITY</em>).</p>
<p><strong>Configurazione finale</strong></p>
<p>La configurazione estesa (modificabile attraverso il comando <em>crm configure edit</em>) è la seguente:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">node $id=&quot;1627f3ec-ec7e-4f0c-b69e-e9729933a2cc&quot; debian-lenny-nodo1
node $id=&quot;f4380aee-c67b-4472-9449-5fa8e5ddae34&quot; debian-lenny-nodo2
primitive drbd0 ocf:linbit:drbd \
	params drbd_resource=&quot;r0&quot; \
	op monitor interval=&quot;20s&quot; timeout=&quot;40s&quot; \
	op start interval=&quot;0&quot; timeout=&quot;240s&quot; \
	op stop interval=&quot;0&quot; timeout=&quot;100s&quot;
primitive drbd1 ocf:linbit:drbd \
	params drbd_resource=&quot;r1&quot; \
	op monitor interval=&quot;20s&quot; timeout=&quot;40s&quot; \
	op start interval=&quot;0&quot; timeout=&quot;240s&quot; \
	op stop interval=&quot;0&quot; timeout=&quot;100s&quot;
primitive ping ocf:pacemaker:ping \
	params host_list=&quot;192.168.1.1&quot; name=&quot;ping&quot; \
	op monitor interval=&quot;10s&quot; timeout=&quot;60s&quot; \
	op start interval=&quot;0&quot; timeout=&quot;60s&quot; \
	op stop interval=&quot;0&quot; timeout=&quot;60s&quot;
primitive share-a-exportfs ocf:heartbeat:exportfs \
	params directory=&quot;/share-a&quot; clientspec=&quot;192.168.1.0/24&quot; options=&quot;rw,async,no_subtree_check,no_root_squash&quot; fsid=&quot;1&quot; \
	op monitor interval=&quot;10s&quot; timeout=&quot;30s&quot; \
	op start interval=&quot;0&quot; timeout=&quot;40s&quot; \
	op stop interval=&quot;0&quot; timeout=&quot;40s&quot;
primitive share-a-fs ocf:heartbeat:Filesystem \
	params device=&quot;/dev/drbd0&quot; directory=&quot;/share-a&quot; fstype=&quot;ext3&quot; \
	op monitor interval=&quot;20s&quot; timeout=&quot;40s&quot; \
	op start interval=&quot;0&quot; timeout=&quot;60s&quot; \
	op stop interval=&quot;0&quot; timeout=&quot;60s&quot; \
	meta is-managed=&quot;true&quot;
primitive share-a-ip ocf:heartbeat:IPaddr2 \
	params ip=&quot;192.168.1.33&quot; nic=&quot;eth0&quot; \
	op monitor interval=&quot;20s&quot; timeout=&quot;40s&quot;
primitive share-b-exportfs ocf:heartbeat:exportfs \
	params directory=&quot;/share-b&quot; clientspec=&quot;192.168.1.0/24&quot; options=&quot;rw,async,no_subtree_check,no_root_squash&quot; fsid=&quot;2&quot; \
	op monitor interval=&quot;10s&quot; timeout=&quot;30s&quot; \
	op start interval=&quot;0&quot; timeout=&quot;40s&quot; \
	op stop interval=&quot;0&quot; timeout=&quot;40s&quot;
primitive share-b-fs ocf:heartbeat:Filesystem \
	params device=&quot;/dev/drbd1&quot; directory=&quot;/share-b&quot; fstype=&quot;ext3&quot; \
	op monitor interval=&quot;20s&quot; timeout=&quot;40s&quot; \
	op start interval=&quot;0&quot; timeout=&quot;60s&quot; \
	op stop interval=&quot;0&quot; timeout=&quot;60s&quot; \
	meta is-managed=&quot;true&quot;
primitive share-b-ip ocf:heartbeat:IPaddr2 \
	params ip=&quot;192.168.1.34&quot; nic=&quot;eth0&quot; \
	op monitor interval=&quot;20s&quot; timeout=&quot;40s&quot;
group share-a share-a-fs share-a-exportfs share-a-ip
group share-b share-b-fs share-b-exportfs share-b-ip
ms ms-drbd0 drbd0 \
	meta master-max=&quot;1&quot; notify=&quot;true&quot;
ms ms-drbd1 drbd1 \
	meta master-max=&quot;1&quot; notify=&quot;true&quot;
clone ping_clone ping \
	meta globally-unique=&quot;false&quot;
location cli-prefer-share-a share-a \
	rule $id=&quot;cli-prefer-rule-share-a&quot; inf: #uname eq debian-lenny-nodo1
location cli-prefer-share-b share-b \
	rule $id=&quot;cli-prefer-share-b-rule&quot; inf: #uname eq debian-lenny-nodo2
location share-a_on_connected_node share-a \
	rule $id=&quot;share-a_on_connected_node-rule&quot; -inf: not_defined ping or ping lte 0
location share-b_on_connected_node share-b \
	rule $id=&quot;share-b_on_connected_node-rule&quot; -inf: not_defined ping or ping lte 0
colocation share-a_on_ms-drbd0 inf: share-a ms-drbd0:Master
colocation share-b_on_ms-drbd1 inf: share-b ms-drbd1:Master
order share-a_after_ms-drbd0 inf: ms-drbd0:promote share-a:start
order share-a_after_ms-drbd1 inf: ms-drbd1:promote share-b:start
property $id=&quot;cib-bootstrap-options&quot; \
	dc-version=&quot;1.0.8-042548a451fce8400660f6031f4da6f0223dd5dd&quot; \
	cluster-infrastructure=&quot;Heartbeat&quot; \
	stonith-enabled=&quot;false&quot; \
	no-quorum-policy=&quot;ignore&quot; \
	last-lrm-refresh=&quot;1284661245&quot;</pre></div></div>

<p><strong>Test funzionale</strong></p>
<p>Una volta montato da parte di un client lo share NFS:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># mount -t nfs 192.168.1.33:/share-a /mnt/</pre></div></div>

<p>è possibile lanciare sempre sul client una copia arbitraria di file:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">cp -av /usr/ /mnt/</pre></div></div>

<p>partirà la copia dei file e sarà possibile agire quindi sul cluster, tenendo monitorato sia la copia che lo stato attraverso <em>crm_mon</em>.</p>
<p><em>Primo test: disconnessione cavo LAN nodo master</em></p>
<p>Alla disconnessione del cavo la risorsa <em>ping</em> avverte immediatamente l&#8217;assenza di connettività e forza la migrazione del gruppo <em>share-a</em> al nodo rimanente, in questo caso il debian-lenny-nodo1. Il tutto è osservabile dal file /var/log/syslog:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">Sep 17 18:05:35 debian-lenny-nodo2 heartbeat: [1079]: info: Link debian-lenny-nodo1:eth0 dead.
...
Sep 17 18:05:46 debian-lenny-nodo2 kernel: [20384.996634] block drbd1: peer( Primary -&gt; Secondary ) 
...
Sep 17 18:05:50 debian-lenny-nodo2 Filesystem[27581]: [27636]: INFO: Running start for /dev/drbd0 on /share-a
...
Sep 17 18:05:50 debian-lenny-nodo2 kernel: [20389.636665] EXT3-fs: mounted filesystem with ordered data mode.
...
Sep 17 18:05:51 debian-lenny-nodo2 exportfs[27676]: [27739]: INFO: File system exported
...
Sep 17 18:05:52 debian-lenny-nodo2 IPaddr2[27764]: [27817]: INFO: ip link set eth0 up
...</pre></div></div>

<p>Lato client, la scrittura su NFS si ferma per qualche secondo e riparte appena l&#8217;ultima operazione di start è eseguita da Pacemaker.</p>
<p><em>Secondo test: migrazione manuale delle risorse</em></p>
<p>Lanciando il comando <em>migrate</em> sulla risorsa <em>share-a</em> viene forzato manualmente lo switch della risorsa dal nodo attuale al nodo indicato:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">crm resource migrate share-a debian-lenny-nodo1</pre></div></div>

<p>Quanto il cluster fa in questo genere di operazione è quello di modificare la stessa <em>location</em> descritta poco sopra:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># crm configure show
...
...
location cli-prefer-share-a share-a \
	rule $id=&quot;cli-prefer-rule-share-a&quot; -inf: #uname eq debian-lenny-nodo1
...
...</pre></div></div>

<p>In sostanza la <em>location</em> prima impostata su <em>share-a</em> è stata modificata da Pacemaker da <em>inf</em> a <em>-inf</em> invertendo il vincolo che legava la risorsa al nodo <em>debian-lenny-nodo1</em>.<br />
E&#8217; necessario porre particolare attenzione a questa regola, poiché il peso <em>-inf</em> implica che la risorsa sarà da qui in poi SEMPRE associata al nodo <em>debian-lenny-nodo2</em>, poiché non potrà più risiedere sul nodo originale.</p>
<p>Per ripristinare la situazione originaria e rimuovere la regola aggiunta esistono due modi:</p>
<ol>
<li>Lanciare il comando precedente utilizzando <em>unmigrate</em>, in modo che la risorsa torni sul nodo originale (e la regola verrà cancellata, eliminando anche l&#8217;impostazione della configurazione originale);</li>
<li>Modificare a mano la configurazione del cluster attraverso il comando <em>crm configure edit</em> rimuovendo la linea aggiunta automaticamente, in modo da lasciare la risorsa dove si trova ora senza vincolarne i futuri spostamenti;</li>
</ol>
<p>Lato client l&#8217;operazione è ancora più indolore di prima: dai log il comportamento è simile al precedente test e la scrittura sullo share NFS si ferma il tempo che la risorsa migra.</p>
<p><em>Terzo test: spegnimento improvviso nodo master</em></p>
<p>Lo spegnimento improvviso del nodo <em>master</em> rende il comportamento del cluster del tutto simile a quello illustrato primo test, con una differenza sostanziale:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">...
Sep 17 18:36:37 debian-lenny-nodo2 heartbeat: [1079]: WARN: node debian-lenny-nodo1: is dead
...
Sep 17 18:36:37 debian-lenny-nodo2 crmd: [1120]: WARN: check_dead_member: Our DC node (debian-lenny-nodo1) left the cluster
...
Sep 17 18:36:37 debian-lenny-nodo2 kernel: [22236.912107] block drbd0: peer( Primary -&gt; Unkno
wn ) conn( Connected -&gt; NetworkFailure ) pdsk( UpToDate -&gt; DUnknown ) 
...</pre></div></div>

<p>Il cluster ha dovuto rimpiazzare il proprio <em>DC</em> (<em>Designated Coordinator</em>) poiché spento ed ovviamente il dispositivo drbd è in stato <em>Primary</em> sul nodo sopravvissuto, ma ovviamente in stato <em>Unknown</em> nella sua replica.</p>
<p>Anche in questo caso, lato client tutto si è svolto in maniera trasparente, la copia si è fermata per qualche secondo per poi ripartire.</p>
<p><strong>Conclusioni</strong></p>
<p>La soluzione illustrata descrive a pieno le potenzialità del progetto Pacemaker. E&#8217; possibile combinare i suggerimenti espressi in questo lungo articolo immaginando di disporre di un cluster composto da più di due macchine, o segmentando ulteriormente le <em>share</em> esposte, creando ulteriori <em>volumi logici</em> e dispositivi <em>drbd</em>.<br />
Il tutto con dei costi decisamente contenuti rispetto alle soluzioni <em>NAS</em> in commercio: in pratica il solo prezzo dell&#8217;hardware!<br />
Bene, con quest&#8217;ultima parte la serie &#8220;Evoluzione dell&#8217;alta affidabilità su Linux&#8221; può dirsi conclusa. Sicuramente &#8220;Mia Mamma Usa Linux&#8221; tornerà su temi inerenti l&#8217;argomento, magari trattando l&#8217;integrazione delle tecniche di virtualizzazione nel cluster, utilizzando <em>virtual machines</em> come fossero risorse da migrare, magari senza necessità che i sistemi virtualizzati vengano spenti!<br />
Commenti sulla serie sono ben accetti, suggerimenti su futuri argomenti anche di più, proposte di collaborazione sono in assoluto il meglio.<br />
Lunga vita al software libero.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.miamammausalinux.org/2010/09/evoluzione-dellalta-affidabilita-su-linux-realizzare-un-nas-con-pacemaker-drbd-ed-exportfs/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>OpenVPN: connessione sicura attraverso Internet di molti client ad un server</title>
		<link>http://www.miamammausalinux.org/2010/05/openvpn-connessione-sicura-attraverso-internet-di-molti-client-ad-un-server/</link>
		<comments>http://www.miamammausalinux.org/2010/05/openvpn-connessione-sicura-attraverso-internet-di-molti-client-ad-un-server/#comments</comments>
		<pubDate>Tue, 04 May 2010 15:23:37 +0000</pubDate>
		<dc:creator>Francesco Pedrini</dc:creator>
				<category><![CDATA[Network]]></category>
		<category><![CDATA[OpenVPN]]></category>
		<category><![CDATA[VPN]]></category>

		<guid isPermaLink="false">http://www.miamammausalinux.org/?p=976</guid>
		<description><![CDATA[VPN significa, letteralmente Rete Privata Virtuale, cioè una serie di collegamenti virtuali e privati creati su un&#8217;infrastruttura ad accesso pubblico, come ad esempio Internet. Una rete privata virtuale consente di comunicare in maniera sicura attraverso un canale insicuro in una forma efficiente ed economica. In questo articolo vedremo come creare un server VPN a cui [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.miamammausalinux.org/wp-content/uploads/2010/05/openvpn.png"><img src="http://www.miamammausalinux.org/wp-content/uploads/2010/05/openvpn.png" alt="" width="100" height="26" class="alignnone size-full wp-image-1002" /></a></p>
<p>VPN significa, letteralmente Rete Privata Virtuale, cioè una serie di collegamenti virtuali e privati creati su un&#8217;infrastruttura ad accesso pubblico, come ad esempio Internet. Una rete privata virtuale consente di comunicare in maniera sicura attraverso un canale insicuro in una forma efficiente ed economica.</p>
<p>In questo articolo vedremo come creare un server VPN a cui far collegare diversi client, con l&#8217;obiettivo di creare una rete estesa e sicura. Il tutto verrà realizzato mediante il celebre software opensource <a title="OpenVPN" href="http://openvpn.net/">OpenVPN</a>.</p>
<p><strong>Un po&#8217; di teoria</strong></p>
<p>Prima di incominciare con la parte pratica, vediamo quali sono i concetti di base di una VPN.</p>
<p>L&#8217;esigenza alla base di una VPN è quella di creare un canale di comunicazione sicuro tra diversi soggetti, appoggiandosi ad un&#8217;infrastruttura già esistente, in modo da poter scambiare i propri dati come se si fosse connessi ad una grande rete LAN senza affrontare i costi altissimi per l&#8217;installazione di un&#8217;infrastruttura fisica tra diverse sedi.</p>
<p>Seguendo l&#8217;analogia che rappresenta Internet come un sistema idraulico, si può pensare ad una VPN come un &#8220;tubo dentro ad un tubo&#8221;.</p>
<p><strong>Tipologie di VPN</strong></p>
<p>Esistono innumerevoli tipi di tecnologie per la creazione di VPN che differiscono per diversi fattori, come ad esempio:</p>
<ul>
<li>I protocolli usati per creare i tunnel privati sulla rete sottostante;</li>
<li>La posizione degli endpoint dei tunnel;</li>
<li>Il livello di sicurezza fornito;</li>
<li>Il livello <a title="OSI" href="http://en.wikipedia.org/wiki/OSI_model">OSI</a> usato per l&#8217;interconnessione delle diverse reti;</li>
</ul>
<p>Attualmente vengono identificati tre tipologie principali di VPN:</p>
<ul>
<li>Trusted VPN</li>
<li>Secured VPN</li>
<li>Hybrid VPN</li>
</ul>
<p>Le VPN di tipo &#8216;Trusted&#8217; sono state le prime ad essere create e sono ancora in uso in alcuni ambienti come quelli bancari, si tratta di reti virtuali create a partire dall&#8217;hardware di rete: in questo caso esiste un <em>ISP</em> (<em>Internet Service Provider</em>) che stabilisce indirizzi e politiche di routing per il proprio cliente, creando così una vera e propria rete virtuale sulla propria infrastruttura. Il grosso vantaggio che forniscono queste reti è il fatto che il traffico viaggia su percorsi ben definiti ed è possibile stabilire in maniera molto semplice politiche di <em>QoS</em> (<em>la qualità del servizio offerto dalla rete</em>), anche se è necessario sacrificare un po&#8217; di flessibilità.</p>
<p>Le VPN di tipo &#8216;Secured&#8217; invece prevedono che il traffico venga incanalato su tunnel cifrati e spedito attraverso Internet come se fosse normale traffico. Nel caso in cui uno di questi pacchetti finisca nelle proverbiali mani sbagliate, le informazioni in esso contenute saranno comunque inaccessibili. Lo svantaggio rispetto alle trusted VPN è la mancanza di predeterminazione dei percorsi effettuati dai pacchetti.</p>
<p>L&#8217;ultima tipologia di VPN è, come suggerisce il nome, un mix tra le due tipologie precedenti, prendendo la sicurezza intrinseca nata dalla cifratura di tutto il traffico di rete delle Secured VPN e la possibilità di fare <em>QoS</em> in maniera semplice, tipica delle Trusted VPN.</p>
<p>OpenVPN permette di creare proprio Secured VPN.</p>
<p><strong>Installazione</strong></p>
<p>Giungiamo così alla parte più pratica dell&#8217;articolo, l&#8217;installazione e configurazione del servizio OpenVPN. L&#8217;articolo tratta l&#8217;installazione del software su un sistema operativo Debian Lenny, ma a pacchetti installati, le informazioni sono utilizzabili sulle più diffuse distribuzioni.</p>
<p>Verrà assunto inoltre che il router con il quale si accede ad internet permetta di fare l&#8217;apertura della porta 1194 TCP (e anche UDP se possibile) verso il vostro server.</p>
<p>Il primo step è naturalmente quello di installare openvpn:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># aptitude install openvpn</pre></div></div>

<p>Una volta installati i vari pacchetti, siamo pronti per sporcarci le mani.</p>
<p><strong>Generazione dei certificati</strong></p>
<p>Per la cifratura dei pacchetti OpenVPN usa il protocollo SSL, e per tanto è necessario generare tutta la serie di certificati per permettere sia la cifratura della connessione che l&#8217;autenticazione dei vari client.</p>
<p>Fortunatamente il pacchetto di OpenVPN fornisce una serie di script già pronti atti a tale scopo nel path <em>/usr/share/doc/openvpn/examples/easy-rsa/2.0/</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># ls /usr/share/doc/openvpn/examples/easy-rsa/2.0/
build-ca          build-key-server  Makefile              sign-req
build-dh          build-req         openssl-0.9.6.cnf.gz  vars
build-inter       build-req-pass    openssl.cnf           whichopensslcnf
build-key         clean-all         pkitool
build-key-pass    inherit-inter     README.gz
build-key-pkcs12  list-crl          revoke-full</pre></div></div>

<p>Nulla vieta di lasciare gli script li dove sono e copiare solo i file generati nella directory di configurazione di OpenVPN, io per comodità preferisco spostare tutta la directory sotto <em>/etc/openvpn/easy-rsa/</em>.</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0/ /etc/openvpn/easy-rsa
# cd /etc/openvpn/easy-rsa</pre></div></div>

<p>Tra i vari file potrete notare un file di testo chiamato &#8220;vars&#8221;, è un file che contiene tutte le variabili necessarie agli script di generazione di certificati e chiavi.<br />
Sebbene non sia necessario modificare i parametri preimpostati (poichè possono essere sovrascritti durante l&#8217;esecuzione dei vari script) risulta più comodo in caso di generazione di un gran numero di certificati.</p>
<p>I parametri da modificare sono i seguenti:</p>
<ul>
<li>KEY_SIZE</li>
<li>KEY_COUNTRY</li>
<li>KEY_PROVINCE</li>
<li>KEY_CITY</li>
<li>KEY_ORG</li>
<li>KEY_EMAIL</li>
</ul>
<p>Sono parametri abbastanza auto esplicativi, ecco come si presenta il mio file vars:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">export KEY_SIZE=2048
...
export KEY_COUNTRY=&quot;IT&quot;
export KEY_PROVINCE=&quot;IT&quot;
export KEY_CITY=&quot;Milano&quot;
export KEY_ORG=&quot;VostraAzienda&quot;
export KEY_EMAIL=&quot;my-email@vostraazienda.it&quot;</pre></div></div>

<p>A questo punto siamo pronti per generare la nostra <a href="http://it.wikipedia.org/wiki/Certificate_authority">certificate authority</a>, ossia la componente (auto generata) che validerà i certificati per la comunicazione, ed i certificati stessi.<br />
Prima di tutto dobbiamo fare in modo di esportare tutto ciò che è contenuto dentro al file &#8216;vars&#8217; appena modificato:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># source vars
NOTE: If you run ./clean-all, I will be doing a rm -rf on /etc/openvpn/easy-rsa/keys
# ./clean-all</pre></div></div>

<p>È necessario richiamare anche lo script &#8220;clean-all&#8221; per avere la certezza di partire con un ambiente pulito.</p>
<p>Ora possiamo generare la nostra <em>Certificate Authority</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># ./build-ca
Generating a 1024 bit RSA private key
..................................................++++++
...++++++
writing new private key to 'ca.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) [IT]:
State or Province Name (full name) [IT]:
Locality Name (eg, city) [Milano]:
Organization Name (eg, company) [VostraAzienda]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) [VostraAzienda CA]:
Email Address [my-email@vostraazienda.it]:</pre></div></div>

<p>Alla richiesta di input mi sono limitato semplicemente a premere invio, i dati erano già corretti poichè sono stati modificati nel file &#8216;vars&#8217;.<br />
Ora possiamo creare il certificato per il server VPN:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># ./build-key-server Gateway</pre></div></div>

<p><em>Gateway</em> è il nome della macchina su cui sto installando il server VPN, per coerenza la coppia chiave/certificato avrà il nome dell&#8217;host su cui viene usato. Vediamo l&#8217;esecuzione dello script:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">Generating a 1024 bit RSA private key
..................++++++
.++++++
writing new private key to 'Gateway.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) [IT]:
State or Province Name (full name) [IT]:
Locality Name (eg, city) [Milano]:
Organization Name (eg, company) [VostraAzienda]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) [Gateway]:
Email Address [me@myhost.mydomain]:
&nbsp;
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:password
An optional company name []:
Using configuration from /etc/openvpn/easy-rsa/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'IT'
stateOrProvinceName   :PRINTABLE:'IT'
localityName          :PRINTABLE:'Milano'
organizationName      :PRINTABLE:'VostraAzienda'
commonName            :PRINTABLE:'Gateway'
emailAddress          :IA5STRING:'my-email@vostraazienda.it'
Certificate is to be certified until Apr 25 13:50:00 2020 GMT (3650 days)
Sign the certificate? [y/n]:y
&nbsp;
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated</pre></div></div>

<p>Quando lo script chiede una password è lecito premere semplicemente invio per evitare di dover immettere la password ogni (ri)avvio di OpenVPN.</p>
<p>Generiamo ora il file <a href="http://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange">Diffie-Hellman</a>, necessario per l&#8217;avvio delle connessioni cifrate.<br />
Attenzione, è un&#8217;operazione MOLTO lunga, quindi preparatevi a prendervi un paio di caffè&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># ./build-dh
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time
........+............</pre></div></div>

<p>Dopo la vostra ristorante pausa caffè, passiamo a generare l&#8217;ultima chiave necessaria per l&#8217;instaurazione di una connessione sicura, questa chiave dovrà essere copiata anche su tutti i client.</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># openvpn --genkey --secret keys/ta.key</pre></div></div>

<p><strong>Generazione dei certificati per i client</strong></p>
<p>La generazione del certificato per il client è letteralmente identica alla generazione di un certificato per il server.<br />
Personalmente preferisco generare dei certificati nominali:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># ./build-key fpedrini</pre></div></div>

<p>e seguirà una procedura identica a quella della generazione del certificato per il server.</p>
<p><strong>Configurazione del server</strong></p>
<p>Passiamo ora configurazione vera e propria del demone di OpenVPN.<br />
Anche in questo caso il pacchetto debian ci viene in aiuto con un file di configurazione già precotto e adatto ai nostri scopi, dobbiamo solo aggiustare qualche piccolo parametro.</p>
<p>Innanzitutto è necessario copiare il file di esempio nella directory giusta:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
# cd /etc/openvpn
# gunzip server.conf.gz</pre></div></div>

<p>Ora siamo pronti a modificare la configurazione, per brevità citerò solo le direttive che andremo a toccare:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">local 192.168.0.1
port 1194
proto udp</pre></div></div>

<p>Queste direttiva indicano ad OpenVPN rispettivamente:</p>
<ul>
<li>Su quale indirizzo ip locale mettersi in attesa di connessioni, se omessa il demone userà tutte le interfacce</li>
<li>Su quale porta ascoltare, la 1194 è il default</li>
<li>Che tipo di protocollo utilizzare per il tunnel, le possibilità sono &#8216;TCP&#8217; e &#8216;UDP&#8217;, vedremo più avanti le differenze</li>
</ul>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">dev tun</pre></div></div>

<p>Indica a OpenVPN di creare un tunnel al layer 3 del livello OSI, utilizzando &#8216;tap&#8217; invece, andremmo a creare un bridge di rete a livello 2.</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">ca easy-rsa/keys/ca.crt
cert easy-rsa/keys/Gateway.crt
key easy-rsa/keys/Gateway.key  # This file should be kept secret
dh easy-rsa/keys/dh2048.pem</pre></div></div>

<p>Queste direttive invece indicano al demone dove andare a prendere i file relativi alla Certification Authority, al certificato del server e il file <em>Diffie-Hellman</em>.</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push &quot;route 192.168.1.0 255.255.255.0&quot;</pre></div></div>

<p>Questi parametri stabiliscono:</p>
<ul>
<li>la subnet e la maschera della rete della VPN, il server prenderà automaticamente il primo indirizzo</li>
<li>il file in cui salvare la lista degli ip assegnati dal dhcp interno di OpenVPN</li>
<li>la rotta che il server deve comunicare al client per fare in modo che possano raggiungere la rete dietro alla VPN.</li>
</ul>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">;push &quot;redirect-gateway def1 bypass-dhcp&quot;</pre></div></div>

<p>Questa riga fa in modo che tutto il traffico generato dai client passi attraverso la VPN. Non sempre è consigliabile attivare questa opzione, poichè causa un notevole rallentamento nella connessione dei client dal momento che i pacchetti del traffico &#8220;normale&#8221; dovranno transitare sulla VPN prima di poter uscire su internet.<br />
Nella mia configurazione è stata lasciata commentata.</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">push &quot;dhcp-option DNS 192.168.1.1&quot;
push &quot;dhcp-option DNS 208.67.220.220&quot;
push &quot;dhcp-option WINS 192.168.1.3&quot;</pre></div></div>

<p>Le prime tre righe permettono di forzare i server DNS e i server WINS tramite il DHCP interno di OpenVPN, mentre l&#8217;ultima permette ai client di comunicare tra di loro.</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">keepalive 10 120</pre></div></div>

<p>Il keepalive di OpenVPN permette di tenere vive le sessioni che passano attraverso i firewall, il primo parametro stabilisce ogni quanti secondi mandare un messaggio verso il client (è qualcosa di simile ad un ping ICMP), il secondo invece stabilisce il periodo massimo di inattività di una connessione.</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">tls-auth keys/ta.key 0</pre></div></div>

<p>È il file necessario per la creazione della connessione cifrata, il secondo parametro settato a 0 indica che la chiave sta venendo usata dal server, mentre sui client sarà impostato a 1.</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">log-append  /var/log/openvpn/openvpn.log
verb 3</pre></div></div>

<p>E per concludere i parametri dedicati al logging, che sono abbastanza auto esplicativi. Il livello di verbosità può variare da 1 a 20.</p>
<p>Per testare rapidamente la configurazione è sufficiente lanciare direttamente OpenVPN (assicurandosi prima di aver fermato il demone lanciato dall&#8217;init script durante l&#8217;installazione):</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># invoke-rc.d openvpn stop
Stopping virtual private network daemon: server.
# openvpn server.conf</pre></div></div>

<p>Se non ricevete nessun errore allora la vostra configurazione è corretta, potete interrompere l&#8217;esecuzione con Ctrl+C.</p>
<p>Come ultima cosa è necessario configurare il file <em>/etc/default/openvpn</em> per permettere l&#8217;avvio automatico del demone in fase di boot:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">...
...
AUTOSTART=&quot;server&quot;
...
...</pre></div></div>

<p>La riga fondamentale è <em>AUTOSTART=&#8221;server&#8221;</em>, che permette all&#8217;initscript di far partire il demone usando la configurazione &#8220;server&#8221;, quella da noi creata.</p>
<p><strong>Configurazione di IPTables</strong></p>
<p>Per consentire ai pacchetti che viaggiano sulla vpn di passare sulla rete vera è necessario abilitare il forwarding tramite iptables, con due semplici regolette:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">iptables -A INPUT -i tun0 -j ACCEPT
iptables -A FORWARD -i tun0 -j ACCEPT</pre></div></div>

<p>e ovviamente attivare il forward con</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">sysctl -w net.ipv4.ip_forward=1</pre></div></div>

<p><strong>Configurazione dei client</strong></p>
<p>La configurazione dei client è abbastanza rapida, innanzitutto vediamo cosa serve per un client:</p>
<ul>
<li>La coppia certificato/chiave per il client (i due file .key e .crt)</li>
<li>Il certificato della CA del server (il file ca.crt)</li>
<li>La chiave di autenticazione TLS (il file ta.key)</li>
<li>Il file di configurazione per il client.</li>
</ul>
<p>I primi tre pezzettini li possiamo recuperare tranquillamente dal server, li abbiamo generati nei passi precedenti, vediamo ora la struttura del file di configurazione:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">client</pre></div></div>

<p>Specifica che si tratta appunto di un client <img src='http://www.miamammausalinux.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">dev tun
proto udp</pre></div></div>

<p>queste righe specificano rispettivamente che stiamo creando una connessione a livello IP e che ci vogliamo connettere usando un tunnel UDP,<br />
Ovviamente questi dati devono coincidere con le impostazioni lato server</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">remote mightyvpn.vostraazienda.it 1194</pre></div></div>

<p>l&#8217;hostname e la porta a quale connettersi, anche in questo caso la porta deve coincidere con quella specificata nella configurazione del server.<br />
È possibile specificare più server remoti, nel caso in cui uno di essi sia inattivo, OpenVPN passerà al successivo.</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">resolv-retry infinite
nobind
user nobody
group nogroup
persist-key
persist-tun</pre></div></div>

<p>Queste direttive stabiliscono che:</p>
<ul>
<li>Il client OpenVPN dovrà tentare all&#8217;infinito di risolvere il nome del server (ovviamente è utile solo se come remote server si specifica un nome e non un indirizzo IP)</li>
<li>Il client non deve fare &#8216;bind&#8217; su una porta specifica</li>
<li>Il client deve fare &#8220;privilege dropping&#8221; dopo l&#8217;inizializzazione (inutile su sistemi windows)</li>
<li>Il client deve tentare di rendere persistenti il tunnel</li>
</ul>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">ca ca.crt
cert fpedrini.crt
key fpedrini.key
ns-cert-type server
tls-auth ta.key 1</pre></div></div>

<p>Ed infine questi sono i parametri relativi ai certificati. Come potete vedere la configurazione è identica al lato server, con l&#8217;eccezione della riga &#8216;tls-auth&#8217;, che finisce per &#8220;1&#8243;.</p>
<p>Una volta salvato il file di configurazione come &#8216;/etc/openvpn/client.conf&#8217; e affiancato da tutti i vari file a corredo è possibile avviare la connessione ad OpenVPN.</p>
<p>Analogamente a quanto fatto per il server, è possibile fare in modo che il proprio pc avvii la connessione all&#8217;avvio del demone OpenVPN modificando opportunamente il file /etc/default/openvpn:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">...
...
AUTOSTART=&quot;client&quot;
...
...</pre></div></div>

<p><strong>Conclusioni</strong></p>
<p>Il test principale di funzionamento è quanto di più banale possa esserci: vedere cioè se dai client che si connettono alla rete si riesce ad accedere a computer presenti nella sotto rete, controllando servizi che si conosce come attivi o attraverso banali <em>ping</em>.<br />
In pochi passi un&#8217;intera infrastruttura può essere accessibile ovunque, grazie ad OpenVPN!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.miamammausalinux.org/2010/05/openvpn-connessione-sicura-attraverso-internet-di-molti-client-ad-un-server/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Un calendario personale con Apache</title>
		<link>http://www.miamammausalinux.org/2009/10/un-calendario-personale-con-apache/</link>
		<comments>http://www.miamammausalinux.org/2009/10/un-calendario-personale-con-apache/#comments</comments>
		<pubDate>Mon, 05 Oct 2009 13:50:19 +0000</pubDate>
		<dc:creator>Marco Bonetti</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Calendario]]></category>
		<category><![CDATA[Calendario personale]]></category>

		<guid isPermaLink="false">http://www.miamammausalinux.org/?p=835</guid>
		<description><![CDATA[Avete mai desiderato un comodo calendario personale sempre online da usare quando e come volete senza bisogno di far sapere ai vari google di turno cosa dovete fare il giovedì pomeriggio? La soluzione è piuttosto semplice e alla portata di chiunque abbia un server apache2 a disposizione. Installazione, configurazione ed utilizzo Ma andiamo con ordine! [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.miamammausalinux.org/wp-content/uploads/2009/10/CalendarServer.png" alt="Calendar Server" /><br />
Avete mai desiderato un comodo calendario personale sempre online da usare quando e come volete senza bisogno di far sapere ai vari google di turno cosa dovete fare il giovedì pomeriggio? <img src='http://www.miamammausalinux.org/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /><br />
La soluzione è piuttosto semplice e alla portata di chiunque abbia un server apache2 a disposizione.</p>
<p><strong>Installazione, configurazione ed utilizzo</strong></p>
<p>Ma andiamo con ordine! Se non avete già installato questo web server, fatelo ora, usando il metodo più appropriato per la vostra distribuzione linux preferita. A questo punto dovete editare il file di configurazione di default che può essere apache2.conf oppure httpd.conf e assicurarsi che siano abilitati seguenti moduli:</p>
<ul>
<li>mod_authn_file</li>
<li>mod_authz_user</li>
<li>mod_auth_basic</li>
<li>mod_auth_digest</li>
<li>mod_dav_fs</li>
</ul>
<p>I primi moduli sono necessari per regolare l&#8217;accesso alle risorse di apache, l&#8217;ultimo è quello che gestirà tutto il calendario.<br />
Bene, ora modificate la configurazione del modulo dav_fs inserendo le segenti voci:</p>

<div class="wp_syntax"><div class="code"><pre class="apache" style="font-family:monospace;"><span style="color: #00007f;">DavLockDB</span> <span style="color: #7f007f;">&quot;/usr/var/DavLock&quot;</span>
&lt;<span style="color: #000000; font-weight:bold;">Directory</span> <span style="color: #7f007f;">&quot;/srv/httpd/htdocs/calendars&quot;</span>&gt;
    <span style="color: #00007f;">Dav</span> <span style="color: #0000ff;">On</span>
&nbsp;
    <span style="color: #00007f;">Order</span> <span style="color: #00007f;">Allow</span>,<span style="color: #00007f;">Deny</span>
    <span style="color: #00007f;">Allow</span> from <span style="color: #0000ff;">all</span>
&nbsp;
    <span style="color: #00007f;">AuthType</span> Digest
    <span style="color: #00007f;">AuthName</span> calendars
&nbsp;
    <span style="color: #00007f;">AuthUserFile</span> <span style="color: #7f007f;">&quot;/usr/user.passwd&quot;</span>
    <span style="color: #00007f;">AuthDigestProvider</span> file
&nbsp;
    &lt;<span style="color: #000000; font-weight:bold;">LimitExcept</span> OPTIONS&gt;
        <span style="color: #00007f;">require</span> <span style="color: #00007f;">user</span> nomeutente
    &lt;/<span style="color: #000000; font-weight:bold;">LimitExcept</span>&gt;
&lt;/<span style="color: #000000; font-weight:bold;">Directory</span>&gt;</pre></div></div>

<p>La creazione del file <em>/usr/user.passwd</em> si effettua attraverso il seguente, semplice comando:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">$ htdigest -c &quot;/usr/user.passwd&quot; calendars nomeutente</pre></div></div>

<p>Ovviamente per le direttive siete liberissimi di scegliere i percorsi che più vi aggradano.<br />
Vediamo cosa vogliono dire le varie opzioni:</p>
<ul>
<li><em>DavLockDB</em> serve per specificare quale file apache userà come file di lock per impedire rovinose scritture simultanee sui file gestiti via dav_fs</li>
<li><em>Dav On</em> usato all&#8217;interno di un tag Directory abilita la gestione di quella cartella tramite il modulo dav_fs</li>
<li>Seguono le direttive standard per gestire l&#8217;autenticazione degli utenti tramite file di password</li>
<li>Infine con la direttiva <em>LimitExcept</em> si definisce il livello di accesso alle risorse</li>
</ul>
<p>Questa ultima direttiva è decisamente importante: il modulo dav_fs permette di eseguire degli upload di file sul proprio web server e sicuramente non vogliamo che tale comportamento sia aperto e disponibile a qualsiasi utente di internet!<br />
Così come è scritta, la direttiva richiede un accesso autenticato sia per la modifica dei calendari che per la loro lettura, se volessimo rilassare i permessi, possiamo usare <em>LimitExcept GET OPTIONS</em>: in questo modo è possibile a utenti non autenticati di visionare i file salvati in /calendars ma, francamente, sconsiglio di eseguire questo tipo di rilassamento.<br />
Bene, il server è pronto! Aprite la vostra applicazione di calendaring preferita, potete create un nuovo calendario all&#8217;indirizzo <em>http://server/calendars/calendario.ics</em> e usarlo per la gestione dei vostri appuntamenti.</p>
<p><strong>Possibili miglioramenti</strong></p>
<p>Prima di concludere, lascio qualche considerazione per possibili migliorie:</p>
<ul>
<li>L&#8217;acesso protetto da password serve per controllare chi può accedere alle risorse e chi no, ma senza un adeguato supporto crittografigo risulta quasi inutile: vi consiglio di combinare questa configurazione con il supporto di apache per https o di modificare la regola <em>Allow from</em> per restringere l&#8217;accesso alle risorse solo da connessioni sicure come tunnel ssh o vpn</li>
<li>L&#8217;architettura presentata è pensata per un calendar server casalingo, tuttavia scala bene se vogliamo tenere directory separate tra più utenti: basta replicare il blocco di direttive <em>Directory</em> per ogni utenza che si vuole aggiungere adattandola, ovviamente, al nuovo username. I problemi nascono quando si vogliono condividere i calendari in sola lettura:
<ul>
<li>Una prima soluzione, semplice, consiste nel mettersi d&#8217;accordo sull&#8217;accesso alle risorse: gli stessi client permettono di scegliere se impotare i calendari in sola lettura o meno.</li>
<li>Una seconda soluzione, più complessa, prevede l&#8217;utilizzo di più direttive <em>Limit</em> al posto di una <em>LimitExcept</em>, in questo modo potremmo usare, per esempio, <em>Limit GET OPTIONS</em> su <em>valid_users</em> per permettere la sola lettura agli utenti autenticati e <em>Limit PUT</em> al proprietario del calendario per permettere solo a lui la modifica dei contenuti. Tale strada, però, può essere potenzialmente pericolosa in caso di utilizzo di metodi http sconosciuti, per maggiori informazioni vi rimando alla <a href="http://httpd.apache.org/docs/2.2/mod/core.html#limit">documentazione ufficiale delle due direttive</a></li>
</ul>
</li>
<li>In questo articolo abbiamo usato il modulo dav_fs solo per gestire un file .ics ma in realtà abbiamo configurato un vero e proprio storage personale sul vostro server apache: potete prendere un qualsiasi client dav e caricare file sotto la cartella /calendars</li>
</ul>
<p><strong>Conclusioni</strong></p>
<p>Questo è tutto! Come avete potuto notare la creazione di un server per un calendario remoto personale non è poi tanto difficile, per quanto riguarda invece gli ambienti enterprise questa soluzione potrebbe essere un po troppo stretta ma in questo caso si possono applicare le altre idee proposte oppure sposarsi su programmi dedicati come la suite <a href="http://www.zimbra.com/">Zimbra</a> oppure il <a href="http://trac.calendarserver.org/">Calendar Server</a> di Apple.</p>
<p>Alla prossima!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.miamammausalinux.org/2009/10/un-calendario-personale-con-apache/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Creare un&#8217;immagine di un disco USB&#8230; senza disco USB.</title>
		<link>http://www.miamammausalinux.org/2009/09/creare-unimmagine-di-un-disco-usb-senza-disco-usb/</link>
		<comments>http://www.miamammausalinux.org/2009/09/creare-unimmagine-di-un-disco-usb-senza-disco-usb/#comments</comments>
		<pubDate>Wed, 23 Sep 2009 09:27:18 +0000</pubDate>
		<dc:creator>Matteo Cappadonna</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Immagine disco]]></category>
		<category><![CDATA[Mount]]></category>
		<category><![CDATA[Sistema]]></category>
		<category><![CDATA[Usb]]></category>

		<guid isPermaLink="false">http://www.miamammausalinux.org/?p=804</guid>
		<description><![CDATA[Eccoci ancora qui con un altro tutorial semplice semplice ma, in alcuni casi, molto utile. Il problema di oggi è stato il seguente: devo montare su una lama HP l&#8217;immagine di un disco USB per poter caricare dei file su un sistema &#8220;live&#8221; (quindi con lettore cd occupato) senza dover configurare la rete (e quindi, [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.miamammausalinux.org/wp-content/uploads/2009/01/linux.png" alt="linux" title="linux" width="85" height="100" class="alignnone size-full wp-image-292" /></p>
<p>Eccoci ancora qui con un altro tutorial semplice semplice ma, in alcuni casi, molto utile.</p>
<p>Il problema di oggi è stato il seguente: devo montare su una lama HP l&#8217;immagine di un disco USB per poter caricare dei file su un sistema &#8220;live&#8221; (quindi con lettore cd occupato) senza dover configurare la rete (e quindi, far riconfigurare la porta degli switch).</p>
<p>Le soluzioni sono 2:<br />
1) Prendere una chiavetta USB, caricare i file, fare un&#8217;immagine e collegarla<br />
2) Creare direttamente da sistema l&#8217;immagine di una chiavetta USB, caricare i file, e collegarla.</p>
<p>Dato che la prima soluzione prevede comunque di avere una chiavetta di dimensione &#8220;trasportabile&#8221; via rete (personalmente ho un pendrive da 16GB: per due file da 2mb l&#8217;uno, farmi un&#8217;immagine da 16GB e spostarla via rete è assurdo), la seconda è molto più malleabile in termine di dimensioni dell&#8217;immagine che si andrà a creare.</p>
<p>Ma, andiamo a cominciare: per prima cosa ci interessa creare un file (che altro non sarà che l&#8217;immagine della nostra chiavetta) di una dimensione particolare; nel mio caso, 10mb sono più che sufficienti.<br />
Mano al buon, vecchio <strong>dd</strong> e dunque:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">$ dd if=/dev/zero of=usbDisk.img bs=1024 count=10000</pre></div></div>

<p>Quindi, partendo dal device &#8220;zero&#8221; (contenente, ovviamente, solo 0) creo un file &#8220;usbDisk.img&#8221; di dimensione 1024byte x 10000 = 1kb x 10000 = 10mb</p>
<p>Terminata la creazione, scatta la magia: andiamo a collegare questo file ad un device facendolo, in effetti, vedere al sistema come un dispositivo fisicamente collegato alla macchina:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">$ losetup -f usbDisk.img</pre></div></div>

<p>Questo comando prende il file usbDisk.img e lo collega al device /dev/loop0</p>
<p>Ora, come ogni disco che si rispetti, andiamo a crearci sopra una partizione; armiamoci di cfdisk (molto semplice, i puristi preferiranno fdisk, ma fate voi) e creiamo una singola partizione di tipo &#8220;Linux&#8221; sul disco:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">$ cfdisk /dev/loop0</pre></div></div>

<p>Salviamo ed usciamo.<br />
In realtà quello che ci serve non è la partizione, bensì il fatto che cfdisk, in fase di scrittura, determina e scrive direttamente sul device informazioni come i cilindri, ecc. che servono successivamente per creare il filesystem.</p>
<p>Quindi, visto che vogliamo simulare un disco usb &#8220;standard&#8221;, andiamo a metterci sopra un filesystem che sia comune, e cosa meglio del vecchio fat32 per questo?</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">$ mkdosfs -F 32 /dev/loop0</pre></div></div>

<p>Terminata la creazione possiamo montare il disco usb come un normalissimo device:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">$ mkdir -p /mnt/fintoDisco
$ mount /dev/loop0 /mnt/fintoDisco</pre></div></div>

<p>e copiarci sopra i file interessati.</p>
<p>Quando abbiamo finito ricordiamoci di smontare il device:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">$ umount /mnt/fintoDisco</pre></div></div>

<p>e, soprattutto, di sganciare il device dal file reale:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">$ losetup -d /dev/loop0</pre></div></div>

<p>Ora possiamo portarci in giro il file come più ci aggrada.</p>
<p>Buon divertimento e buon lavoro</p>
]]></content:encoded>
			<wfw:commentRss>http://www.miamammausalinux.org/2009/09/creare-unimmagine-di-un-disco-usb-senza-disco-usb/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Nagios: notifiche SMS con la pendrive Onda MT503HS (e parenti prossime)</title>
		<link>http://www.miamammausalinux.org/2009/07/nagios-notifiche-sms-con-la-pendrive-onda-mt503hs-e-parenti-prossime/</link>
		<comments>http://www.miamammausalinux.org/2009/07/nagios-notifiche-sms-con-la-pendrive-onda-mt503hs-e-parenti-prossime/#comments</comments>
		<pubDate>Thu, 16 Jul 2009 15:39:49 +0000</pubDate>
		<dc:creator>Raoul Scarazzini</dc:creator>
				<category><![CDATA[Nagios]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[monitoring]]></category>
		<category><![CDATA[SMS]]></category>

		<guid isPermaLink="false">http://www.miamammausalinux.org/?p=732</guid>
		<description><![CDATA[Il problema è noto: lo strumento per il controllo di risorse e servizi Nagios viene in genere predisposto per inviare le notifiche attraverso messaggi di posta elettronica, ma cosa succede se l&#8217;anomalia riguarda proprio l&#8217;invio delle mail di notifica? Sul precedente articolo di Mia Mamma Usa Linux &#8220;Un Nagios parlante con Festival&#8221; è stata presentata [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.miamammausalinux.org/wp-content/uploads/2009/01/nagios.png" alt="nagios" title="nagios" width="100" class="alignnone size-full wp-image-174" /><img src="http://www.miamammausalinux.org/wp-content/uploads/2009/06/onda-mt503hs.png" alt="Onda MT503HS" title="onda-mt503hs" width="100" height="77" class="size-full wp-image-733" /></p>
<p>Il problema è noto: lo strumento per il controllo di risorse e servizi Nagios viene in genere predisposto per inviare le notifiche attraverso messaggi di posta elettronica, ma cosa succede se l&#8217;anomalia riguarda proprio l&#8217;invio delle mail di notifica? Sul precedente articolo di Mia Mamma Usa Linux &#8220;<a href="http://www.miamammausalinux.org/2009/02/un-nagios-parlante-con-festival/">Un Nagios parlante con Festival</a>&#8221; è stata presentata una soluzione per fare in modo che un computer segnali i malfunzionamenti attraverso un sintetizzatore vocale e delle casse audio, ma se non si ha la disponibilità di un impianto audio o più semplicemente se la macchina che effettua i controlla risiede in una locazione diversa da quella in cui ci si trova (tipicamente un centro elaborazione dati) come ci si deve comportare?<br />
Una soluzione percorribile è quella di utilizzare le notifiche SMS, che unite alle notifiche standard danno un&#8217;approssimativa certezza di ricevere da almeno una fonte la segnalazione di un guasto.<br />
Quanto verrà presentato in questo articolo è nello specifico una soluzione che prevede l&#8217;integrazione di Nagios con la chiavetta modello <em>ONDA MT503HS</em> e più in generale una soluzione applicabile a tutte le chiavette USB attualmente sul mercato.</p>
<p><strong>Cenni sul dispositivo</strong></p>
<p>Ogni operatore di telefonia mobile possiede un&#8217;offerta che prevede una chiavetta USB funzionante come modem che permette la connessione <em>GPRS/EDGE/UMTS/HSDPA</em> all&#8217;operatore stesso e la conseguente navigazione in internet.<br />
Questi tipi di <em>pendrive</em> generalmente hanno una peculiarità interessante, vengono definiti &#8220;<em>flip-flop</em>&#8220;, possono cioè essere usati in due modi: come dispositivo di archiviazione di massa (possiedono infatti uno slot per micro-sd) o come modem. A deciderne l&#8217;impiego è generalmente l&#8217;utente che una volta inserita la chiavetta si trova di fronte alla scelta attraverso un menu, quantomeno sui sistemi operativi Microsoft Windows, in quanto il driver viene letto ed installato partendo dai dati che si trovano sulla memoria flash del dispositivo.<br />
Il motivo che rende questo dispositivo ideale per la realizzazione del progetto di notifiche SMS è che una volta posta la chiavetta in stato &#8220;modem&#8221;, questa risulta interrogabile con i comuni comandi AT, . Questa funzionalità permette quindi di utilizzare il modem per l&#8217;invio di SMS. Un altro indubbio vantaggio è quello dell&#8217;alimentazione: il dispositivo riceve l&#8217;energia necessaria attraverso i 5 volt della presa USB e non richiede pertanto un trasformatore.<br />
Inoltre sebbene ogni chiavetta sia venduta da uno specifico operatore supporta SIM di qualsiasi tipo, pertanto se la pendrive è venduta dall&#8217;operatore <em>Tim</em>, è possibile comunque utilizzarla con una SIM dell&#8217;operatore <em>Vodafone</em>, e così via.<br />
Tirando le somme si capisce come un computer con collegata una pendrive di questo tipo possa facilmente diventare un <em><a href="http://en.wikipedia.org/wiki/SMS_gateways">gateway sms</a></em>, proprio quello che serve per realizzare il progetto descritto.<br />
Il motivo per cui la pendrive scelta è il modello <em>Onda MT503HS</em> è puramente casuale, come si dice in questi casi era &#8220;<em>quello che passava il convento</em>&#8220;.</p>
<p><strong>Requisiti preliminari ed essenziali</strong></p>
<p>Prima di fare qualsiasi cosa, l&#8217;esperienza suggerisce di recarsi nel luogo dove dovrà risiedere la macchina su cui verrà installato Nagios, inserire la SIM che si vorrà usare per le notifiche in un telefonino e controllare quanto segnale c&#8217;è a disposizione. Una pendrive usb generalmente prende come un comune cellulare, nello stesso posto se quindi il cellulare ha campo, lo avrà anche la chiavetta.<br />
L&#8217;esperienza inoltre insegna che si può costruire il miglior software per le notifiche possibile, testarlo in ogni modo ed orgogliosamente portarlo nel luogo dove risiederà convinti del corretto funzionamento per finire a tutta velocità contro il muro rappresentato dell&#8217;assenza di campo.<br />
A seconda del luogo quindi è meglio capire quale sia il miglior operatore della zona, in modo da non incorrere in cocenti delusioni.</p>
<p><strong>Configurazione della pendrive</strong></p>
<p>La pendrive <em>Onda MT503HS</em> è venduta come compatibile con tutti i maggiori sistemi operativi: Windows, Linux e Mac OSx. Nella confezione è presente un CD contenente i driver di ogni sistema e se si usa Linux, almeno nel caso di Debian, questi driver non funzionano. Il pacchetto di installazione prevede la compilazione dei sorgenti del modulo relativo al dispositivo, ma l&#8217;esito delle operazioni di compilazione è sempre negativo.<br />
Fortunatamente però Linux consente di ovviare al problema con i driver nativi e l&#8217;utilizzo di un programma, denominato <em><a href="http://www.draisberghof.de/usb_modeswitch/">usb_modeswitch</a></em> che permette di forzare la scelta dell&#8217;impiego del dispositivo.<br />
La procedura di installazione descritta è relativa a <em>Debian Lenny</em>, ma come sempre ci si può riferire al sito del progetto per recuperare i sorgenti o capire dove reperire i pacchetti binari per le più diffuse distribuzioni.<br />
Il pacchetto è installabile attraverso <em>apt-get</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">$ apt-get install usb-modeswitch</pre></div></div>

<p>oltre all&#8217;eseguibile <em>/usr/sbin/usb_modeswitch</em> i file necessari al corretto funzionamento del meccanismo di switch della periferica sono due:</p>
<p><em>/etc/usb_modeswitch.conf</em></p>
<p>Al cui interno vanno abilitate le righe relative al modello della pendrive. Cercando la parola chiave &#8220;ONDA MT503HS&#8221;, si trova la sezione in cui abilitare le righe rimuovendo i caratteri &#8220;;&#8221; iniziali:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">########################################################
# ONDA MT503HS (most likely a ZTE model)
#
# Contributor: Lucio Asnaghi a.k.a. kRAkEn/gORe
&nbsp;
DefaultVendor=  0x19d2
DefaultProduct= 0x2000
&nbsp;
TargetVendor=   0x19d2
TargetProduct=  0x0002
&nbsp;
MessageEndpoint=0x08
MessageContent=&quot;55534243b0c8dc812000000080000a85010101180101010101000000000000&quot;
########################################################</pre></div></div>

<p><em>/etc/udev/rules.d/usb_modeswitch.rules</em></p>
<p>Analogamente cercando la stringa relativa al modello &#8220;ONDA MT503HS&#8221;, va abilitata la regola udev che associa l&#8217;esecuzione del comando usb_modeswitch all&#8217;inserimento della periferica:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">########################################################
# ONDA MT503HS (most likely a ZTE model)
#
# Contributor: Lucio Asnaghi a.k.a. kRAkEn/gORe
# Vendor:Product id = 0x19d2:0x2000
SUBSYSTEM==&quot;usb&quot;, SYSFS{idVendor}==&quot;19d2&quot;, SYSFS{idProduct}==&quot;2000&quot;, RUN+=&quot;/usr/sbin/usb_modeswitch --DefaultVendor 0x19d2 --DefaultProduct 0x2000 --MessageEndpoint 0x08 --MessageContent 55534243b0c8dc812000000080000a85010101180101010101000000000000&quot;
&nbsp;
########################################################</pre></div></div>

<p>E&#8217; palese che a seconda del modello di pendrive in possesso corrisponderà un&#8217;abilitazione diversa all&#8217;interno dei suddetti file.<br />
Terminate le modifiche è possibile inserire la pendrive nella porta USB, monitorando quanto viene scritto dal sistema all&#8217;interno del file <em>/var/log/messages</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">Jun 12 09:11:35 nagios kernel: [   21.897954] usb 1-1: configuration #1 chosen from 1 choice
Jun 12 09:11:35 nagios kernel: [   21.901706] scsi1 : SCSI emulation for USB Mass Storage devices
Jun 12 09:11:35 nagios kernel: [   21.913128] usb 1-1: New USB device found, idVendor=19d2, idProduct=0002
Jun 12 09:11:35 nagios kernel: [   21.913139] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Jun 12 09:11:35 nagios kernel: [   21.913148] usb 1-1: Product: ONDA CDMA Technologies MSM
Jun 12 09:11:35 nagios kernel: [   21.913154] usb 1-1: Manufacturer: Qualcomm, Incorporated
Jun 12 09:11:35 nagios kernel: [   21.913161] usb 1-1: SerialNumber: Data Interface
Jun 12 09:11:35 nagios kernel: [   23.110641] usbcore: registered new interface driver usbserial
Jun 12 09:11:35 nagios kernel: [   23.110682] usbserial: USB Serial support registered for generic
Jun 12 09:11:35 nagios kernel: [   23.110789] usbcore: registered new interface driver usbserial_generic
Jun 12 09:11:35 nagios kernel: [   23.110796] usbserial: USB Serial Driver core
Jun 12 09:11:35 nagios kernel: [   23.133222] usbserial: USB Serial support registered for GSM modem (1-port)
Jun 12 09:11:35 nagios kernel: [   23.133291] option 1-1:1.1: GSM modem (1-port) converter detected
Jun 12 09:11:35 nagios kernel: [   23.133459] usb 1-1: GSM modem (1-port) converter now attached to ttyUSB0
Jun 12 09:11:35 nagios kernel: [   23.133496] option 1-1:1.2: GSM modem (1-port) converter detected
Jun 12 09:11:35 nagios kernel: [   23.133578] usb 1-1: GSM modem (1-port) converter now attached to ttyUSB1
Jun 12 09:11:35 nagios kernel: [   23.133611] option 1-1:1.3: GSM modem (1-port) converter detected
Jun 12 09:11:35 nagios kernel: [   23.133689] usb 1-1: GSM modem (1-port) converter now attached to ttyUSB2
Jun 12 09:11:35 nagios kernel: [   23.133721] option 1-1:1.4: GSM modem (1-port) converter detected
Jun 12 09:11:35 nagios kernel: [   23.133809] usb 1-1: GSM modem (1-port) converter now attached to ttyUSB3
Jun 12 09:11:35 nagios kernel: [   23.133841] option 1-1:1.5: GSM modem (1-port) converter detected
Jun 12 09:11:35 nagios kernel: [   23.133923] usb 1-1: GSM modem (1-port) converter now attached to ttyUSB4
Jun 12 09:11:35 nagios kernel: [   23.133950] usbcore: registered new interface driver option
Jun 12 09:11:35 nagios kernel: [   23.133957] option: USB Driver for GSM modems: v0.7.2</pre></div></div>

<p>Dapprima il dispositivo viene riconosciuto come una periferica di archiviazione di massa e subito dopo subentra la regola <em>udev</em> che lo converte in una periferica ad accesso seriale utilizzando il modulo <em>usbserial</em> e creando i <em>device ttyUSB</em> tutti di tipo <em>GSM Modem</em>.<br />
Il dispositivo di riferimento da utilizzare sarà <em>ttyUSB1</em>.</p>
<p><strong>Spedire SMS dalla linea di comando</strong></p>
<p>Tra i vari pacchetti disponibili per la gestione degli SMS in Linux, <em>gsm-utils</em> consente di gestire attraverso la linea di comando quanto necessario per l&#8217;invio di SMS. Il pacchetto è disponibile nelle maggiori distribuzioni. L&#8217;installazione su sistemi Debian è la consueta:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">$ apt-get install gsm-utils</pre></div></div>

<p>Il comando che permette l&#8217;invio dei messaggi di testo è <em>gsmsendsms</em> ed ha la seguente sintassi:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">/usr/bin/gsmsendsms -C &lt;numero del centro messaggi&gt; -d /dev/ttyUSB1 &lt;numero di cellulare&gt; &quot;&lt;messaggio di testo&gt;&quot;</pre></div></div>

<p>I parametri da specificare, come è intuibile, sono il numero del centro messaggi, che varia da operatore ad operatore (ed è rintracciabile generalmente con una semplice ricerca in google), il device da utilizzare, che come precedentemente illustrato è <em>/dev/ttyUSB1</em>, il numero del cellulare di destinazione preceduto sempre dal prefisso internazionale (quindi per l&#8217;Italia +39) ed infine il testo da inviare.<br />
Provando a lanciare il comando in questione l&#8217;output potrebbe essere il seguente:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">/usr/bin/gsmsendsms[ERROR]: unexpected response '+ZUSIMR:2' when sending 'AT+CMGS=18'</pre></div></div>

<p>Sebbene questo appaia a tutti gli effetti come un errore, l&#8217;SMS arriva comunque a destinazione. </p>
<p><strong><em>Nello specifico&#8230;</em></strong></p>
<p>Per eliminare questo inconveniente (che a tutti gli effetti è qualcosa di unicamente estetico) è necessario utilizzare il programma <a href="http://en.wikipedia.org/wiki/Minicom"><em>minicom</em></a> e configurarlo per accedere al device /dev/ttyUSB1 alla velocità di 9600 <a href="http://it.wikipedia.org/wiki/Baud">baud</a>.<br />
Una rapida occhiata mostrerà infatti come la pendrive scriva costantemente il codice <em>+ZUSIMR:2</em>, confondendo il programma che si aspetta un &#8220;OK&#8221; come responso al comando AT inviato al dispositivo.<br />
Il problema è risolvibile immettendo la seguente stringa:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">AT+CPMS=&quot;SM&quot;,&quot;ME&quot;,&quot;MT&quot;</pre></div></div>

<p>attraverso minicom. Subito dopo l&#8217;immissione del comando la sequenza interminabile di <em>+ZUSIMR:2</em> terminerà.<br />
La stringa di comando AT passata al dispositivo seleziona dove verranno memorizzati i messaggi SMS in arrivo. L&#8217;ordine indicato è SM (SIM card), ME (dispositivo) e (altra area del dispositivo).</p>
<p><strong>Configurare Nagios</strong></p>
<p>Per concludere il progetto con successo non rimane altro da fare con configurare Nagios in modo che supporti le notifiche via SMS.<br />
Nel file <em>commands.cfg</em> dela directory <em>/etc/nagios3</em> andranno quindi definiti i nuovi tipi di modifica attraverso l&#8217;SMS in questa forma:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># 'notify-host-by-sms' command definition
define command{
	command_name	notify-host-by-sms
	command_line	/usr/bin/gsmsendsms -C &lt;numerocentromessaggi&gt; -d /dev/ttyUSB1 $CONTACTPAGER$ &quot;Nagios - $NOTIFICATIONTYPE$ - Host $HOSTNAME$ is in state $HOSTSTATE$ - Date/Time: $LONGDATETIME$&quot;
	}
&nbsp;
# 'notify-service-by-sms' command definition
define command{
	command_name	notify-service-by-sms
	command_line	/usr/bin/gsmsendsms -C &lt;numerocentromessaggi&gt; -d /dev/ttyUSB1 $CONTACTPAGER$ &quot;Nagios - $NOTIFICATIONTYPE$ - Service $SERVICEDESC$ (Host $HOSTALIAS$) is in state $SERVICESTATE$ - Date/Time: $LONGDATETIME$&quot;
	}</pre></div></div>

<p>infine, per ogni contatto definito all&#8217;interno della configurazione di Nagios (generalmente nel file contacts.cfg) andranno inserite le nuove notifiche create:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">define contact{
        contact_name                    &lt;nome contatto&gt;
        alias                           &lt;alias contatto&gt;
        service_notification_period     24x7
        host_notification_period        24x7
        service_notification_options    u,c,r
        host_notification_options       d,r
        service_notification_commands   notify-service-by-email,notify-service-by-sms
        host_notification_commands      notify-host-by-email,notify-host-by-sms
        email                           &lt;email contatto&gt;
        pager                           &lt;numero di telefono&gt;
	}</pre></div></div>

<p>Riavviato il servizio, le notifiche via SMS per il contatto arriveranno al numero indicato nel campo <em>pager</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">$ /etc/init.d/nagios3 reload</pre></div></div>

<p>Per testare subito quanto creato sarà sufficiente attraverso l&#8217;interfaccia web accedere al dettaglio di un host o di un servizio e cliccare sulla voce &#8220;Send custom service notification&#8221;. Se l&#8217;SMS arriva la missione è compiuta.</p>
<p><strong>Accertarsi che il sistema stia funzionando</strong></p>
<p>Certo si potrebbe sindacare sul fatto che se si rompe la macchina delle notifiche si è punto e a capo, ma questa è una cosa a cui si può porre rimedio inserendo degli invii automatici di SMS a crontab che segnalano come il sistema di notifiche SMS stia correttamente funzionando:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># Notifica quotidiana del funzionamento notifiche SMS
00 09	* * *	root	/usr/bin/gsmsendsms -C &lt;numerodelcentromessaggi&gt; -d /dev/ttyUSB1 &lt;numerodicellulare&gt; &quot;Nagios: Se ricevi questo messaggio, il servizio di notifica SMS funziona correttamente.&quot;</pre></div></div>

<p>Ogni giorno quindi, alle nove della mattina il numero di cellulare inserito nel comando riceverà un SMS che proverà il corretto funzionamento delle notifiche.</p>
<p><strong>Conclusioni</strong></p>
<p>Il metodo presentato nell&#8217;articolo è certamente economico, per certi versi non privo di difficoltà, ma indubbiamente alla portata di chiunque.<br />
Scegliendo con oculatezza il piano tariffario associato alla SIM che sarà presente nella pendrive si potrà certamente rendere il servizio di monitoraggio di Nagios completo e professionale.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.miamammausalinux.org/2009/07/nagios-notifiche-sms-con-la-pendrive-onda-mt503hs-e-parenti-prossime/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>SSH in CHROOT: la soluzione nativa</title>
		<link>http://www.miamammausalinux.org/2009/06/ssh-in-chroot-la-soluzione-nativa/</link>
		<comments>http://www.miamammausalinux.org/2009/06/ssh-in-chroot-la-soluzione-nativa/#comments</comments>
		<pubDate>Wed, 10 Jun 2009 15:23:02 +0000</pubDate>
		<dc:creator>Raoul Scarazzini</dc:creator>
				<category><![CDATA[Network]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[SSH]]></category>
		<category><![CDATA[Chroot]]></category>
		<category><![CDATA[Sicurezza]]></category>

		<guid isPermaLink="false">http://www.miamammausalinux.org/?p=707</guid>
		<description><![CDATA[Nei precedenti articoli pubblicati nella serie &#8220;SSH in CHROOT: Una gabbia per la shell sicura&#8221; parte 1 e parte 2, veniva affrontato il tema della messa in sicurezza di SSH attraverso una Patch che obbligava determinati utenti a rimanere chiusi all&#8217;interno di una gabbia virtuale. Dalla versione 5 di SSH però è possibile sfruttare un [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.miamammausalinux.org/wp-content/uploads/2009/01/openssh.png" alt="openssh" title="openssh" width="100" height="98" class="alignnone size-full wp-image-248" /></p>
<p>Nei precedenti articoli pubblicati nella serie &#8220;SSH in CHROOT: Una gabbia per la shell sicura&#8221; <a href="http://www.miamammausalinux.org/2008/02/ssh-in-chroot-una-gabbia-per-la-shell-sicura-1-di-2/">parte 1</a> e <a href="http://www.miamammausalinux.org/2008/02/ssh-in-chroot-una-gabbia-per-la-shell-sicura-2-di-2/">parte 2</a>, veniva affrontato il tema della messa in sicurezza di SSH attraverso una <em>Patch</em> che obbligava determinati utenti a rimanere chiusi all&#8217;interno di una gabbia virtuale.<br />
Dalla versione 5 di SSH però è possibile sfruttare un meccanismo nativo che implementa il CHROOT. Ecco spiegato come.</p>
<p><strong>Capire la versione di SSH installata nel sistema</strong></p>
<p>Prima di procedere con la configurazione del pacchetto è bene accertarsi che la versione di SSH installata nel sistema sia uguale o superiore alla <em>4.8p1</em>, su sistemi Debian e derivati, l&#8217;interrogazione è possibile attraverso il seguente comando:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;"># dpkg -l openssh-*
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Cfg-files/Unpacked/Failed-cfg/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Hold/Reinst-required/X=both-problems (Status,Err: uppercase=bad)
||/ Nome                                    Versione                                Descrizione
+++-=======================================-=======================================-==============================================================================================
ii  openssh-blacklist                       0.4.1                                   list of default blacklisted OpenSSH RSA and DSA keys
ii  openssh-blacklist-extra                 0.4.1                                   list of non-default blacklisted OpenSSH RSA and DSA keys
ii  openssh-client                          1:5.1p1-5                               secure shell client, an rlogin/rsh/rcp replacement
ii  openssh-server                          1:5.1p1-5                               secure shell server, an rshd replacement</pre></div></div>

<p>Mentre in sistemi RedHat e derivati è sufficiente interrogare l&#8217;elenco pacchetti installati con <em>rpm</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">$ rpm -qa openssh*
openssh-4.3p2-16.el5
openssh-askpass-4.3p2-16.el5
openssh-clients-4.3p2-16.el5
openssh-server-4.3p2-16.el5</pre></div></div>

<p>Nei casi riportati, sul sistema Debian (versione <em>Lenny</em>) la versione di SSH supporta nativamente il <em>Chroot</em> mentre il sistema RedHat (versione 5) no. In questo caso è necessario eseguire l&#8217;aggiornamento del pacchetto se ne si vorrà sfruttare la nuova funzionalità, ricompilando localmente la versione 5 partendo dai sorgenti disponibili presso <a href="http://www.openssh.org/portable.html">il sito ufficiale del progetto OpenSSH</a> oppure scaricando un rpm precompilato da repository pubblici come <a href="http://www.rpmfind.net/linux/rpm2html/search.php?query=openssh&#038;submit=Search+...">http://www.rpmfind.net</a>.</p>
<p><strong>Come funziona il CHROOT nativo</strong></p>
<p>Il metodo con cui il demone SSH, previa configurazione, costruisce la gabbia per l&#8217;utente che effettua la login può essere diviso in due tipologie: l&#8217;accesso diretto via ssh e quello via sftp.<br />
Nel primo caso la directory nella quale l&#8217;utente effettuerà il login dovrà contenere la struttura essenziale di file e directory necessaria alla navigazione all&#8217;interno del sistema, mentre attraverso il funzionamento sftp il demone non necessiterà di un ambiente nativo, ma sfruttando il comando interno sftp, fornirà l&#8217;interfaccia di accesso al sistema.</p>
<p><strong>Predisposizione del sistema</strong></p>
<p>I test che verranno effettuati nel corso dell&#8217;articolo partiranno dal presupposto che esista un gruppo denominato <em>test</em> e che tutte le utenze facenti parte di questo gruppo vengano ingabbiate.<br />
Verrà quindi creato un utente denominato <em>test</em> con cui verranno effettuate le prove:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">$ adduser test</pre></div></div>

<p>Il comando crea automaticamente il gruppo omonimo.<br />
Terminata la creazione dell&#8217;utente di test è necessario creare la struttura relativa alla gabbia. Per far questo è possibile utilizzare lo script <em>create_chroot_env.sh</em> contenuto nel file <a href="http://www.miamammausalinux.org/wp-content/uploads/2008/02/ssh-in-chroot-scripts.tar">ssh-in-chroot-scripts.tar</a> presentato nella precedente serie di articoli.<br />
Lanciando il comando come segue:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">$ ./create_chroot_env.sh /chroot</pre></div></div>

<p>nella cartella <em>/chroot</em> verrà creato un ambiente con tutti i requisiti imposti da ssh per l&#8217;implementazione della gabbia.<br />
Requisito essenziale per il corretto funzionamento del sistema è che la cartella nella quale verrà impostata la gabbia sia accessibile in scrittura alla sola utenza di root. Avendo lanciato lo script come utente root (non sarebbe possibile altrimenti utilizzare il path definito) tale requisito è pienamente rispettato.</p>
<p><strong>Configurazione del demone per l&#8217;utilizzo via ssh</strong></p>
<p>A questo punto la configurazione del server ssh andrà variata per supportare il chroot esclusivamente per le utenze facenti parte del gruppo test attraverso l&#8217;aggiunta delle seguenti righe nel file <em>/etc/ssh/sshd_config</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">Match Group test
        ChrootDirectory /chroot/</pre></div></div>

<p>terminata la modifica le configurazioni andranno ricaricate attraverso il seguente comando:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">$ /etc/init.d/ssh reload</pre></div></div>

<p><strong>Verifica del funzionamento</strong></p>
<p>Per verificare il funzionamento della gabbia è sufficiente effettuare il login nel sistema e controllare come e se sia possibile muoversi all&#8217;interno di questo:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">$ ssh test@172.16.1.130
test@172.16.1.130's password: 
Linux anomalia 2.6.26-1-686 #1 SMP Fri Mar 13 18:08:45 UTC 2009 i686
&nbsp;
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
&nbsp;
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Tue Jun  9 23:09:39 2009 from 172.16.1.1
-bash-3.2$ pwd
/
-bash-3.2$ ls
bin  dev  etc  home  lib
-bash-3.2$ cd ..
-bash-3.2$ pwd
/
-bash-3.2$ ls
bin  dev  etc  home  lib</pre></div></div>

<p>l&#8217;output illustrato conferma le aspettative: a login effettuato non è possibile scorrere il path precedente alla cartella /. La gabbia funziona.</p>
<p><strong>Configurazione del demone per l&#8217;utilizzo via sftp</strong></p>
<p>La configurazione impostata non prevede l&#8217;utilizzo di <em>sftp</em>, infatti un tentativo di connessione non andrebbe a buon fine:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">$ sftp test@172.16.1.130
Connecting to 172.16.1.130...
test@172.16.1.130's password: 
subsystem request failed on channel 0
Couldn't read packet: Connection reset by peer</pre></div></div>

<p>per fare in modo che questo tipo di connessione sia utilizzabile, è necessario modificare nuovamente <em>/etc/ssh/sshd_config</em> sostituendo la riga</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">Subsystem sftp /usr/lib/openssh/sftp-server</pre></div></div>

<p>con</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">Subsystem sftp internal-sftp</pre></div></div>

<p>In questo modo si indica ad ssh di utilizzare per il comando sftp non lo script locale <em>/usr/lib/openssh/sftp-server</em> ma la versione interna al demone.</p>
<p><strong>Verifica del funzionamento</strong></p>
<p>A questo punto dopo aver ricaricato il demone, è possibile provare nuovamente la login via sftp:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">$ sftp test@172.16.1.130
Connecting to 172.16.1.130...
test@172.16.1.130's password: 
subsystem request failed on channel 0
Couldn't read packet: Connection reset by peer
rasca@anomalia:~$ sftp test@172.16.1.130
Connecting to 172.16.1.130...
test@172.16.1.130's password: 
sftp&gt; ls
bin   dev   etc   home  lib   
sftp&gt; cd ..
sftp&gt; ls 
bin   dev   etc   home  lib</pre></div></div>

<p>Come da pronostico, il login ha avuto successo.<br />
E&#8217; da notare che in questo caso la directory di arrivo dell&#8217;utenza è sempre la <em>/</em> del <em>chroot</em> ma si può fare in modo che questa corrisponda ad una qualsiasi cartella o alla home dell&#8217;utente modificando il parametro <em>ChrootDirectory</em> nel file di configurazione di ssh. E&#8217; consentito l&#8217;utilizzo delle diciture speciali %h, corrispondente alla homedir dell&#8217;utente, e %u, corrispondente al nome dell&#8217;utente.</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">        ChrootDirectory %h</pre></div></div>

<p>E&#8217; chiaro che ogni directory scelta dovrà possedere il requisito essenziale di essere di proprietà di root e non scrivibile da alcun gruppo.</p>
<p><strong>Conclusioni</strong></p>
<p>Rispetto alla soluzione presentata nei precedenti articoli, che comportava l&#8217;applicazione di una patch ai sorgenti di ssh, quanto illustrato ha l&#8217;indubbio vantaggio di sfruttare un&#8217;implementazione nativa che non necessita di operazioni sul pacchetto. Certo i requisiti richiesti, in particolare relativamente alla proprietà della cartella madre del chroot, sono piuttosto rigidi ed obbligano a riflettere su come distribuire le utenze.<br />
La soluzione migliore, come sempre, è quella più funzionale allo scopo che ci si prefigge.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.miamammausalinux.org/2009/06/ssh-in-chroot-la-soluzione-nativa/feed/</wfw:commentRss>
		<slash:comments>35</slash:comments>
		</item>
	</channel>
</rss>

