Archivi categoria: SO: Linux

Creazione di una logging facility mediante logrotate ed expect

Scenario

Diversi siti Web (Apache) con N virtual host, ciascuno dei quali utilizza 2 file di log dedicati (access ed error), per il salvataggio degli accessi (nel primo caso) e degli errori generati (nel secondo caso).

Problema

Data l’enorme mole di utenza, è necessario comprimere e salvare i suddetti file di log con cadenza settimanale, spostando l’archivio appena ottenuto su di una logging facility (nella fattispecie una linux box), utilizzando il protocollo SFTP.

Soluzione

Integrare lo scrip di logrotate con alcuni scrip expect fatti in casa.

logging-facility

Logrotate

Lo scrip logrotate che si occuperà della vera e propria rotazione dei file di log (con cadenza settimanale) è il seguente:

/var/log/httpd/*log {
    rotate 1
    missingok
    notifempty
    sharedscrips
    dateext
    compress
    copytruncate
    weekly
    postrotate
        /sbin/service httpd restart > /dev/null 2>/dev/null || true
    endscrip
    lastaction
        /root/logrotation/autoputlog/apache > /var/log/autoputlog/apache.log
    endscrip
}

/var/log/httpd/virtual/*/*log {
    rotate 1
    missingok
    notifempty
    sharedscrips
    dateext
    compress
    copytruncate
    weekly
    postrotate
        /sbin/service httpd restart > /dev/null 2>/dev/null || true
    endscrip
    lastaction
         /root/logrotation/autoputlog/apachecustom > /var/log/autoputlog/apachecustom.log
    endscrip
}

Nella fattispecie, la prima parte si occupa della rotazione dei file di log relativi alla root directory canonica di Apache, ovvero /var/www/html, mentre la seconda parte si occupa dei virtual host veri e propri.

I suddetti scrip ci permettono di integrare logrotate con expect grazie alla direttiva lastaction. In particolare, essa farà in modo che, una volta completata la rotazione (con la creazione di una tarball opportuna), venga eseguito lo scrip expect apache (nel primo caso) ed apachecustom (nel secondo caso), presenti nella directory /root/logrotation/autoputlog.

L’output realtivo al processo di esecuzione degli scrip in questione verrà salvato rispettivamente all’interno del file apache.log ed apachecustom.log, presenti in /var/log/autoputlog. Inoltre, sarà necessario creare i file in questione prima che la rotazione venga testata, utilizzando i comandi :

[root@frontend ~]# mkdir -p /var/log/autoputlog

e

[root@frontend ~]# touch apache.log apachecustom.log

Infine, di seguito riporto il contenuto dello scrip expect apache:

#!/usr/bin/expect
set timeout 60
set password "vostrapassword"
spawn sftp admin@iplogfacility:array1/logs/frontend1/httpd
expect "*?assword:*"
send "$password\r"
expect "sftp"
send "put /var/log/httpd/*.gz\r"
expect "sftp"
send "exit\r"
expect eof

ed apachecustom:

#!/usr/bin/expect
set timeout -1
set password "vostrapassword"
spawn sftp admin@iplogfacility:array1/logs/frontend1/httpd
expect "*?assword:*"
send "$password\r"
expect "sftp"
send "cd vhost1\r"
expect "sftp"
send "put /var/log/httpd/virtual/vhost1/*.gz\r"
expect "sftp"
send "cd ../vhost2\r"
expect "sftp"
send "put /var/log/httpd/virtual/vhost2/*.gz\r"
expect "sftp"
send "cd ../vhost3\r"
expect "sftp"
send "put /var/log/httpd/virtual/vhost3/*.gz\r"
expect "sftp"
send "exit\r"
expect eof

Non ci rimane che lanciare forzatamente logrotate per testarne il funzionamento, utilizzando il comando:

[root@frontend ~]# logrotate -f /etc/logrotate.d/httpd

ed abbiamo finito.

A presto.

Centos 6 e snmptrapd: ricevere le trap SNMP sulla nostra linux box

Il protocollo SNMP, nativamente, ci mette a disposizione 2 modalità di funzionamento: quella classica, basata sul semplice polling, che utilizza la porta UDP 161, e quella “asincrona”, le cosiddette trap, che utilizzano la porta UDP 162.

Va da se che la seconda modalità è migliore rispetto alla prima, in quanto ci consente di ricevere un allarme quasi in tempo reale, dato che è proprio il dispositivo monitorato a generare l’evento (trap) ed a inoltrarcelo.

snmptrap

Ma vediamo ora come configurare la nostra linux box in modo da farle accettare (e loggare) le suddette trap.

Iptables

La prima cosa da fare consiste nel consentire il traffico UDP in ingresso, sulla porta 162:

iptables -I INPUT -p udp --dport 162 -j ACCEPT

Ovviamente tale regola iptables può essere ulteriormente affinata, specificando, ad esempio, l’interfaccia in ingresso (-i), l’IP sorgente (-s) e l’IP di destinazione (-d).

Configurazione di snmptrapd

Adesso occorre configurare il demone che si occupa della ricezione delle trap, ovvero snmptrapd.

Il suo file di configurazione è /etc/snmp/snmptrapd.conf, il cui contenuto dovrà essere simile al seguente:

authCommunity log,execute,net keypublic
format1 %l-%m-%y %h:%j:%k from %A: %b %P %N %W %v\n
format2 %l-%m-%y %h:%j:%k from %A: %b %P %N %W %v\n

La prima entry specifica la community string (keypublic) e le azioni che snmptrapd può effettuare alla ricezione delle trap, ovvero loggarle (log), eseguire un evento specifico tramite handler (execute) oppure inoltrarle ad un altro dispositivo connesso in rete (net).

Mediante le direttive format1 e format2 (utilizzare, rispettivamente, nell’ambito del protocollo SNMPv1 e v2c), specifichiamo il formato del file di log in cui verranno salvate le trap ricevute. In particolare, con:

%l-%m-%y %h:%j:%k

indichiamo il timestamp nel formato giorno-mese-anno ora:minuto:secondo.

Utilizzando invece:

from %A

siamo in grado di loggare il nome del dispositivo che ci ha inviato la trap, mentre con:

%b

ricaviamo l’indirizzo IP del suddetto dispositivo.

Infine, con:

 %P, %N, %W

abbiamo rispettivamente la community string utilizzata dalla trap, la stringa enterprise (che identifica univocamente il produttore del dispositivo) e la descrizione della trap. Ecco un esempio del contenuto del file di log popolato da snmptrapd:

23-7-2015 10:9:0 from 10.12.12.3: UDP: [10.12.12.3]:62741->[10.12.12.2] TRAP, SNMP v1, community keypublic VMWARE-CIMOM-MIB::vmwCimOm Enterprise Specific VMWARE-ENV-MIB::vmwEnvIndicationTime.0 = STRING: 2015-7-23,8:8:59.0

Occorre notare che le trap non vengono ricevute (e loggate) in formato numerico, in quanto sulla linux box sono presenti le MIB (scritte attraverso il linguaggio SMI) specifiche per i dispisitivi monitorati (in questo caso degli host VMWare). Solo a titolo informativo, le suddette MIB vanno salvate all’interno della directory /usr/share/snmp/mibs/.

 Opzioni di avvio

Una volta configurato, snmptrapd deve essere avviato utilizzando determinate opzioni, affinchè il processo di logging venga effettuato secondo le nostre necessità. Il file in cui specificare tali opzioni è /etc/sysconfig/snmptrapd, il cui contenutò dovrà essere simile al seguente:

OPTIONS="-A -m ALL -M /usr/share/snmp/mibs -Lf /var/log/snmptrapd.log -p /var/run/snmptrapd.pid"

dove l’opzione -A indica la modalità di scrittura del file di log (append); -m ALL indica la necessità di utilizzare tutte le MIB presenti sul sistema; -M serve a specificare il pathname delle MIB; -Lf indica il file di log ed infine -p punta al pathname del file *.pid (process ID) associato al demone in questione.

Rotazione del file di log

Naturalmente un file di log troppo grande risulta molto più difficile da consultare, ergo occorre definire delle regole di rotazione utilizzando lo strumento messo a disposizione dalla nostra linux box, ovvero logrotate. In particolare, il contenuto del file snmptrapd presente nella directory /etc/logrotate.d dovrà essere il seguente:

/var/log/snmptrapd.log {
    rotate 10
    missingok
    notifempty
    sharedscripts
    delaycompress
    copytruncate
    weekly
    postrotate
        /sbin/service snmtrapd restart > /dev/null 2>/dev/null || true
    endscript
}

Tra le suddette opzioni, quella più importante è certamente copytruncate, senza la quale, dopo ogni rotazione, il file di log non sarebbe in grado di registrare nuovi eventi.

Ora che è tutto configurato possiamo avviare il demone:

[root@linuxbox ~]# service snmptrapd start

e fare in modo che venga eseguito automaticamente dopo ogni boot:

[root@linuxbox ~]# chkconfig snmptrapd on

Invio tramite email delle trap di allarme

L’ultimo step consiste nel fare in modo che tutte le trap di allarme vengano inviate sulla nostra mailbox. Per fare ciò si può utilizzare swatch, il cui file di configurazione (/etc/swatch_snmp.conf) dovrà essere simile a questo:

#SNMP TRAP ALERT
watchfor  /Alert|alert/
     echo
     mail addresses=vostro.indirizzo\@email.it,subject=SWATCH LINUX-BOX: SNMP TRAP ALERT

Editiamo il file /etc/rc.local in modo da avviare automaticamente swatch ad ogni boot della macchina:

swatch -c /etc/swatch_snmp.conf -t /var/log/snmptrapd.log &

Lanciamo il comando:

[root@linuxbox ~]# swatch -c /etc/swatch_snmp.conf -t /var/log/snmptrapd.log &

ed abbiamo finito.

Alla prossima.

sniffer.sh: script bash per l’individuazione dei site grabber

Scenario

Supponiamo che il vostro sito sia diventato oggetto delle attenzioni di un grabber (di cui non si conosce l’indirizzo IP pubblico), che ogni X tempo ne preleva il contenuto forzosamente.

Supponiamo, inoltre, che il suddetto grabber sia abbastanza intelligente da coprire le proprie tracce “spoofando” lo user agent in modo da apparire come un client lecito.

590x300

Nel caso in cui non si abbiano a disposizione strumenti di log analysis avanzati quali Splunk, l’unica alternativa per individuare l’IP pubblico del grabber consiste nel crearsi degli strumenti ad-hoc,  in grado di fare un conteggio del numero di hit per ciascun IP pubblico che ha contattato il nostro sito.

In soldoni si tratta di un semplice scrip bash, che riporto di seguito.

#!/bin/bash

filename1="/var/log/sniffer.log"

filename2="/var/log/sources.log"

filename3="/var/log/sources_sorted.log"

filename4="/var/log/sources_sorted_by_hits.log"

if [ -e $filename1 ];then

cat /dev/null > $filename1

fi

if [ -e $filename2 ];then

cat /dev/null > $filename2

fi

if [ -e $filename3 ];then

cat /dev/null > $filename3

fi

if [ -e $filename4 ];then

cat /dev/null > $filename4

fi

echo ""

echo -e "33[32mSniffing traffic... Press CTRL+C to stop"

echo -e "33[37m"

START=$(date +%s);

iftop -i eth0 -n -f 'port (80 or 443)' -t > $filename1

echo ""

read -p "Press [Enter] key to continue..."

END=$(date +%s);

ELAPSED_TIME=$((END-START))

echo -e "33[32mShowing hit number provided in $ELAPSED_TIME seconds, ordered by source..."

echo -e "33[37m"

cat $filename1 | grep '<=' | awk '{ print $1 }' > $filename2

cat $filename2 | sort -u > $filename3

while read line

do
 hits=`cat $filename2 | grep $line | wc -l`

host=`host $line`

echo "hits for IP $line ($host): $hits" >> $filename4

done < $filename3

cat $filename4 | sort -k 5 -nr

exit 0

Esso si basa principalmente sul software iftop e, una volta lanciato, rimane in ascolto sulle porte di interesse (nel nostro caso la TCP/80 e la TCP/443), per poi stilare una “classifica” di IP pubblici in base al numero di hit che hanno prodotto durante il tempo di osservazione.

Come informazione aggiuntiva, per ogni IP viene ricavato anche il suo FQDN (attraverso il comando host), in modo da individuare ancora più facilmente la provenienza del grabber.

Per maggiore chiarezza, ecco un esempio di output relativo al suddetto script:

hits for IP 87.18.215.154 (154.215.18.87.in-addr.arpa domain name pointer host154-215-dynamic.18-87-r.retail.telecomitalia.it.): 18
hits for IP 84.223.145.17 (17.145.223.84.in-addr.arpa domain name pointer dynamic-adsl-84-223-145-17.clienti.tiscali.it.): 23
hits for IP 84.222.212.172 (172.212.222.84.in-addr.arpa domain name pointer dynamic-adsl-84-222-212-172.clienti.tiscali.it.): 23
hits for IP 79.18.99.217 (217.99.18.79.in-addr.arpa domain name pointer host217-99-dynamic.18-79-r.retail.telecomitalia.it.): 24
hits for IP 2.35.156.49 (49.156.35.2.in-addr.arpa domain name pointer net-2-35-156-49.cust.vodafonedsl.it.): 21
hits for IP 188.87.64.235 (235.64.87.188.in-addr.arpa domain name pointer static-235-64-87-188.ipcom.comunitel.net.): 23
hits for IP 151.45.153.218 (218.153.45.151.in-addr.arpa domain name pointer adsl-ull-218-153.45-151.net24.it.): 14

Inoltre, consultando il file /var/log/sources_sorted_by_hits.log, sarà possibile ricavare la lista degli IP/FQDN ordinati (in modo decrescente) in base al numero delle hit che hanno effettuato.

Una volta individuato l’IP che ci interessa non ci resta che bloccarlo utilizzando, ad esempio, iptables:

iptables -I INPUT -s <ip del grabber> -j DROP

ed abbiamo finito.

Alla prossima.

checksecurity.sh: script bash per monitorare gli aggiornamenti critici su CentOS 6

Poichè devo gestire un elevato numero di VM *nix, mi è indispensabile riuscire ad automatizzare quanti più task possibili, tenendo sempre a mente tale regola:

                                                                        a good sysadmin is a lazy one

Uno di questi task riguarda le notifiche per gli aggiornamenti critici di sistema, soprattutto per ciò che concerne l’aspetto della cyber security.

A tal proposito, ho realizzato uno scrip bash in grado di verificare la presenza di eventuali aggiornamenti e di inviarmi successiva notifica via email.  Starà a me, in un secondo momento, decidere quando e se installare gli aggiornamenti proposti.

I tool necessari al suo funzionamento sono 2, ovvero yum-security e mutt. Procediamo dunque con la loro installazione mediante yum:

[root@linuxbox ~]# yum install yum-plugin-security mutt -y

bashEd ecco lo scrip:

#!/bin/bash

logfile=/var/log/checksecurity.log

data=`date +%d-%m-%Y`

destinatario=vostro.indirizzo@email.it

echo "$data: Checking for security updates..." >> $logfile

yum clean all

yum list-security >> /root/checksec/tmp

security=`cat /root/chcksec/tmp | grep security | grep -v Loaded`

bugfix=`cat /root/checksec/tmp | grep bugfix`

cve=`cat /root/checksec/tmp | grep cve`

if [ -n "$security" ];then
echo "$data: security updates available" > /root/checksec/out
fi

if [ -n "$bugfix" ];then
echo "$data: bugfix updates available" >> /root/checksec/out
fi

if [ -n "$cve" ];then
echo "$data: cve updates available" >> /root/checksec/out
fi

if [ -s /root/checksec/out ];then

cat /root/checksec/tmp >> /root/checksec/out

cat /root/checksec/out >> $logfile

cat /root/checksec/out | mutt -s "GESTORE01: security, bugfix and cve system report" $destinatario

rm /root/checksec/out

else

echo "$data: Nothing to do, exiting..." | tee -a $logfile

fi

rm /root/checksec/tmp

exit 0;

Ci rimane solo rendere lo scrip eseguibile (chmod +x /root/checksec/checksecurity.sh) ed aggiungerlo a crontab.

Alla prossima.

Nagios: script bash + expect per monitorare il numero di NAT translation sui router Cisco

Dopo aver cercato a lungo un OID SNMP che potesse restituirmi on-the-fly il numero di NAT translation attive sul mio router Cisco, sono arrivato alla conclusione che il modo più semplice per ricavare tale informazione consiste nel creare uno scrip bash + expect da dare in pasto a Nagios.

Nagios_logo_blackPer prima cosa, dunque, mi sono soffermato sulla creazione dello scrip expect, in modo da poter interrogare il router oggetto di monitoraggio, lanciando un comando specifico, che è il seguente:

Router# show ip nat statistics

Ed ecco lo scrip expect vero e proprio:

#!/usr/bin/expect

set ip [lindex $argv 0]
set password1 [lindex $argv 1]
set password2 [lindex $argv 2]

spawn ssh -l nightfly "$ip"
expect "*?assword:*"
send "$password1\r"
expect ">"
send "ena\r"
expect "Password:"
send "$password2\r"
expect "#"
send "show ip nat statistics\r"
expect "#"
send "exit\r"
expect eof

Esso riceve come parametri l’IP del dispositivo, la password vty e la password ena.
Dopo averlo chiamato get_nat_num (ed averlo reso eseguibile con chmod +x get_nat_num), mi sono soffermato sulla creazione dello scrip bash, che è il seguente:

#!/bin/bash

host=$1
password1=$2
password2=$3
warning=$4
critical=$5

usage="check_nat_translations <host> <password1> <password2> <warning> <critical>"

if [ -n "$host" ]; then

        if [ -n "$password1" ];then

                if [ -n "$password2" ];then

                        if [ -n "$warning" ];then

                                if [ -n "critical" ];then

                                        if [ "$critical" -lt "$warning" ];then

                                                echo "UNKNOWN: critical has to be greater than warning"
                                                exit 3;

                                        else

                                                output=`/usr/lib64/nagios/plugins/get_nat_num $1 $2 $3 | grep "Total active translations"  | awk '{print $4}'`

                                        fi

                                        if [ -n "$output" ];then

                                                if [ "$output" -ge "$critical" ];then

                                                        echo "CRITICAL: total number of active NAT translations is $output | nat_translations=$output;$warning;$critical";
                                                        exit 2;

                                                elif [ "$output" -lt "$critical"  -a  "$output" -ge "$warning" ];then

                                                        echo "WARNING: total number of active NAT translations is $output | nat_translations=$output;$warning;$critical";
                                                        exit 1;

                                                else

                                                        echo "OK: total number of active NAT translations is $output | nat_translations=$output;$warning;$critical";
                                                        exit 0;

                                                fi
                                        else

                                                echo "UNKNOWN: output is null"
                                                exit 3;

                                        fi

                                else

                                        echo "$usage"
                                        exit 3;
                                fi

                        else

                                echo "$usage"
                                exit 3;
                        fi

                else

                        echo "$usage"
                        exit 3;
                fi
        else

                echo "$usage"
                exit 3;
        fi

else

        echo "$usage"
        exit 3;

fi

Esso accetta in ingresso 5 parametri: i primi 3 da passare allo scrip get_nat_num, gli ultimi 2 da utilizzare come soglie per Nagios (una warning ed una critical).

Rendiamo eseguibile anche questo scrip (chmod +x check_nat_translations) e soffermiamoci sulla configurazione di Nagios.

Come primo step occorre creare il comando che utilizza i plugin appena creati:

# 'check_nat_translations' command definition
 define command{
 command_name    check_nat_translations
 command_line    $USER1$/check_nat_translations $HOSTADDRESS$ $ARG1$ $ARG2$ $ARG3$ $ARG4$
 }

Successivamente è necessario creare un servizio (da inserire nel file di configurazione relativo ad un host determinato), che si avvalga del comando creato in precedenza:

define service{
 use                             local-service         ; Name of service template to use
 host_name                       cisco
 service_descripion             NAT Translations Number
 check_command                   check_nat_translations!password1!password2!40000!50000
 }

Salviamo la configurazione, riavviamo Nagios, ed il gioco è fatto.

Alla prossima.

CentOS 6: Watchdog open source mediante Monit

Premesso che Monit può essere configurato anche come NMS a tutti gli effetti (sia centralizzato che distribuito, vedi M/Monit), lo scopo di questo post è quello di illustrarne la configurazione come semplice watchdog.

watchdogEsso, infatti, si occuperà di riavviare eventuali servizi “in stallo” (nella fattispecie httpd e mysql), riducendo notevolmente i tempi di downtime.

Per prima cosa occorre installare il suddetto applicativo:

[root@server ~]# yum install monit

Una volta installato possiamo editarne la configurazione (/etc/monit.conf) nel modo seguente:

set httpd port 2813 and #2813 è la porta su cui è in ascolto l'interfaccia Web di Monit
     use address <indirizzo IP>  #l'indirizzo IP è quello su cui l'interfaccia Web di Monit è in binding
     allow 0.0.0.0/0          #semplice ACL per consentire a qualunque IP sorgente di connettersi alla suddetta interfaccia  
     allow username:password      # credenziali di accesso all'interfaccia Web di Monit
     allow @monit           
     allow @users readonly

A questo punto creiamo due file all’interno della directory /etc/monit.d, rispettivamente httpd e mysqld.

Il primo conterrà le seguenti direttive:

check process httpd with pidfile /var/run/httpd.pid
group apache
start program = "/etc/init.d/httpd start"
stop program = "/etc/init.d/httpd stop"
if failed host 94.23.68.182 port 80
protocol http then restart
if 5 restarts within 5 cycles then timeout

Il secondo, invece, avrà il seguente contenuto:

check process MySQL-Server with pidfile /var/run/mysqld/mysqld.pid
    start program = "/etc/init.d/mysqld start"
    stop program = "/etc/init.d/mysqld stop"
    if failed host localhost port 3306
    protocol mysql then restart
    if 5 restarts within 5 cycles then timeout

Verifichiamo la sintassi delle suddette configurazioni mediante il comando:

[root@server ~]# monit -t

Ora possiamo avviare il nostro watchdog:

[root@server ~]# service monit start

imponendone l’avvio automatico dopo ogni reboot del server:

[root@server ~]# chkconfig monit on

Verifichiamo l’effettiva raggiungibilità dell’interfaccia Web di Monit mediante la URL:

http://IP:2813

ed il gioco è fatto.

E’ tutto. Alla prossima.

Configurare un server VNC su CentOS 6

Avere a disposizione un server VNC sulla nostra linux box è molto comodo, soprattutto quando la si utilizza come “ponte” per accedere all’interfaccia Web di configurazione di alcuni dispositivi di rete (quali NAS, access point, router e così via).

vnc

Di seguitò illustrerò come fare ad installare e configurare un server VNC sulla nostra macchina CentOS 6.

Installazione  del server VNC

Per scaricare il server VNC è sufficiente utilizzare il packet manager integrato alla distro, ovvero yum:

[root@vncserver ~]# yum install tigher-vnc

Configurazione del server VNC

Per prima cosa occorre creare le utenze che andranno ad utilizzare il server VNC:

[root@vncserver ~]# useradd <username1>
[root@vncserver ~]# passwd <username1>
[root@vncserver ~]# useradd <username2>
[root@vncserver ~]# passwd <username2>

Una volta create le utenze,  occorre settare i parametri delle sessioni VNC a cui avranno accesso, editando il file /etc/sysconfig/vncserver:

VNCSERVERS="1:username1 2:username2"
VNCSERVERARGS[1]="-geometry 1024x768"
VNCSERVERARGS[2]="-geometry 1024x768"

Per entrambi gli utenti precedentemente definiti abbiamo previsto delle sessioni VNC con risoluzione a 1024×768.

A questo punto, ciascun utente, dovrà impostare la propria password VNC mediante il comando:

[username1@vncserver ~]$ vncpasswd

Infine, dovrà editare il file xstartup presente nella propria home directory:

[username1@vncserver ~]$ nano /home/username/.vnc/xstartup

commentando la entry:

#twm &

ed inserendo la seguente direttiva (nel caso in cui sulla linux box sia installato KDE come X server):

startkde &

Invece, se si sta utilizzando Gnome, la direttiva da inserire è la seguente:

exec gnome-session

Configurazione del firewall

Per configurare il firewall (netfilter) occorre editare il file /etc/sysconfig/iptables, aggiungendo quanto segue:

-A INPUT -m state --state NEW -m tcp -p tcp -m multiport --dports 5901:5903,6001:6003 -j ACCEPT

Riavviamo netfilter con il seguente comando:

[root@vncserver ~]# service iptables restart

e facciamo in modo che il nostro server VNC venga eseguito in modo automatico dopo ogni riavvio della macchina:

[root@vncserver ~]# chkconfig vncserver on

Infine, avviamo il suddetto demone:

[root@vncserver ~]# service vncserver start

Client VNC

Il client che preferisco è Real VNC Viewer e potete scaricarlo da qui.

Fine del post, a presto.

Websockets e Squid Proxy

Ultimamente ho deciso di approfondire una tecnologia Web abbastanza recente, ovvero i Websockets. In particolare, essa consente di instaurare un tunnel di comunicazione client/server attraverso il protocollo HTTP, riducendo notevolmente, rispetto al classico longpolling tipico del linguaggio AJAX, la mole di traffico richiesta e soprattutto l’overhead del server. Mediante i Websockets sarà possibile inviare “gli aggiornamenti” al client “in tempo reale”, ovvero senza che l’utente debba effettuare i classici “refresh” della pagina Web.

In ambito open source esistono diverse implementazioni dei Websockets. Quella che preferisco in assoluto si basa sulla libreria socket.io, integrata ad un applicativo nodejs (quest’ultimo rappresenta una vera e propria rivoluzione poichè ha consentito di utilizzare un linguaggio di programmazione nato per i client, ovvero Javascript, come un vero e proprio linguaggio server-side).

Ora, effettuando alcuni test su un proxy Web (Squid per la precisione), ho notato che i tentativi di connessione verso il server nodejs (sfruttando quindi i Websockets), venivano sistematicamente bloccati.

squid

La spiegazione è molto semplice. Infatti, andando a visualizzare la configurazione di default del suddetto proxy, è possibile notare la presenza di tale parametro:

http_access deny CONNECT !SSL_ports

Tale direttiva impone a Squid di negare l’uso del metodo HTTP CONNECT da parte dei client nel caso in cui non si stia utilizzando il protocollo HTTPS (HTTP + SSL/TLS). Infatti, di per se, il protocollo HTTPS prevede l’instaurazione di un “tunnel” di comunicazione “sicuro” tra client e server, utilizzando, per l’appunto, il metodo CONNECT. Ora, tale metodo viene utilizzato anche dai Websocket per creare il “canale” di comunicazione HTTP con i client, ergo basta commentare la suddetta entry per consentire l’accesso ai client:

#http_access deny CONNECT !SSL_ports

Effettuiamo reload della configurazione di Squid mediante il comando

[root@webProxy ~]# squid -k reconfigure

ed il gioco è fatto.

Alla prossima.

Nagios troubleshooting

In questo post ho illustrato il comando da lanciare per appurare molto velocemente l’eventuale presenza di errori all’interno della configurazione di Nagios . Qui, invece, ho discusso di un valido tool in grado di debuggare i plugin utilizzati dall’NMS in questione.

nagiosEntrambi i suddetti metodi non rappresentano le uniche alternative in fase di troubleshooting. Infatti, Nagios mette a disposizione nativamente una modalità debug, la quale è in grado di “mostrare” come i vari comandi (configurati all’interno del file commands.cfg e valorizzati in nomehost.cfg) vengono interpretati ed eseguiti di volta in volta.

Per attivare tale modalità occorre operare all’interno del file /etc/nagios/nagios.cfg, impostando il debug level a 2048 (macros):

debug_level=2048

Il file da consultare sarà questo:

/var/log/nagios/nagios.debug

Inoltre, quando si ha a che fare con alcuni plugin sviluppati soprattutto in perl che lanciati da linea di comando come utente nagios funzionano correttamente mentre da pagina Web restituiscono un risultato di tipo Critical con output null, si può aggiungere, all’interno del file /etc/nagios/commands.cfg (in corrispondenza del comando che fa uso del suddetto plugin), la seguente entry:

2>&1

Ad esempio, per il plugin check_squid.pl ho definito il seguente comando:

'check_squid' command definition
define command{
        command_name    check_squid
        command_line    $USER1$/check_squid -u $ARG1$ -p $HOSTADDRESS$ -l $ARG2$ -e $ARG3$ 2>&1
        }

in modo tale da pololare il risultato del check presente nella pagina Web reindirizzando lo standard err (2>) nello standard out (&1).

Entrambi i metodi illustrati in questo post prevedono un reload della configurazione di Nagios per entrare in funzione:

[root@NMS ~]# service nagios reload

Per ora è tutto.

Alla prossima.

check_arptables: script Nagios per verificare lo stato di arptables_jf

In questo post ho discusso della configurazione di LVS in modalità Direct Routing. Tale configurazione richiedeva l’installazione e la corretta configurazione di arptables_jf per la gestione delle richieste ARP dirette ai frontend. Adesso vedremo come verificare l’effettivo funzionamento del suddetto applicativo attraverso l’NMS open source per eccellenza, Nagios.

nagiosCreazione dell’eseguibile e configurazione dell’NMS

Il codice bash che ho creato per effettuare i controlli sullo status di arptables_jf è il seguente:

#!/bin/bash

host=$1
warning=$2
critical=$3

usage="check_arptables <host> <warning> <critical>"

if [ -n "$host" ]; then

        if [ -n "$warning" ];then

                if [ -n "critical" ];then

                        if [ "$warning" -lt "$critical" ];then

                                echo "UNKNOWN: warning has to be greater than critical"
                                exit 3;

                        else

                                output=`sudo arptables -L | grep -v Chain | grep -v target | wc -l`

                                if [ "$output" -le "$critical" ];then

                                        echo "CRITICAL: total number of rules is $output";
                                        exit 2;

                                elif [ "$output" -gt "$critical"  -a  "$output" -le "$warning" ];then

                                        echo "WARNING: total number of rules is $output";
                                        exit 1;

                                else

                                        echo "OK: total number of rules is $output";
                                        exit 0;

                                fi
                        fi
                else

                        echo "$usage"
                        exit 3;

                fi
        else

                echo "$usage"
                exit 3;

        fi
else

        echo "$usage"
        exit 3;

fi

Il suddetto codice è abbastanza esplicativo: dopo aver verificato la presenza di tutti i parametri richiesti e la loro consistenza (ovvero la soglia di warning deve essere strettamente maggiore di quella di critical), viene effettuato il conteggio delle regole arptables attive sul frontend monitorato. Il comando principale è il seguente:

sudo arptables -L | grep -v Chain | grep -v target | wc -l

Da notare che è presente la direttiva sudo poichè l’applicativo arptables richiede i privilegi di root per essere eseguito. Rendiamo il suddetto codice eseguibile:

[root@NMS ~]# chmod +x check_arptables

e copiamolo nella directory /usr/lib64/nagios/plugins del frontend:

[root@NMS ~]# scp check_arptables root@frontend.dominio.com:/usr/lib64/nagios/plugins

Ora è possibile, all’interno della configurazione di Nagios, definire il comando da lanciare per monitorare arptables sul frontend (all’interno del file /etc/nagios/commands.cfg):

# 'check_remote_arptables' command definition
define command{
        command_name    check_remote_arptables
        command_line    $USER1$/check_by_ssh -H $HOSTADDRESS$ -C "/usr/lib64/nagios/plugins/check_arptables $ARG1$ $ARG2$ $ARG3$"
        }

Tale comando non fa altro che connettersi al frontend via SSH (senza password, mediante un semplice scambio di chiavi RSA) e lanciare l’eseguibile precedentemente creato.

Nella configurazione di Nagios relativa allo specifico frontend, invece, occorre creare un servizio simile al seguente:

define service{
        use                             local-service         ; Name of service template to use
        host_name                       frontend.dominio.com
        service_description             Arptables Rules Status
        check_command                   check_remote_arptables!localhost!3!2
        notifications_enabled           0
        }

Configurazione del frontend

Sul frontend è sufficiente editare il file /etc/sudoers per consentire all’utente nagios di lanciare il comando arptables senza sessione TTY e senza richiesta di inserimento della password. Nella fattispecie, nel primo caso è sufficiente commentare la direttiva:

#Defaults requiretty

mentre nel secondo caso occorre inserire la seguente stringa:

nagios  ALL=(root)      NOPASSWD: /sbin/arptables

A configurazione del frontend terminata possiamo lanciare sull’NMS il comando:

[root@NMS ~]# service nagios reload

ed abbiamo finito.

Ora arptables è correttamente monitorato.

Alla prossima.