CentOS 6, Nagios e NagVis: creazione di mappe personalizzate per l’attività di monitoring

Da qualche anno ormai sono solito postare diversi articoli riguardanti il mio NMS preferito, ovvero Nagios (nella versione core). Qualcuno di voi obietterà dicendo che c’è di meglio sul mercato, soprattutto per ciò che concerne la facilità/rapidità di utilizzo e configurazione. Personalmente credo che, utilizzando le terze parti che hanno reso celebre il software in questione, è possibile raggiungere livelli di usabilità e prestazioni del tutto simili a quelle degli NMS concorrenti e di ultima generazione (vedi, ad esempio, Icinga).

nagvis

In particolare, la mia infrastruttura di monitoraggio tipo si compone dei seguenti elementi:

1) Nagios core;

2) PNP4Nagios per la graficizzazione dei risultati ottenuti mediante i check;

2) Un sistema per la ricezione delle trap SNMP (snmptrapd + snmptt per la loro traduzione) convertite all’occorrenza in check passivi mediante il plugin submit_check_result;

3) Un tool per il monitoraggio delle macchine Windows mediante polling (NRPE + check_nrpe);

4) NSCA insieme ad NSClient++ per la ricezione dei check passivi provenienti dalle macchine Windows;

5) Swatch + NRDP per la conversione dei nuovi eventi registrati all’interno dei file di log (monitorati in tempo reale da swatch) in check passivi;

6) MRTG per il monitoraggio delle prestazioni della rete (throughput di picco e medio) e, all’occorrenza, per tenere sotto controllo le performance di Nagios (vedi questo articolo per ulteriori dettagli);

7) Event handlers vari ed eventuali per la risoluzione automatica dei problemi segnalati da Nagios;

8) NagVis per la creazione di mappe personalizzate, contenenti tutti gli elementi della nostra infrastruttura che vogliamo tenere sotto controllo (con grado di dettaglio libero a piacere).

In questo post tratterò, per l’appunto, l’installazione e la configurazione di NagVis.

Installazione e configurazione dell’event broker

Per prima cosa occorre scaricare ed installare sul nostro sistema il cosiddetto event broker, ovvero un applicativo che farà da “tramite” (lasciatemi passare il termine) tra Nagios e NagVis. Nella fattispecie, esso “interrogherà” Nagios sullo stato di un host o di un servizio e girerà il risultato a NagVis.

L’event broker di nostro interesse è mklivestatus (creato da Mathias Kettner, lo stesso autore di Check_Mk), la cui pagina ufficiale è questa.

Possiamo dunque scaricarlo:

[root@linuxbox ~]# cd /usr/local/

[root@linuxbox local]# wget 'https://mathias-kettner.de/download/check_mk-1.2.7i3p5.tar.gz'

decomprimerlo:

[root@linuxbox local]# tar -xvf check_mk-1.2.7i3p5.tar.gz

ed installarlo:

[root@linuxbox local]# cd check_mk-1.2.7i3p5 && ./configure && make && make install

A questo punto creiamo la directory rw all’interno di /var/spool/nagios, assegnandole il giusto owner:

[root@linuxbox local]# cd /var/spool/nagios && mkdir rw

[root@linuxbox nagios]# chown nagios:nagios rw

In questo modo il nostro event broker potrà salvare le informazioni, ricavate dall’NMS, all’interno dell’apposito file /var/spool/nagios/rw/live.

Ora possiamo integrare il suddetto applicativo a Nagios, modificandone il file di configurazione (/etc/nagios/nagios.cfg) come segue:

event_broker_options=-1

broker_module=/usr/local/lib/mk-livestatus/livestatus.o /var/spool/nagios/rw/live

Passiamo adesso a NagVis.

Installazione e configurazione di NagVis

Prima di tutto è necessario installare le dipendenze indispensabili al suddetto applicativo:

[root@linuxbox ~]# yum install php-gd php-mbstring php-pdo graphviz graphviz-graphs perl-GraphViz graphviz-doc rsync

A questo punto sarà possibile installare NagVis puntando a questo link. Esso si riferisce all’ultima versione stabile (ovvero la 1.8.5).

[root@linuxbox ~]# cd /usr/local/ && wget http://www.nagvis.org/share/nagvis-1.8.5.tar.gz

Una volta completato il download occorre decomprimere l’archivio:

[root@linuxbox local]# tar -xvf nagvis-1.8.5.tar.gz

e, successivamente, passare all’installazione vera e propria dell’applicativo:

[root@linuxbox local]# cd nagvis-1.8.5 && ./install.sh

Inoltre, occorre configurarlo come segue:

[root@linuxbox nagvis]# nano etc/nagvis.ini.php

[backend_live_1]
backendtype="mklivestatus"
socket="unix:/var/spool/nagios/rw/live"

Riavviamo Nagios come al solito:

[root@linuxbox nagvis]# service nagios reload

e puntiamo all’indirizzo dell’interfaccia Web di NagVis:

http://ipserver/nagvis

Infine, dopo esserci loggati utilizzando le credenziali di default (admin/admin), possiamo modificarle ed installare delle immagini utili alla creazione delle nostre mappe attingendo da questo e quest’altro sito.

Il risultato finale sarà simile al seguente:

nagvis_vmwareIl post termina qui, alla prossima.

CentOS 6 e PHP 5.3.3: cifratura del codice sorgente mediante BLENC (Blowfish Encoder for PHP source scripts)

A quanti di voi sarà capitato di dover cifrare del codice PHP scritto di vostro pugno, magari perchè contenente informazioni sensibili, quali, ad esempio, username e password di accesso al database?

Ebbene, un metodo semplice per ottenere quanto sopra consiste nell’installare il modulo PHP BLENC (che è ancora in versione beta – qui trovate il manuale). Tale operazione può essere effettuata in modo semiautomatico utilizzando il tool pecl presente sulla nostra macchina.

PHPPrima di procedere, è necessario verificare che il suddetto applicativo sia già installato, digitando il comando:

[root@linuxbox ~]# which pecl

il cui output dovrebbe essere:

/usr/bin/pecl

Successivamente, potremo procedere con l’installazione vera e propria del modulo BLENC, lanciando il comando:

[root@linuxbox ~]# pecl install -f blenc

A questo punto potremo creare il file blenc.ini da posizionare all’interno della dir /etc/php.d, il cui contenuto dovrà  essere simile al seguente:

; Enable blenc extension module
extension=blenc.so

All’interno del file /etc/php.ini, utilizzando la entry blenc.key_file, possiamo definire il percorso in cui trovare le chiavi per decifrare gli scrip criptati, ovvero:

[blenc]

blenc.key_file = /usr/local/etc/blenckeys

Ora passiamo alla creazione del file encrypt.php, il cui contenuto dovrà essere:

<?php

$file_to_crypt=file_get_contents("security.php");

$key=blenc_encrypt($file_to_crypt, "connect.php");

$key_file = ini_get('blenc.key_file');

file_put_contents($key_file, $key."\n", FILE_APPEND);

?>

il quale ci consentirà di cifrare gli scrip di nostro interesse.

In particolare, security.php contiene il codice sorgente che vogliamo criptare, connect.php sarà il nostro file cifrato e la chiave generata mediante la funzione blenc_encrypt() verrà salvata all’interno dell’apposito file /usr/local/etc/blenckeys, ricavato mediante il parsing della direttiva blenc.key_file presente in /etc/php.ini.

Da notare che all’interno della funzione file_put_contents(), il secondo argomento contiene il carattere \n (newline), poichè per il corretto funzionamento del modulo è necessario che per ogni riga sia presente una sola chiave (dove ogni chiave si riferisce univocamente ad un file cifrato). Tale “accortezza” non è presente all’interno del manuale ufficiale.

Come ultimo step riavviamo httpd:

[root@linuxbox ~]# service httpd reload

ed abbiamo finito.

Alla prossima.

Nagios e CentOS 6: tuning dei service check timeout

In questo post vi ho parlato di come configurare Nagios affinchè riesca a monitorare lo stato degli aggiornamenti relativi ad una macchina Windows Server 2008 R2.

Per qualche tempo tutto ha funzionato correttamente, fino a quando il servizio in questione ha cominciato a restituirmi dei timeout. Aver ridotto gli intervalli dei check non ha portato i risultati sperati, per cui ho dovuto armarmi di pazienza ed iniziare a fare un po’ di sano troubleshooting.

nagiosProblema

Dopo l’uscita degli ultimi sistemi operativi di casa Microsoft (8, 10, Server 2012, Server 2012 R2), la verifica degli aggiornamenti relativi a Windows 7, Server 2008 e Server 2008 R2 (per i quali il supporto è ancora attivo) è diventato un processo lento e macchinoso, probabilmente a causa della minore priorità data agli OS in questione. Ecco la causa principale dei timeout di cui sopra. Come risolvere dunque? Procediamo utilizzando un metodo (quasi) infallibile, ovvero il divide et impera.

Step 1: verifica del timeout associato al comando check_nrpe

Il tool check_nrpe, utilizzato per interrogare lo stato della macchina Windows, prevede l’uso (facoltativo) della flag -t, utile per la definizione del tempo di timeout (che per default è pari a 10 secondi). Per questo motivo ho fatto in modo che il comando check_WMI_windows_updates prevedesse la possibilità di specificare un tempo di timeout libero a piacere (-t $ARG1$):

# nagios-WMI-windows-updates check command definition

define command {
        command_name    check_WMI_windows_updates
        command_line    /usr/lib64/nagios/plugins/check_nrpe -H $HOSTADDRESS$ -t $ARG1$ -c get_windows_updates
        }

Nella fattispecie, il servizio che si avvale del suddetto comando ha un tempo di timeout pari a 600 secondi, come riportato di seguito:

define service{
        use                             generic-service         ; Name of service template to use
        host_name                       Windows-Machine
        service_description             query WMI Updates for Microsoft Windows Machine
        check_command                   check_WMI_windows_updates!600
        normal_check_interval           120
        }

Esso deve coincidere con il timeout del comando get_windows_updates definito all’interno del file \Pugins\V2\V2_nrpe_commands.cfg, il cui contenuto sarà:

command[get_windows_updates]=cscrip.exe //nologo //T:600 c:\nrpe\plugins\v2\check_windows_updates.wsf /w:0 /c:1

Il suddetto timeout va definito anche all’interno del file bin\nrpe.cfg, nel modo seguente:

command_timeout= 600

Tutte queste modifiche erano già state opportunamente trattate nell’ambito del mio post originale, ma ho ritenuto comunque utile rammentarle.

Step 2: verifica del timeout associato ai servizi di Nagios

Fortunatamente, l’NMS in questione ci consente di definire un tempo di timeout “globale” per i check dei servizi definiti dall’utente. Esso è presente all’interno del file /etc/nagios/nagios.cfg e la direttiva di nostro interesse è service_check_timeout da impostare come segue:

service_check_timeout=600

Riavviamo quindi Nagios per rendere effettive le modifiche appena apportate:

[root@linuxbox ~]# service nagios reload

Step 3: verifica dei timeout delle NAT translations

L’ultima fase di troubleshooting consiste nella verifica dei timeout associati alle NAT translations del router. Il dispositivo in questione è un Cisco 877 e per visualizzare le informazioni di nostro interesse occorre utilizzare il comando:

sh ip nat translations verbose

il cui output sarà simile al seguente:

extended, timing-out, use_count: 0, entry-id: 427758, lc_entries: 0
tcp 78.13.12.241:443      192.168.4.2:443       ---                   ---
    create 2w0d, use 00:00:51 timeout:300000, timing-out,
    flags:

Come si può notare, il timeout di default per le connessioni TCP è pari a 300000 ms (300 secondi ovvero 5 minuti), ergo dobbiamo incrementarlo fino a 600000 per allinearlo alla configurazione di Nagios. Per fare ciò è sufficiente lanciare il comando:

ip nat translation tcp-timeout 600

Salviamo la configurazione del router mediante un copy run start ed i timeout del servizio spariranno come per magia.

Il post termina qui, alla prossima.

CentOS 6: gestione delle periferiche removibili mediante UDEV

Scenario

Macchina CentOS 6 dotata di 2 dischi rigidi, ovvero:

1) /dev/sda dove è presente la partizione di boot (sda1) e quella di root (sda2);

2) /dev/sdb che consta di un’unica partizione dedicata al salvataggio di dati.

CentOSProblema

Collegando una memoria flash di tipo USB (che funge da dongle per un applicativo in esecuzione sul server) essa viene inizialmente mappata come /dev/sdc. Dopo un riavvio della macchina, però, il kernel name assegnato alla stessa diventa /dev/sda e di conseguenza i 2 dischi rigidi vengono mappati come /dev/sdb e /dev/sdc. Ciò, fortunatamente, non va ad inficiare il funzionamento del server, in quanto il file /etc/fstab contiene gli UUID (univoci e soprattutto statici) assegnati a ciascuna partizione (anzichè il kernel name che, come abbiamo visto, può variare).

Nel mio caso, però, esiste un problema: poichè utilizzo uno specifico tool per monitorare lo stato delle partizioni, le quali vengono interrogate mediante il loro kernel name, dovrei modificare tale parametro di volta in volta, distinguendo il caso in cui i dischi rigidi vengono mappati in modo “standard”, ovvero come /dev/sda e /dev/sdb, dal caso in cui vengono riconosciuti come /dev/sdb e /dev/sdc (con la memoria flash che fa le veci di /dev/sda). Ergo, devo fare in modo che la memoria flash venga mappata sempre e comunque come /dev/sdd.

Soluzione

Quanto sopra può essere realizzato configurando opportunamente udev. Tale applicativo si basa su alcuni file di configurazione, dislocati su 2 directory differenti, ovvero:

1) /lib/udev/rules.d/ che contiene i file di configurazione di default (non vanno editati);

2) /etc/udev/rules.d che contiene i file di configurazione “customizzabili” dall’utente (il cui contenuto ha una maggiore priorità rispetto a quello dei file di default, “scavalcandoli” all’occorrenza).

Tutti i suddetti file vengono dati in pasto ad udev seguendo un ordine crescente dettato esclusivamente dal loro filename. Da ciò si capisce come mai il contenuto tipico della directory /etc/udev/rules.d è simile al seguente:

[root@linuxbox ~]# ls /etc/udev/rules.d/
60-pcmcia.rules  70-persistent-cd.rules    90-hal.rules
60-fprint-autosuspend.rules  60-raw.rules     70-persistent-net.rules  90-alsa.rules                98-kexec.rules

dove le direttive presenti nel file 60-pcmcia.rules vengono lette (ed eseguite) prima di quelle relative a 70-persistent-cd.rules.

Poichè vogliamo che il file contenente le nostre direttive custom venga valutato per primo, dobbiamo nominarlo come 10-local.rules. Creiamolo quindi utilizzando il comando:

[root@linuxbox ~]# touch /etc/udev/rules.d/10-local.rules

per poi popolarlo come vi indicherò più avanti.

Dopo aver creato il suddetto file, occorre individuare le caratteristiche tipiche di ciascun disco rigido e della memoria flash, utilizzando il comando:

[root@linuxbox ~]# udevadm info -a -n /dev/sdXY

dove X è la lettera che identifica il device ed Y (facoltativo) è il numero di partizione.

Ad esempio, per /dev/sda possiamo utilizzare il comando:

[root@linuxbox ~]# udevadm info -a -n /dev/sda

il cui output sarà simile al seguente:

custom logging function 0x7f90ec575030 registered
udevadm[29910]: custom logging function 0x7f90ec575030 registered
selinux=1
udevadm[29910]: selinux=1
calling: info
udevadm[29910]: calling: info
device 0x7f90ec599460 has devpath '/devices/pci0000:00/0000:00:0b.0/host0/target0:0:0/0:0:0:0/block/sda'
udevadm[29910]: device 0x7f90ec599460 has devpath '/devices/pci0000:00/0000:00:0b.0/host0/target0:0:0/0:0:0:0/block/sda'

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/pci0000:00/0000:00:0b.0/host0/target0:0:0/0:0:0:0/block/sda':
    KERNEL=="sda"
    SUBSYSTEM=="block"
    DRIVER==""
    ATTR{range}=="16"
    ATTR{ext_range}=="256"
    ATTR{removable}=="0"
    ATTR{ro}=="0"
    ATTR{size}=="976773168"
    ATTR{alignment_offset}=="0"
    ATTR{discard_alignment}=="0"
    ATTR{capability}=="52"
    ATTR{stat}==" 7302543  1320445 841562942 71451185  6119635 28157362 271395642 272451897        0 51376878 343882883"
    ATTR{inflight}=="       0        0"

device 0x7f90ec59ff90 has devpath '/devices/pci0000:00/0000:00:0b.0/host0/target0:0:0/0:0:0:0'
udevadm[29910]: device 0x7f90ec59ff90 has devpath '/devices/pci0000:00/0000:00:0b.0/host0/target0:0:0/0:0:0:0'
  looking at parent device '/devices/pci0000:00/0000:00:0b.0/host0/target0:0:0/0:0:0:0':
    KERNELS=="0:0:0:0"
    SUBSYSTEMS=="scsi"
    DRIVERS=="sd"
    ATTRS{device_blocked}=="0"
    ATTRS{type}=="0"
    ATTRS{scsi_level}=="6"
    ATTRS{vendor}=="ATA     "
    ATTRS{model}=="TOSHIBA HDWJ105 "
    ATTRS{rev}=="AX00"
    ATTRS{state}=="running"
    ATTRS{timeout}=="30"
    ATTRS{eh_timeout}=="10"
    ATTRS{iocounterbits}=="32"
    ATTRS{iorequest_cnt}=="0xd13eaf"
    ATTRS{iodone_cnt}=="0xcfd529"
    ATTRS{ioerr_cnt}=="0x1e"
    ATTRS{modalias}=="scsi:t-0x00"
    ATTRS{evt_media_change}=="0"
    ATTRS{evt_inquiry_change_reported}=="0"
    ATTRS{evt_capacity_change_reported}=="0"
    ATTRS{evt_soft_threshold_reached}=="0"
    ATTRS{evt_mode_parameter_change_reported}=="0"
    ATTRS{evt_lun_change_reported}=="0"
    ATTRS{dh_state}=="detached"
    ATTRS{queue_depth}=="31"
    ATTRS{queue_ramp_up_period}=="120000"
    ATTRS{queue_type}=="simple"
    ATTRS{unload_heads}=="0"

device 0x7f90ec5a1b20 has devpath '/devices/pci0000:00/0000:00:0b.0/host0/target0:0:0'
udevadm[29910]: device 0x7f90ec5a1b20 has devpath '/devices/pci0000:00/0000:00:0b.0/host0/target0:0:0'
  looking at parent device '/devices/pci0000:00/0000:00:0b.0/host0/target0:0:0':
    KERNELS=="target0:0:0"
    SUBSYSTEMS=="scsi"
    DRIVERS==""

device 0x7f90ec5b3e10 has devpath '/devices/pci0000:00/0000:00:0b.0/host0'
udevadm[29910]: device 0x7f90ec5b3e10 has devpath '/devices/pci0000:00/0000:00:0b.0/host0'
  looking at parent device '/devices/pci0000:00/0000:00:0b.0/host0':
    KERNELS=="host0"
    SUBSYSTEMS=="scsi"
    DRIVERS==""

device 0x7f90ec595fb0 has devpath '/devices/pci0000:00/0000:00:0b.0'
udevadm[29910]: device 0x7f90ec595fb0 has devpath '/devices/pci0000:00/0000:00:0b.0'
  looking at parent device '/devices/pci0000:00/0000:00:0b.0':
    KERNELS=="0000:00:0b.0"
    SUBSYSTEMS=="pci"
    DRIVERS=="ahci"
    ATTRS{vendor}=="0x10de"
    ATTRS{device}=="0x0ab4"
    ATTRS{subsystem_vendor}=="0x1043"
    ATTRS{subsystem_device}=="0x83e2"
    ATTRS{class}=="0x010185"
    ATTRS{irq}=="25"
    ATTRS{local_cpus}=="f"
    ATTRS{local_cpulist}=="0-3"
    ATTRS{modalias}=="pci:v000010DEd00000AB4sv00001043sd000083E2bc01sc01i85"
    ATTRS{numa_node}=="-1"
    ATTRS{enable}=="1"
    ATTRS{broken_parity_status}=="0"
    ATTRS{msi_bus}==""

device 0x7f90ec5a5200 has devpath '/devices/pci0000:00'
udevadm[29910]: device 0x7f90ec5a5200 has devpath '/devices/pci0000:00'
  looking at parent device '/devices/pci0000:00':
    KERNELS=="pci0000:00"
    SUBSYSTEMS==""
    DRIVERS==""

Discorso simile vale per la partizione 1 del disco /dev/sda:

[root@linuxbox ~]# udevadm info -a -n /dev/sda1

il cui output sarà simile a:

custom logging function 0x7ff9331c9030 registered
udevadm[30106]: custom logging function 0x7ff9331c9030 registered
selinux=1
udevadm[30106]: selinux=1
calling: info
udevadm[30106]: calling: info
device 0x7ff9331ed460 has devpath '/devices/pci0000:00/0000:00:0b.0/host0/target0:0:0/0:0:0:0/block/sda/sda1'
udevadm[30106]: device 0x7ff9331ed460 has devpath '/devices/pci0000:00/0000:00:0b.0/host0/target0:0:0/0:0:0:0/block/sda/sda1'

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/pci0000:00/0000:00:0b.0/host0/target0:0:0/0:0:0:0/block/sda/sda1':
    KERNEL=="sda1"
    SUBSYSTEM=="block"
    DRIVER==""
    ATTR{partition}=="1"
    ATTR{start}=="2048"
    ATTR{size}=="1024000"
    ATTR{alignment_offset}=="0"
    ATTR{discard_alignment}=="0"
    ATTR{stat}=="    2379      166   368458    10840       34       49      178     1663        0    11039    12484"
    ATTR{inflight}=="       0        0"

In particolare, utilizzeremo le informazioni riportate come attributi (ATTR) per identificare nel modo più preciso possibile il device/partizione su cui applicare le nostre regole.

Detto ciò, procediamo con la stesura del contenuto relativo al file 10-local.rules, che dovrà essere simile al seguente:

KERNEL=="sd?1", SUBSYSTEM=="block", ATTR{size}=="3915639", NAME="sdd1"
KERNEL=="sd*", SUBSYSTEM=="block", ATTR{size}=="3915776", ATTR{capability}=="53", NAME="sdd"
KERNEL=="sdb", SUBSYSTEM=="block", ATTR{size}=="976773168", ATTR{capability}=="52", NAME="sda"
KERNEL=="sdb1", SUBSYSTEM=="block", ATTR{size}=="1024000", NAME="sda1"
KERNEL=="sdb2", SUBSYSTEM=="block", ATTR{size}=="975747072", NAME="sda2"
KERNEL=="sdc", SUBSYSTEM=="block", ATTR{size}=="1953525168", ATTR{capability}=="52", NAME="sdb"
KERNEL=="sdc1", SUBSYSTEM=="block", ATTR{size}=="1953520002", NAME="sdb1"

La prima direttiva fa in modo che la partizione della memoria flash (con dimensione pari a 3915639 byte) venga rinominata in sdd1. La seconda direttiva, invece, agisce direttamente sul device, rinominandolo in sdd. Da notare che tutti i campi che contengono le condizioni da matchare per l’identificazione del dispositivo/partizione si avvalgono dell’operatore ==, mentre quelle che agiscono su di essi contengono l’operatore di assegnazione, ovvero =. Inoltre, nell’ambito delle suddette direttive, si fa uso dei caratteri speciali ? e *, con il primo che identifica un solo carattere alfanumerico, e * che identifica qualsiasi occorrenza di caratteri alfanumerici (anche nel caso in cui esse siano pari a 0).

Le rimanenti direttive, stilate sulla falsariga della prima, fanno sì che i dischi rigidi vengano rinominati rispettivamente in /dev/sda e /dev/sdb. Ovviamente tale operazione è da intendersi solo ed esclusivamente nel caso in cui, durante la fase di boot della macchina, la memoria flash sia già collegata ad una porta USB della stessa.

Non ci rimane che testare “in place” (e quindi senza reboot) le suddette regole lanciando il comando:

[root@linuxbox ~]# udevadm test /sys/block/sdX

per i device e:

[root@linuxbox ~]# udevadm test /sys/block/sdX/sdXY

per le parizioni, seguito da un:

[root@linuxbox ~]# ls -ilah /dev

per appurare che i dispositivi siano stati effettivamente mappati secondo le nostre necessità.

Per ora è tutto. A presto.

Cisco 877: configurazione del server DHCP integrato

Come ogni router che si rispetti, anche il Cisco 877 può essere configurato a mo’ di server DHCP, seguendo una procedura abbastanza semplice ed intuitiva. In questo post vedremo come tirare giù una configurazione base, comprensiva di una exclusion e di una reservation.

cisco 877Definizione dei pool DHCP e della reservation

Per prima cosa occorre definire i pool di indirizzi IP da cui il nostro server andrà “a pescare” quelli da assegnare alle macchine che ne faranno richiesta. Nello specifico, ho creato 2 pool, uno per gli indirizzi della LAN (pool wifi) ed uno necessario alla reservation (pool pcportatile), ovvero:

ip dhcp pool wifi
   network 192.168.7.0 255.255.255.0
   default-router 192.168.7.1
   dns-server 192.168.7.1
!
ip dhcp pool pcportatile
   host 192.168.7.3 255.255.255.0
   client-identifier 0149.d224.a5d4.0e
   default-router 192.168.7.1
   dns-server 192.168.7.1

Da notare che per il pool pcportatile ho utilizzato la direttiva client-identifier, recante il MAC address del dispositivo oggetto della reservation, nella forma aaaa.bbbb.cccc e con prefisso 01. Nella fattispecie, il MAC address del PC è 49:d2:24:a5:d4:0e, che in notazione Cisco diventa 49d2.24a5.d40e. Aggiungiamo quindi lo 01 come prefisso ed avremo il client-identifier finale, ovvero 0149.d224.a5d4.0e.

Detto ciò, un modo rapido di ricavare il suddetto identificativo consiste nell’utilizzo del seguente comando:

sh ip dhcp binding

il cui output sarà simile al seguente:

Bindings from all pools not associated with VRF:
IP address          Client-ID/              Lease expiration        Type
                    Hardware address/
                    User name
192.168.7.3         0149.d224.a5d4.0e       Infinite                Manual
192.168.7.8         0151.f0d3.fc7d.54       Sep 07 2016 09:15 AM    Automatic

Definizione dell’exclusion

Per ciò che concerne l’exclusion, la sua configurazione consta di un’unica direttiva, ovvero:

ip dhcp excluded-address 192.168.7.2

In tal modo faremo sì che l’IP 192.168.7.2 non rientri nei pool precedentemente definiti e quindi non possa essere assegnato a nessun dispositivo (poichè trattasi di un indirizzo statico associato ad una stampante).

Il post termina qui, alla prossima.

Hardening del servizio Remote Desktop su Windows Server 2008 R2

Uno dei target preferiti dagli script kiddie è il servizio Remote Desktop di Windows. Vi assicuro che, giornalmente, i tentativi di bruteforcing contro di esso possono superare (e anche di molto ) il centinaio. Proprio per questo motivo ho deciso di mettere in atto tutta una serie di accorgimenti in grado di limitare questa tipologia di attacco, basandomi principalmente su due strategie:

1) quella proattiva, grazie alla quale è possibile bloccare l’IP sorgente dei tentativi di intrusione;

2) quella passiva, basata sul monitoraggio in tempo reale degli eventi di Windows, con la generazione di alert ad hoc da parte dell’NMS (Nagios) nel caso in cui vi siano episodi di logon falliti.

user-enumeration-mediante-nmap-L-gnHMmv

Entrambe le suddette strategie si applicano a tutti i servizi attivi sulla macchina remota e che prevedono autenticazione (FTP, HTTP, ecc.), incluso, ovviamente, il Remote Desktop.

Ingredienti

I software necessari per l’hardening del servizio Remote Desktop sono i seguenti:

1) Il tool IPBan (che potete scaricare gratuitamente da qui), il quale è in grado di bannare l’IP sorgente degli attacchi dopo un determinato numero di tentativi di accesso falliti;

2) Il tool NSClient++ (anch’esso gratuito, lo si può scaricare da qui), nella versione 0.4.1.105 per architettura a 64 bit (la più recente tra quelle che non hanno problemi con il matching dei filtri sul monitoraggio degli eventi di Windows).

Lato NMS, invece, è necessario installare e configurare NSCA server, il quale rimarrà in ascolto sulla porta TCP 5667 nell’attesa che NSClient++ gli inoltri qualche evento (grazie all’applicativo NSCAClient). Una volta ricevuto l’evento, esso verrà dato in pasto a Nagios che, grazie ad un servizio di tipo passivo, genererà un allarme specifico in grado di ragguagliarci sul tentativo di accesso fallito.

Installazione e configurazione di IPBan

Prima di installare il suddetto tool è necessario configurare la macchina su cui è attivo Remote Desktop, operando mediante l’utility secpol.msc (Local Policy -> Security Options) ed impostando i seguenti parametri:

1) Network security: LAN Manager authentication level da settare su Send NTLMv2 response only. Refuse LM & NTLM

2) Network security: Restrict NTLM: Audit Incoming NTLM Traffic da impostare su Enable auditing for all accounts

3) Network security: Restrict NTLM: Incoming NTLM traffic da impostare su Deny all accounts

Inoltre, è necessario settare su Allow connections from computers running any version of Remote Desktop (less secure) il tab Remote delle impostazioni di sistema (vedi lo screenshot sottostante).

RDP

Tali direttive sono necessarie affinchè sul log degli eventi di Windows venga salvato l’indirizzo IP sorgente dell’attacco, in modo tale che IPBan possa riconoscerlo e quindi bloccarlo.

Una volta fatto ciò, estraiamo il contenuto del file IPBan.zip all’interno di C:\IPBan e lanciamo il prompt dei comandi con privilegi di amministratore, per poi digitare il seguente comando:

C:\IPBan> sc create IPBAN type= own start= auto binPath= C\:IPBan\ipban.exe DisplayName= IPBAN

il quale ci permetterà di creare un servizio apposito basato sul tool appena scaricato.

Inoltre, editiamo il suo file di configurazione (IPBan.exe.config), portando a 3 il numero massimo di tentativi di logon falliti prima del ban (tale valore, di default, è pari 5):

<!-- Number of failed audits in the event viewer before banning the ip address -->
<add key="FailedLoginAttemptsBeforeBan" value="3" />

Infine avviamo il servizio precedentemente creato:

C:\Users\Administrator>net start IPBAN

Installazione e configurazione di NSClient++

Come già detto in precedenza, il suddetto software ci consente di monitorare in tempo reale gli eventi di Windows, filtrandoli in modo opportuno.

Nel mio caso ho scelto di installare solo ed esclusivamente i plugin più comuni ed NSCAClient, il quale interagirà col nostro NMS.

Di seguito riporto uno screenshot esplicativo:

nsclient

Una volta completata l’installazione si può procedere con la configurazione di NSClient++, editando il file nsclient.ini presente nella directory C:\Program Files\NSclient++ ed il cui contenuto dovrebbe essere simile al seguente:

 # If you want to fill this file with all avalible options run the following command:
#   nscp settings --generate --add-defaults --load-all
# If you want to activate a module and bring in all its options use:
#   nscp settings --activate-module <MODULE NAME> --add-defaults
# For details run: nscp settings --help

; Undocumented section
[/settings/default]

; Undocumented key
password = vostrapassword

; Undocumented key
allowed hosts = 127.0.0.1,::1

; Undocumented section
[/modules]

;moduli da abilitare
CheckEventLog=1
NSCAClient = 1

[/settings/eventlog/real-time]
enabled=1
debug=1
log=Application,Security
destination=NSCA
startup age=30m

[/settings/eventlog/real-time/filters/logon-failed]
filter= id = 4625 
severity= WARNING

[/settings/NSCA/client]
hostname=Server-Windows-RDP

[/settings/NSCA/client/targets/default]
address=nsca://indirizzoNMS:5667
encryption=3des
password=vostrapassword

In particolare, nella sezione [/modules] vengono specificati i moduli di NSClient++ da caricare, ovvero CheckEventLog ed NSCAClient (il primo serve per il monitoraggio in tempo reale degli eventi ed il secondo per l’inoltro degli stessi all’NMS).

Nella sezione [/settings/eventlog/real-time] vengono definiti i parametri generali per il monitoraggio degli eventi, tra cui i log di cui tenere traccia (Application e Security) ed a chi devono essere inoltrati (destination=NSCA). Inoltre, solo durante una prima fase di testing, è opportuno abilitare la modalità debug (debug=1), soprattutto per verificare il corretto funzionamento dei filtri da noi definiti.

Nella sezione [/settings/eventlog/real-time/filters/logon-failed] (dove logon-failed non è altro che il nome del servizio associato all’host da monitorare e presente nello specifico file di configurazione di Nagios) viene indicato il filtro da utilizzare per l’identificazione dell’evento (filter=ID = 4625, ovvero logon failure) e la severity dell’alert generato da Nagios (severity= WARNING).

In [/settings/NSCA/client] viene definito l’hostname del server da monitorare (hostname=Server-Windows-RDP), il quale deve coincidere con quello definito nel file di configurazione di Nagios.

Infine, in [/settings/NSCA/client/targets/default] vengono indicati i parametri di connessione al nostro NMS (su cui è attivo il server NSCA), quali URL (address=nsca://indirizzoNMS:5667), modalità di cicfratura simmetrica (encryption=3des) e password (password=vostrapassword). Da notare che, inizialmente, avevo scelto come metodo di cifratura AES256 lato client e RIJNDAEL-256 lato server, ma l’autenticazione falliva costantemente, ragion per cui ho dovuto optare per il triplo des.

Avviamo quindi il servizio nscp mediante il comando:

C:\Users\Administrator>net start nscp

e passiamo alla configurazione dell’NMS.

Installazione e configurazione di NSCA Server

La macchina su cui è attivo Nagios è una CentOS 6.4 a 64 bit ergo, per installare NSCA Server (nella sua ultima versione stabile, ovvero la 2.7.2), è sufficiente lanciare il comando:

[root@nms ~]# yum install nagios-nsca

Una volta installato, occorre configurarlo edintando il file /etc/nagios/nsca.cnf, il cui contenuto dovrà essere simile al seguente:

pid_file=/var/run/nsca.pid

server_port=5667

nsca_user=nagios

nsca_group=nagios

debug=1

command_file=/var/spool/nagios/cmd/nagios.cmd

alternate_dump_file=/var/spool/nagios/nsca.dump

aggregate_writes=0

append_to_file=0

max_packet_age=30

password=vostrapassword

decryption_method=3

Dove il decryption method 3 non è altro che il triplo des. Ovviamente, affinchè client e server possano “capirsi”, è necessario che decryption method e password coincidano su entrambi i fronti.

Infine, avviamo il servizio in questione digitando:

[root@nms ~]# service nsca start

Configurazione di Nagios

L’ultimo step consiste nella configurazione di un servizio di tipo passivo relativo all’host monitorato da Nagios. Editiamo quindi il file /etc/nagios/object/Server-Windows-RDP.cfg aggiungendo il servizio logon-failed, il quale avrà la seguente struttura:

define service{
        use                             local-service
        host_name                       Server-Windows-RDP
        service_descripion             logon-failed
        check_command                   check_passive
        passive_checks_enabled          1
        active_checks_enabled           0
        max_check_attempts              1
        is_volatile                     1
        check_freshness                 1
        freshness_threshold             600
        flap_detection_enabled          0
        }

Ricarichiamo la configurazione del nostro NMS per rendere effettive le suddette modifiche:

[root@nms ~]# service nagios reload

ed abbiamo finito.

Considerazioni finali

Prima di chiedere il post occorre fare qualche precisazione:

1) Non sono un fan di NSCP,  sia perchè vi sono continui cambi di sintassi tra minor release (soprattutto per ciò che concerne la definizione dei filtri) che per la presenza di qualche baco più o meno grave. Ad esempio, ho notato che nella versione 0.5.0, l’inserimento di record all’interno del log degli eventi di Windows (creati ad hoc mediante il comando nscp eventlog insert) non funziona (come alternativa ho dovuto utilizzare l’applet write-eventlog di PowerShell).

2) E’ necessario che la versione del client NSCA sia identica a quella del server, pena l’impossibilità di ricevere gli eventi (CRC error).

3) Sia lato client che lato server il payload massimo degli eventi è pari a 512 byte (limite superato abbondatemente nella versione unstable 2.9.1 e portato a 4096 byte). Ciò comporta la possibile perdita di parte dell’output (ovvero tutto ciò che eccede i 512 byte). Esiste comunque una direttiva (lato client) in grado di innalzare il suddetto limite (payload length), ma per farla funzionare è necessario modificare il contenuto della libreria common.h prima della compilazione da sorgente. Quest’ultima operazione risulta essere abbastanza semplice se si ha a che fare con i sorgenti *NIX (#define MAX_PLUGINOUTPUT_LENGTH 4096) ma molto più tediosa nel caso dei sorgenti Windows.

Il post termina qui.

Alla prossima.

NRPE_NT e Nagios: script PowerShell per il controllo dell’uptime su Windows Server 2008 R2

Tenere sotto controllo l’uptime dei nostri server è molto importante, soprattutto se si ha a che fare con macchine in produzione. Per ciò che concerne i sistemi operativi di casa Microsoft (sia client che server), esiste un comando che può tornarci molto utile allo scopo, ovvero:

net stats srv

il quale, basandosi sul servizio Server di Windows, colleziona e fornisce tutta una serie di informazioni associate alla nostra macchina, tra cui, per l’appunto, il suo tempo di attività:

Statistics since 7/11/2016 9:21:08 AM

powershellAffinchè il suddetto task possa essere effettuato in automatico dal nostro NMS (Nagios), è necessario utilizzare uno scrip (get_uptime.ps1, creato da me allo scopo) da integrare al servizio NRPE_NT. Per ragioni di semplicità e comodità ho deciso di avvalermi di Windows PowerShell per la stesura dello stesso, il cui contenuto è il seguente:

$critical = $Args[0]
$warning = $Args[1]

if ($warning -and $critical) #both variable are defined and not empty
{
    if ($critical -lt $warning)
    {
        $os = Get-WmiObject win32_operatingsystem
        $uptime = (Get-Date) - ($os.ConvertToDateTime($os.lastbootuptime))
        $minutes_to_seconds = $Uptime.Minutes*60
        $hours_to_seconds = $Uptime.Hours*3600
        $days_to_seconds = $Uptime.Days*86400
        $uptime_in_seconds = $minutes_to_seconds + $hours_to_seconds + $days_to_seconds
        if ($uptime_in_seconds -gt $critical -and $uptime_in_seconds -gt $warning)
        {
            $Display = "OK: System Uptime is " + $Uptime.Days + " days, " + $Uptime.Hours + " hours, " + $Uptime.Minutes + " minutes"
            Write-Output $Display
            exit 0
        }
        elseif ($uptime_in_seconds -gt $critical -and $uptime_in_seconds -le $warning)
        {
            $Display = "WARNING: System Uptime is " + $Uptime.Days + " days, " + $Uptime.Hours + " hours, " + $Uptime.Minutes + " minutes"
            Write-Output $Display
            exit 1
        }
        else
        {
            $Display = "CRITICAL: System Uptime is " + $Uptime.Days + " days, " + $Uptime.Hours + " hours, " + $Uptime.Minutes + " minutes"
            Write-Output $Display
            exit 2
        }
    }
    else
    {
        $Usage = "Usage: .\get_uptime.ps1 <critical threshold in seconds> <warning threshold in seconds>"
        $Error1 = "Warning threshold must be greater then the critical one"
        Write-Output $Usage
        Write-Output $Error1
        exit 3
    }
}
else
{
    $Usage = "Usage: .\get_uptime.ps1 <critical threshold in seconds> <warning threshold in seconds>"
    $Error2 = "Warning threshold and critical threshold must be defined"
    Write-Output $Usage
    Write-Output $Error2
    exit 3
}

In soldoni, il suddetto scrip riceve due argomenti da linea di comando, ovvero la soglia critica e quella di warning, espresse entrambe in secondi. Ovviamente, trattandosi di tempo di attività, la prima deve essere strettamente minore della seconda.

Configurazione di NRPE_NT

Salviamo tale scrip all’interno della directory C:\nrpe\Plugins\V2 e successivamente editiamo il file C:\nrpe\Plugins\V2\V2_nrpe_commands.cfg, aggiungendo la seguente direttiva:

# =================================
# Windows System Uptime checks
# =================================

command[get_system_uptime]=cmd.exe /c echo C:\nrpe\Plugins\V2\get_uptime.ps1 "$ARG1$" "$ARG2$" | powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -command -

In particolare, stiamo definendo il comando get_system_uptime che si avvarrà di get_uptime.ps1 per l’individuazione del tempo di attività.

Occorre precisare che l’esecuzione dello scrip non può avvenire richiamando direttamente l’eseguibile powershell.exe, ma deve prima passare per cmd.exe (il cui output, mediante pipe, viene dato in pasto a PowerShell grazie alla direttiva -command -, dove il - finale rappresenta “tutto ciò che proviene dal pipe”). Inoltre, si rende indispensabile bypassare l’executionpolicy di PowerShell, consentendo ad NRPE_NT di lanciare get_uptime.ps1 senza restrizioni.

Infine, riavviamo NRPE_NT per rendere effettive le suddette modifiche:

C:\Users\Administrator> net stop nrpe_nt
C:\Users\Administrator> net start nrpe_nt

Configurazione di Nagios

Per prima cosa è necessario creare un apposito comando all’interno del file /etc/nagios/object/commands.cfg:

# nagios-Windows-uptime check command definition

define command {
        command_name    check_Windows_uptime
        command_line    /usr/lib64/nagios/plugins/check_nrpe -H $HOSTADDRESS$ -t $ARG1$ -c get_system_uptime -a $ARG2$ $ARG3$
        }

Successivamente, all’interno del file che rappresenta l’host da monitorare, è necessario aggiungere un servizio specifico che si avvale del suddetto comando:

define service{
        use                             generic-service         ; Name of service template to use
        host_name                       Windows-Server
        service_descripion             query Windows System Uptime for Microsoft Windows Machine
        check_command                   check_Windows_uptime!30!60!900
        }

Ricarichiamo la configurazione di Nagios:

[root@linuxbox ~]# service nagios reload

ed abbiamo finito.

Alla prossima.

Windows Server 2008 R2: installare e configurare ClamD come servizio

Scenario

Macchina Windows Server 2008 R2 adibito a server di posta (inbound/outbound) mediante hMailServer. Su quest’ultimo si vuole utilizzare ClamD (eseguibile appartenente alla suite ClamAV) per la scansione degli allegati (poichè più stabile e performante di ClamWin).

clamavIn questo post vedremo come installare il suddetto applicativo sottoforma di servizio. Inoltre, tramite il task scheduler di Windows, utilizzeremo uno scrip custom (da me creato) per il download e l’installazione degli aggiornamenti.

Download e configurazione di ClamAV

E’ possibile scaricare il software il questione da qui (è gratis). La versione da me utilizzata è la Win64 (poichè il SO è a 64 bit).

Una volta completato il download, estraiamo il contenuto del file *.zip (ho scelto questa tipologia di file anzichè il *.msi per avere un maggiore controllo durante la fase di installazione e configurazione) e rinominiamo la dir in ClamAV. Infine, copiamola all’interno di C:\Program Files\.

Posizioniamoci dunque all’interno della directory C:\Program Files\ClamAV e creiamo la cartella database (in cui verranno salvate le firme aggiornate) ed i file clamd.conf:

##
## Example config file for the Clam AV daemon
## Please read the clamd.conf(5) manual before editing this file.
##

# Comment or remove the line below.
#Example

# Uncomment this option to enable logging.
# LogFile must be writable for the user running daemon.
# A full path is required.
# Default: disabled
LogFile C:\Program Files\ClamAV\clamd.log

# By default the log file is locked for writing - the lock protects against
# running clamd multiple times (if want to run another clamd, please
# copy the configuration file, change the LogFile variable, and run
# the daemon with --config-file option).
# This option disables log file locking.
# Default: no
#LogFileUnlock yes

# Maximum size of the log file.
# Value of 0 disables the limit.
# You may use 'M' or 'm' for megabytes (1M = 1m = 1048576 bytes)
# and 'K' or 'k' for kilobytes (1K = 1k = 1024 bytes). To specify the size
# in bytes just don't use modifiers. If LogFileMaxSize is enabled, log
# rotation (the LogRotate option) will always be enabled.
# Default: 1M
LogFileMaxSize 2M

# Log time with each message.
# Default: no
LogTime yes

# Also log clean files. Useful in debugging but drastically increases the
# log size.
# Default: no
LogClean yes

# Use system logger (can work together with LogFile).
# Default: no
#LogSyslog yes

# Specify the type of syslog messages - please refer to 'man syslog'
# for facility names.
# Default: LOG_LOCAL6
#LogFacility LOG_MAIL

# Enable verbose logging.
# Default: no
LogVerbose yes

# Enable log rotation. Always enabled when LogFileMaxSize is enabled.
# Default: no
#LogRotate yes

# Log additional information about the infected file, such as its
# size and hash, together with the virus name.
ExtendedDetectionInfo yes

# This option allows you to save a process identifier of the listening
# daemon (main thread).
# Default: disabled
#PidFile /var/run/clamd.pid

# Optional path to the global temporary directory.
# Default: system specific (usually /tmp or /var/tmp).
#TemporaryDirectory /var/tmp

# Path to the database directory.
# Default: hardcoded (depends on installation options)
#DatabaseDirectory /var/lib/clamav

# Only load the official signatures published by the ClamAV project.
# Default: no
#OfficialDatabaseOnly no

# The daemon can work in local mode, network mode or both. 
# Due to security reasons we recommend the local mode.

# Path to a local socket file the daemon will listen on.
# Default: disabled (must be specified by a user)
#LocalSocket /tmp/clamd.socket

# Sets the group ownership on the unix socket.
# Default: disabled (the primary group of the user running clamd)
#LocalSocketGroup virusgroup

# Sets the permissions on the unix socket to the specified mode.
# Default: disabled (socket is world accessible)
#LocalSocketMode 660

# Remove stale socket after unclean shutdown.
# Default: yes
#FixStaleSocket yes

# TCP port address.
# Default: no
TCPSocket 3310

# TCP address.
# By default we bind to INADDR_ANY, probably not wise.
# Enable the following to provide some degree of protection
# from the outside world. This option can be specified multiple
# times if you want to listen on multiple IPs. IPv6 is now supported.
# Default: no
TCPAddr 127.0.0.1

# Maximum length the queue of pending connections may grow to.
# Default: 200
#MaxConnectionQueueLength 30

# Clamd uses FTP-like protocol to receive data from remote clients.
# If you are using clamav-milter to balance load between remote clamd daemons
# on firewall servers you may need to tune the options below.

# Close the connection when the data size limit is exceeded.
# The value should match your MTA's limit for a maximum attachment size.
# Default: 25M
#StreamMaxLength 10M

# Limit port range.
# Default: 1024
#StreamMinPort 30000
# Default: 2048
#StreamMaxPort 32000

# Maximum number of threads running at the same time.
# Default: 10
#MaxThreads 20

# Waiting for data from a client socket will timeout after this time (seconds).
# Default: 120
#ReadTimeout 300

# This option specifies the time (in seconds) after which clamd should
# timeout if a client doesn't provide any initial command after connecting.
# Default: 5
#CommandReadTimeout 5

# This option specifies how long to wait (in miliseconds) if the send buffer is full.
# Keep this value low to prevent clamd hanging
#
# Default: 500
#SendBufTimeout 200

# Maximum number of queued items (including those being processed by MaxThreads threads)
# It is recommended to have this value at least twice MaxThreads if possible.
# WARNING: you shouldn't increase this too much to avoid running out  of file descripors,
# the following condition should hold:
# MaxThreads*MaxRecursion + (MaxQueue - MaxThreads) + 6< RLIMIT_NOFILE (usual max is 1024)
#
# Default: 100
#MaxQueue 200

# Waiting for a new job will timeout after this time (seconds).
# Default: 30
#IdleTimeout 60

# Don't scan files and directories matching regex
# This directive can be used multiple times
# Default: scan all
#ExcludePath ^/proc/
#ExcludePath ^/sys/

# Maximum depth directories are scanned at.
# Default: 15
#MaxDirectoryRecursion 20

# Follow directory symlinks.
# Default: no
#FollowDirectorySymlinks yes

# Follow regular file symlinks.
# Default: no
#FollowFileSymlinks yes

# Scan files and directories on other filesystems.
# Default: yes
#CrossFilesystems yes

# Perform a database check.
# Default: 600 (10 min)
#SelfCheck 600

# Execute a command when virus is found. In the command string %v will
# be replaced with the virus name.
# Default: no
#VirusEvent /usr/local/bin/send_sms 123456789 "VIRUS ALERT: %v"

# Run as another user (clamd must be started by root for this option to work)
# Default: don't drop privileges
#User clamav

# Initialize supplementary group access (clamd must be started by root).
# Default: no
#AllowSupplementaryGroups no

# Stop daemon when libclamav reports out of memory condition.
#ExitOnOOM yes

# Don't fork into background.
# Default: no
#Foreground yes

# Enable debug messages in libclamav.
# Default: no
#Debug yes

# Do not remove temporary files (for debug purposes).
# Default: no
#LeaveTemporaryFiles yes

# Permit use of the ALLMATCHSCAN command. If set to no, clamd will reject
# any ALLMATCHSCAN command as invalid.
# Default: yes
#AllowAllMatchScan no

# Detect Possibly Unwanted Applications.
# Default: no
#DetectPUA yes

# Exclude a specific PUA category. This directive can be used multiple times.
# See https://github.com/vrtadmin/clamav-faq/blob/master/faq/faq-pua.md for 
# the complete list of PUA categories.
# Default: Load all categories (if DetectPUA is activated)
#ExcludePUA NetTool
#ExcludePUA PWTool

# Only include a specific PUA category. This directive can be used multiple
# times.
# Default: Load all categories (if DetectPUA is activated)
#IncludePUA Spy
#IncludePUA Scanner
#IncludePUA RAT

# In some cases (eg. complex malware, exploits in graphic files, and others),
# ClamAV uses special algorithms to provide accurate detection. This option
# controls the algorithmic detection.
# Default: yes
#AlgorithmicDetection yes

# This option causes memory or nested map scans to dump the content to disk.
# If you turn on this option, more data is written to disk and is available
# when the LeaveTemporaryFiles option is enabled.
#ForceToDisk yes

# This option allows you to disable the caching feature of the engine. By
# default, the engine will store an MD5 in a cache of any files that are
# not flagged as virus or that hit limits checks. Disabling the cache will
# have a negative performance impact on large scans.
# Default: no
#DisableCache yes

##
## Executable files
##

# PE stands for Portable Executable - it's an executable file format used
# in all 32 and 64-bit versions of Windows operating systems. This option allows
# ClamAV to perform a deeper analysis of executable files and it's also
# required for decompression of popular executable packers such as UPX, FSG,
# and Petite. If you turn off this option, the original files will still be
# scanned, but without additional processing.
# Default: yes
#ScanPE yes

# Certain PE files contain an authenticode signature. By default, we check
# the signature chain in the PE file against a database of trusted and
# revoked certificates if the file being scanned is marked as a virus.
# If any certificate in the chain validates against any trusted root, but
# does not match any revoked certificate, the file is marked as whitelisted.
# If the file does match a revoked certificate, the file is marked as virus.
# The following setting completely turns off authenticode verification.
# Default: no
#DisableCertCheck yes

# Executable and Linking Format is a standard format for UN*X executables.
# This option allows you to control the scanning of ELF files.
# If you turn off this option, the original files will still be scanned, but
# without additional processing.
# Default: yes
#ScanELF yes

# With this option clamav will try to detect broken executables (both PE and
# ELF) and mark them as Broken.Executable.
# Default: no
#DetectBrokenExecutables yes

##
## Documents
##

# This option enables scanning of OLE2 files, such as Microsoft Office
# documents and .msi files.
# If you turn off this option, the original files will still be scanned, but
# without additional processing.
# Default: yes
#ScanOLE2 yes

# With this option enabled OLE2 files with VBA macros, which were not
# detected by signatures will be marked as "Heuristics.OLE2.ContainsMacros".
# Default: no
#OLE2BlockMacros no

# This option enables scanning within PDF files.
# If you turn off this option, the original files will still be scanned, but
# without decoding and additional processing.
# Default: yes
#ScanPDF yes

# This option enables scanning within SWF files.
# If you turn off this option, the original files will still be scanned, but
# without decoding and additional processing.
# Default: yes
#ScanSWF yes

##
## Mail files
##

# Enable internal e-mail scanner.
# If you turn off this option, the original files will still be scanned, but
# without parsing individual messages/attachments.
# Default: yes
#ScanMail yes

# Scan RFC1341 messages split over many emails.
# You will need to periodically clean up $TemporaryDirectory/clamav-partial directory.
# WARNING: This option may open your system to a DoS attack.
#       Never use it on loaded servers.
# Default: no
#ScanPartialMessages yes

# With this option enabled ClamAV will try to detect phishing attempts by using
# signatures.
# Default: yes
#PhishingSignatures yes

# Scan URLs found in mails for phishing attempts using heuristics.
# Default: yes
#PhishingScanURLs yes

# Always block SSL mismatches in URLs, even if the URL isn't in the database.
# This can lead to false positives.
#
# Default: no
#PhishingAlwaysBlockSSLMismatch no

# Always block cloaked URLs, even if URL isn't in database.
# This can lead to false positives.
#
# Default: no
#PhishingAlwaysBlockCloak no

# Detect partition intersections in raw disk images using heuristics.
# Default: no
#PartitionIntersection no

# Allow heuristic match to take precedence.
# When enabled, if a heuristic scan (such as phishingScan) detects
# a possible virus/phish it will stop scan immediately. Recommended, saves CPU
# scan-time.
# When disabled, virus/phish detected by heuristic scans will be reported only at
# the end of a scan. If an archive contains both a heuristically detected
# virus/phish, and a real malware, the real malware will be reported
#
# Keep this disabled if you intend to handle "*.Heuristics.*" viruses 
# differently from "real" malware.
# If a non-heuristically-detected virus (signature-based) is found first, 
# the scan is interrupted immediately, regardless of this config option.
#
# Default: no
#HeuristicScanPrecedence yes

##
## Data Loss Prevention (DLP)
##

# Enable the DLP module
# Default: No
#StructuredDataDetection yes

# This option sets the lowest number of Credit Card numbers found in a file
# to generate a detect.
# Default: 3
#StructuredMinCreditCardCount 5

# This option sets the lowest number of Social Security Numbers found
# in a file to generate a detect.
# Default: 3
#StructuredMinSSNCount 5

# With this option enabled the DLP module will search for valid
# SSNs formatted as xxx-yy-zzzz
# Default: yes
#StructuredSSNFormatNormal yes

# With this option enabled the DLP module will search for valid
# SSNs formatted as xxxyyzzzz
# Default: no
#StructuredSSNFormatStripped yes

##
## HTML
##

# Perform HTML normalisation and decryption of MS scrip Encoder code.
# Default: yes
# If you turn off this option, the original files will still be scanned, but
# without additional processing.
#ScanHTML yes

##
## Archives
##

# ClamAV can scan within archives and compressed files.
# If you turn off this option, the original files will still be scanned, but
# without unpacking and additional processing.
# Default: yes
#ScanArchive yes

# Mark encrypted archives as viruses (Encrypted.Zip, Encrypted.RAR).
# Default: no
#ArchiveBlockEncrypted no

##
## Limits
##

# The options below protect your system against Denial of Service attacks
# using archive bombs.

# This option sets the maximum amount of data to be scanned for each input file.
# Archives and other containers are recursively extracted and scanned up to this
# value.
# Value of 0 disables the limit
# Note: disabling this limit or setting it too high may result in severe damage
# to the system.
# Default: 100M
#MaxScanSize 150M

# Files larger than this limit won't be scanned. Affects the input file itself
# as well as files contained inside it (when the input file is an archive, a
# document or some other kind of container).
# Value of 0 disables the limit.
# Note: disabling this limit or setting it too high may result in severe damage
# to the system.
# Default: 25M
#MaxFileSize 30M

# Nested archives are scanned recursively, e.g. if a Zip archive contains a RAR
# file, all files within it will also be scanned. This options specifies how
# deeply the process should be continued.
# Note: setting this limit too high may result in severe damage to the system.
# Default: 16
#MaxRecursion 10

# Number of files to be scanned within an archive, a document, or any other
# container file.
# Value of 0 disables the limit.
# Note: disabling this limit or setting it too high may result in severe damage
# to the system.
# Default: 10000
#MaxFiles 15000

# Maximum size of a file to check for embedded PE. Files larger than this value
# will skip the additional analysis step.
# Note: disabling this limit or setting it too high may result in severe damage
# to the system.
# Default: 10M
#MaxEmbeddedPE 10M

# Maximum size of a HTML file to normalize. HTML files larger than this value
# will not be normalized or scanned.
# Note: disabling this limit or setting it too high may result in severe damage
# to the system.
# Default: 10M
#MaxHTMLNormalize 10M

# Maximum size of a normalized HTML file to scan. HTML files larger than this
# value after normalization will not be scanned.
# Note: disabling this limit or setting it too high may result in severe damage
# to the system.
# Default: 2M
#MaxHTMLNoTags 2M

# Maximum size of a scrip file to normalize. scrip content larger than this
# value will not be normalized or scanned.
# Note: disabling this limit or setting it too high may result in severe damage
# to the system.
# Default: 5M
#MaxscripNormalize 5M

# Maximum size of a ZIP file to reanalyze type recognition. ZIP files larger
# than this value will skip the step to potentially reanalyze as PE.
# Note: disabling this limit or setting it too high may result in severe damage
# to the system.
# Default: 1M
#MaxZipTypeRcg 1M

# This option sets the maximum number of partitions of a raw disk image to be scanned.
# Raw disk images with more partitions than this value will have up to the value number
# partitions scanned. Negative values are not allowed.
# Note: setting this limit too high may result in severe damage or impact performance.
# Default: 50
#MaxPartitions 128

# This option sets the maximum number of icons within a PE to be scanned.
# PE files with more icons than this value will have up to the value number icons scanned.
# Negative values are not allowed.
# WARNING: setting this limit too high may result in severe damage or impact performance.
# Default: 100
#MaxIconsPE 200

# This option sets the maximum calls to the PCRE match function during an instance of regex matching.
# Instances using more than this limit will be terminated and alert the user but the scan will continue.
# For more information on match_limit, see the PCRE documentation.
# Negative values are not allowed.
# WARNING: setting this limit too high may severely impact performance.
# Default: 10000
#PCREMatchLimit 20000

# This option sets the maximum recursive calls to the PCRE match function during an instance of regex matching.
# Instances using more than this limit will be terminated and alert the user but the scan will continue.
# For more information on match_limit_recursion, see the PCRE documentation.
# Negative values are not allowed and values > PCREMatchLimit are superfluous.
# WARNING: setting this limit too high may severely impact performance.
# Default: 5000
#PCRERecMatchLimit 10000

# This option sets the maximum filesize for which PCRE subsigs will be executed.
# Files exceeding this limit will not have PCRE subsigs executed unless a subsig is encompassed to a smaller buffer.
# Negative values are not allowed.
# Setting this value to zero disables the limit.
# WARNING: setting this limit too high or disabling it may severely impact performance.
# Default: 25M
#PCREMaxFileSize 100M

##
## On-access Scan Settings
##

# Enable on-access scanning. Currently, this is supported via fanotify.
# Clamuko/Dazuko support has been deprecated.
# Default: no
#ScanOnAccess yes

# Set the  mount point to be scanned. The mount point specified, or the mount point 
# containing the specified directory will be watched. If any directories are specified, 
# this option will preempt the DDD system. This will notify only. It can be used multiple times.
# (On-access scan only)
# Default: disabled
#OnAccessMountPath /
#OnAccessMountPath /home/user

# Don't scan files larger than OnAccessMaxFileSize
# Value of 0 disables the limit.
# Default: 5M
#OnAccessMaxFileSize 10M

# Set the include paths (all files inside them will be scanned). You can have
# multiple OnAccessIncludePath directives but each directory must be added
# in a separate line. (On-access scan only)
# Default: disabled
#OnAccessIncludePath /home
#OnAccessIncludePath /students

# Set the exclude paths. All subdirectories are also excluded.
# (On-access scan only)
# Default: disabled
#OnAccessExcludePath /home/bofh

# With this option you can whitelist specific UIDs. Processes with these UIDs
# will be able to access all files.
# This option can be used multiple times (one per line).
# Default: disabled
#OnAccessExcludeUID 0

# Toggles dynamic directory determination. Allows for recursively watching include paths.
# (On-access scan only)
# Default: no
#OnAccessDisableDDD yes

# Modifies fanotify blocking behaviour when handling permission events.
# If off, fanotify will only notify if the file scanned is a virus,
# and not perform any blocking.
# (On-access scan only)
# Default: no
#OnAccessPrevention yes

# Toggles extra scanning and notifications when a file or directory is created or moved.
# Requires the  DDD system to kick-off extra scans.
# (On-access scan only)
# Default: no
#OnAccessExtraScanning yes

##
## Bytecode
##

# With this option enabled ClamAV will load bytecode from the database. 
# It is highly recommended you keep this option on, otherwise you'll miss detections for many new viruses.
# Default: yes
#Bytecode yes

# Set bytecode security level.
# Possible values:
#       None - no security at all, meant for debugging. DO NOT USE THIS ON PRODUCTION SYSTEMS
#         This value is only available if clamav was built with --enable-debug!
#       TrustSigned - trust bytecode loaded from signed .c[lv]d files,
#                insert runtime safety checks for bytecode loaded from other sources
#       Paranoid - don't trust any bytecode, insert runtime checks for all
# Recommended: TrustSigned, because bytecode in .cvd files already has these checks
# Note that by default only signed bytecode is loaded, currently you can only
# load unsigned bytecode in --enable-debug mode.
#
# Default: TrustSigned
#BytecodeSecurity TrustSigned

# Set bytecode timeout in miliseconds.
# 
# Default: 5000
# BytecodeTimeout 1000

##
## Statistics gathering and submitting
##

# Enable statistical reporting.
# Default: no
#StatsEnabled yes

# Disable submission of individual PE sections for files flagged as malware.
# Default: no
#StatsPEDisabled yes

# HostID in the form of an UUID to use when submitting statistical information.
# Default: auto
#StatsHostID auto

# Time in seconds to wait for the stats server to come back with a response
# Default: 10
#StatsTimeout 10

e freshclam.conf:

##
## Example config file for freshclam
## Please read the freshclam.conf(5) manual before editing this file.
##

# Comment or remove the line below.
#Example

# Path to the database directory.
# WARNING: It must match clamd.conf's directive!
# Default: hardcoded (depends on installation options)
#DatabaseDirectory /var/lib/clamav

# Path to the log file (make sure it has proper permissions)
# Default: disabled
UpdateLogFile C:\Program Files (x86)\ClamAV\freshclam.log

# Maximum size of the log file.
# Value of 0 disables the limit.
# You may use 'M' or 'm' for megabytes (1M = 1m = 1048576 bytes)
# and 'K' or 'k' for kilobytes (1K = 1k = 1024 bytes).
# in bytes just don't use modifiers. If LogFileMaxSize is enabled,
# log rotation (the LogRotate option) will always be enabled.
# Default: 1M
#LogFileMaxSize 2M

# Log time with each message.
# Default: no
#LogTime yes

# Enable verbose logging.
# Default: no
#LogVerbose yes

# Use system logger (can work together with UpdateLogFile).
# Default: no
#LogSyslog yes

# Specify the type of syslog messages - please refer to 'man syslog'
# for facility names.
# Default: LOG_LOCAL6
#LogFacility LOG_MAIL

# Enable log rotation. Always enabled when LogFileMaxSize is enabled.
# Default: no
#LogRotate yes

# This option allows you to save the process identifier of the daemon
# Default: disabled
#PidFile /var/run/freshclam.pid

# By default when started freshclam drops privileges and switches to the
# "clamav" user. This directive allows you to change the database owner.
# Default: clamav (may depend on installation options)
#DatabaseOwner clamav

# Initialize supplementary group access (freshclam must be started by root).
# Default: no
#AllowSupplementaryGroups yes

# Use DNS to verify virus database version. Freshclam uses DNS TXT records
# to verify database and software versions. With this directive you can change
# the database verification domain.
# WARNING: Do not touch it unless you're configuring freshclam to use your
# own database verification domain.
# Default: current.cvd.clamav.net
#DNSDatabaseInfo current.cvd.clamav.net

# Uncomment the following line and replace XY with your country
# code. See http://www.iana.org/cctld/cctld-whois.htm for the full list.
# You can use db.XY.ipv6.clamav.net for IPv6 connections.
#DatabaseMirror db.XY.clamav.net

# database.clamav.net is a round-robin record which points to our most 
# reliable mirrors. It's used as a fall back in case db.XY.clamav.net is 
# not working. DO NOT TOUCH the following line unless you know what you
# are doing.
DatabaseMirror database.clamav.net

# How many attempts to make before giving up.
# Default: 3 (per mirror)
#MaxAttempts 5

# With this option you can control scriped updates. It's highly recommended
# to keep it enabled.
# Default: yes
#scripedUpdates yes

# By default freshclam will keep the local databases (.cld) uncompressed to
# make their handling faster. With this option you can enable the compression;
# the change will take effect with the next database update.
# Default: no
#CompressLocalDatabase no

# With this option you can provide custom sources (http:// or file://) for
# database files. This option can be used multiple times.
# Default: no custom URLs
#DatabaseCustomURL http://myserver.com/mysigs.ndb
#DatabaseCustomURL file:///mnt/nfs/local.hdb

# This option allows you to easily point freshclam to private mirrors.
# If PrivateMirror is set, freshclam does not attempt to use DNS
# to determine whether its databases are out-of-date, instead it will
# use the If-Modified-Since request or directly check the headers of the
# remote database files. For each database, freshclam first attempts
# to download the CLD file. If that fails, it tries to download the
# CVD file. This option overrides DatabaseMirror, DNSDatabaseInfo
# and scripedUpdates. It can be used multiple times to provide
# fall-back mirrors.
# Default: disabled
#PrivateMirror mirror1.mynetwork.com
#PrivateMirror mirror2.mynetwork.com

# Number of database checks per day.
# Default: 12 (every two hours)
#Checks 24

# Proxy settings
# Default: disabled
#HTTPProxyServer myproxy.com
#HTTPProxyPort 1234
#HTTPProxyUsername myusername
#HTTPProxyPassword mypass

# If your servers are behind a firewall/proxy which applies User-Agent
# filtering you can use this option to force the use of a different
# User-Agent header.
# Default: clamav/version_number
#HTTPUserAgent SomeUserAgentIdString

# Use aaa.bbb.ccc.ddd as client address for downloading databases. Useful for
# multi-homed systems.
# Default: Use OS'es default outgoing IP address.
#LocalIPAddress aaa.bbb.ccc.ddd

# Send the RELOAD command to clamd.
# Default: no
#NotifyClamd /path/to/clamd.conf

# Run command after successful database update.
# Default: disabled
#OnUpdateExecute command

# Run command when database update process fails.
# Default: disabled
#OnErrorExecute command

# Run command when freshclam reports outdated version.
# In the command string %v will be replaced by the new version number.
# Default: disabled
#OnOutdatedExecute command

# Don't fork into background.
# Default: no
#Foreground yes

# Enable debug messages in libclamav.
# Default: no
#Debug yes

# Timeout in seconds when connecting to database server.
# Default: 30
#ConnectTimeout 60

# Timeout in seconds when reading from database server.
# Default: 30
#ReceiveTimeout 60

# With this option enabled, freshclam will attempt to load new
# databases into memory to make sure they are properly handled
# by libclamav before replacing the old ones.
# Default: yes
#TestDatabases yes

# When enabled freshclam will submit statistics to the ClamAV Project about
# the latest virus detections in your environment. The ClamAV maintainers
# will then use this data to determine what types of malware are the most
# detected in the field and in what geographic area they are.
# Freshclam will connect to clamd in order to get recent statistics.
# Default: no
#SubmitDetectionStats /path/to/clamd.conf

# Country of origin of malware/detection statistics (for statistical
# purposes only). The statistics collector at ClamAV.net will look up
# your IP address to determine the geographical origin of the malware
# reported by your installation. If this installation is mainly used to
# scan data which comes from a different location, please enable this
# option and enter a two-letter code (see http://www.iana.org/domains/root/db/)
# of the country of origin.
# Default: disabled
#DetectionStatsCountry country-code

# This option enables support for our "Personal Statistics" service. 
# When this option is enabled, the information on malware detected by
# your clamd installation is made available to you through our website.
# To get your HostID, log on http://www.stats.clamav.net and add a new
# host to your host list. Once you have the HostID, uncomment this option
# and paste the HostID here. As soon as your freshclam starts submitting
# information to our stats collecting service, you will be able to view
# the statistics of this clamd installation by logging into
# http://www.stats.clamav.net with the same credentials you used to
# generate the HostID. For more information refer to:
# http://www.clamav.net/documentation.html#cctts 
# This feature requires SubmitDetectionStats to be enabled.
# Default: disabled
#DetectionStatsHostID unique-id

# This option enables support for Google Safe Browsing. When activated for
# the first time, freshclam will download a new database file (safebrowsing.cvd)
# which will be automatically loaded by clamd and clamscan during the next
# reload, provided that the heuristic phishing detection is turned on. This
# database includes information about websites that may be phishing sites or
# possible sources of malware. When using this option, it's mandatory to run
# freshclam at least every 30 minutes.
# Freshclam uses the ClamAV's mirror infrastructure to distribute the
# database and its updates but all the contents are provided under Google's
# terms of use. See http://www.google.com/transparencyreport/safebrowsing
# and http://www.clamav.net/documentation.html#safebrowsing 
# for more information.
# Default: disabled
#SafeBrowsing yes

# This option enables downloading of bytecode.cvd, which includes additional
# detection mechanisms and improvements to the ClamAV engine.
# Default: enabled
#Bytecode yes

# Download an additional 3rd party signature database distributed through
# the ClamAV mirrors. 
# This option can be used multiple times.
#ExtraDatabase dbname1
#ExtraDatabase dbname2

Entrambi i suddetti file sono abbastanza basilari, potete dunque modificarli in base alle vostre esigenze.

Per verificare che tutto è stato configurato correttamente, lanciamo un prompt dei comandi (con privilegi di amministratore) ed eseguiamo clamd.exe:

C:\Program Files\ClamAV\clamd.exe

Se non vegnono riportati errori di sorta possiamo procedere con il download delle firme aggiornate e con l’installazione del suddetto applicativo sottoforma di servizio.

Per scaricare le firme è sufficiente lanciare il comando:

C:\Program Files\ClamAV\freshclam.exe

Installazione di ClamD come servizio

Per effettuare tale operazione si possono seguire 2 strade: la prima consiste nell’utilizzare il tool nativo di Windows sc; la seconda, che preferisco, prevede l’uso del tool nssm (che potete scaricare da qui).

Procediamo dunque con l’installazione del servizio lanciando il seguente comando (dopo aver estratto l’archivio contenente la versione a 64 bit dell’applicativo appena scaricato):

nssm install ClamD  "C:\Program Files\ClamAV\clamd.exe"

Se l’installazione è andata a buon fine possiamo procedere con l’avvio del servizio utilizzando il comando:

net start ClamD

oppure avvalendoci di services.msc.

Infine, per fare in modo che gli aggiornamenti dell’antivirus vengano scaricati automaticamente ogni notte, è sufficiente utilizzare il seguente scrip *.bat:

@echo off

echo %DATE% %TIME% : Starting ClamD signature update

"C:\Program Files\ClamAV\freshclam.exe"

net stop ClamD

net start ClamD

echo %DATE% %TIME% : ClamD signature update completed

echo ------------------------------------------------------------------

e creare un apposito task mediante il task scheduler di Windows (con l’opzione >> “C:\Program Files\ClamAv\clamd_update.log”, in modo da tenere traccia dello status relativo agli aggiornamenti automatici).

Adesso il nostro server di posta è più sicuro.

Alla prossima.

Logica di funzionamento del DNS (Domain Name System)

Prima di approfondire un argomento che avevo già trattato tempo addietro, ovvero il DNS cache poisoning (vedi qui per ulteriori dettagli), è utile illustrare la logica di funzionamento su cui si basa il Domain Name System.

Esistono, in soldoni, 2 tipologie di query DNS:
1) ricorsive;
2) iterative.

Supponiamo che il client voglia risolvere l’FQDN www.ciao.com

Nel primo caso il client contatterà il proprio resolver (ad esempio il nameserver dell’ISP) sottoponendogli la query. Se la risposta non è contenuta all’interno
della sua cache, esso effettuerà una query ai root nameserver. I root nameserver forniranno una risposta di tipo referral (con ANSWER SECTION vuota ed AUTHORITY SECTION non vuota), contenente una lista di nameserver da contattare per il top level domain (in gergo TLD) .com.
A questo punto il resolver contatterà uno dei nameserver autoritativi appena individuati, il quale fornirà una risposta di tipo referral indicando il nameserver autoritativo per il dominio cercato. Infine, quest’ultimo verrà interrogato e fornirà una risposta alla query (ANSWER SECTION non vuota) indicando l’indirizzo IP relativo al record A (www) ricercato (sempre se il suddetto record esiste).
La risposta, una volta giunta al resolver, verrà quindi girata al client.

recursiveDa notare che sia i root nameserver che i nameserver autoritativi per i TLD forniscono esclusivamente risposte di tipo referral, ergo funzionano solo
in modalità iterativa. Infatti, pensate a cosa accadrebbe se ciascun root nameserver interrogato (13 in tutto) iniziasse a fare query ricorsive per individuare
un determinato indirizzo IP… sarebbe una scelta davvero sconveniente (per usare un’espressione moderata) sia in termini di carico che in termini di latenza.

Inoltre, ciascun software che svolge funzioni di namserver utilizza degli algoritmi ben precisi per individuare il server a cui sottoporre la query (root, TLD o autoritativo che sia).
Nella fattispecie, bind usa la tecnica dell’RTT (Round Trip Time), grazie alla quale dovrebbe riuscire ad individuare il namserver più peformante (che coincide con quello che ha risposto più velocemente alla query).

Per ciò che concerne le query iterative, esse prevedono (in generale) il coinvolgimento diretto del client. Per prima cosa esso sottoporrà la query al proprio resolver, che gli risponderà con la lista dei root nameserver (risposta di tipo referral). Il root nameserver successivamente contattato dal client, gli fornirà una risposta di tipo referral indicando una lista di namserver autoritativi per il TLD .com. Dopodichè il client sottoporrà la query ad uno dei predetti nameserver, il quale gli fornirà come risposta una lista dei namserver autoritativi per il dominio ciao.com.
Infine, il client contatterà uno dei nameserver autoritativi per ciao.com che gli girerà la risposta contenente l’indirizzo IP per www.ciao.com (sempre se il record esiste).

Un esempio di query iterativa più essere facilmente ricavato utilizzando dig con l’opzione +trace, ad esempio:

[root@linuxbox ~]# dig +trace www.ciao.com

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.37.rc1.el6_7.2 <<>> +trace www.ciao.com
;; global options: +cmd
.                       440639  IN      NS      b.root-servers.net.
.                       440639  IN      NS      m.root-servers.net.
.                       440639  IN      NS      h.root-servers.net.
.                       440639  IN      NS      k.root-servers.net.
.                       440639  IN      NS      a.root-servers.net.
.                       440639  IN      NS      i.root-servers.net.
.                       440639  IN      NS      f.root-servers.net.
.                       440639  IN      NS      e.root-servers.net.
.                       440639  IN      NS      j.root-servers.net.
.                       440639  IN      NS      d.root-servers.net.
.                       440639  IN      NS      l.root-servers.net.
.                       440639  IN      NS      g.root-servers.net.
.                       440639  IN      NS      c.root-servers.net.
;; Received 496 bytes from 192.168.1.1#53(192.168.1.1) in 38 ms

com.                    172800  IN      NS      a.gtld-servers.net.
com.                    172800  IN      NS      b.gtld-servers.net.
com.                    172800  IN      NS      c.gtld-servers.net.
com.                    172800  IN      NS      d.gtld-servers.net.
com.                    172800  IN      NS      e.gtld-servers.net.
com.                    172800  IN      NS      f.gtld-servers.net.
com.                    172800  IN      NS      g.gtld-servers.net.
com.                    172800  IN      NS      h.gtld-servers.net.
com.                    172800  IN      NS      i.gtld-servers.net.
com.                    172800  IN      NS      j.gtld-servers.net.
com.                    172800  IN      NS      k.gtld-servers.net.
com.                    172800  IN      NS      l.gtld-servers.net.
com.                    172800  IN      NS      m.gtld-servers.net.
;; Received 490 bytes from 192.203.230.10#53(192.203.230.10) in 4323 ms

ciao.com.               172800  IN      NS      dns2.progtech.net.
ciao.com.               172800  IN      NS      dns.progtech.net.
;; Received 111 bytes from 192.33.14.30#53(192.33.14.30) in 623 ms

www.ciao.com.           86400   IN      A       185.60.164.38
ciao.com.               86400   IN      NS      dns2.progtech.net.
ciao.com.               86400   IN      NS      dns.progtech.net.
;; Received 127 bytes from 80.190.149.57#53(80.190.149.57) in 82 ms

Per completezza, riporto il contenuto di una risposta ad una quey DNS, con le relative sezioni (QUERY, ANSWER, AUTHORITY, ADDITIONAL)

[root@linuxbox ~]# dig libero.it

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.37.rc1.el6_7.2 <<>> libero.it
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23298
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2

;; QUESTION SECTION:
;libero.it.                     IN      A

;; ANSWER SECTION:
libero.it.              300     IN      A       37.9.239.32

;; AUTHORITY SECTION:
libero.it.              10799   IN      NS      n2.libero.it.
libero.it.              10799   IN      NS      n1.libero.it.

;; ADDITIONAL SECTION:
n2.libero.it.           10799   IN      A       156.154.67.47
n1.libero.it.           10799   IN      A       156.154.66.47

;; Query time: 256 msec
;; SERVER: 10.1.1.1#53(10.1.1.1)
;; WHEN: Tue May 31 09:29:06 2016
;; MSG SIZE  rcvd: 109

essa ci tornerà utile quando vedremo più nel dettaglio la logica su cui si basa il DNS cache poisoning.

DNS Spoofing a fin di bene

Facendo una rapida ricerca su Google si evince che il DNS Spoofing è una tecnica di cracking che rientra nella categoria MITM (Man in The Middle), tramite la quale “si fa credere” al PC della vittima che il sito X (ad esempio www.facebook.com) risponde all’indirizzo IP della macchina dell’aggressore (ad esempio 192.168.1.5). Se oltre a ciò sulla macchina dell’aggressore è presente anche una replica della home di facebook (ottenuta, ad esempio, mediante wget), le credenziali della vittima potranno essere facilmente individuate, a meno di messaggi HSTS (connessione non sicura/sito non attendibile) e di utenti più smaliziati (assenza del “lucchetto” di fianco alla barra degli indirizzi del browser).

Essa può essere realizzata seguendo 2 alternative: l’inserimento di record ad hoc all’interno del file hosts della macchina vittima oppure modificando il suo nameserver primario (dalle impostazioni di rete). In quest’ultimo caso parliamo di DNS Hijacking.

dnsspoofing

Dopo questa breve premessa è comunque utile fare una precisazione: il DNS Spoofing non è sempre sinonimo di cracking. Infatti, basti pensare al caso in cui l’ISP decide di “bloccare” l’accesso ad un sito per via dei suoi contenuti, agendo direttamente sui propri nameserver in modo da creare una mappatura statica indirizzo IP/FQDN che rimanda ad una pagina Web specifica, in cui viene notificato all’utente il blocco in atto (con eventuale registrazione degli indirizzi delle macchine che tentano di accedervi).

Un altro caso di utilizzo “bonario” della tecnica in questione riguarda il “blocco” di domini che veicolano notoriamente spyware, adaware e malware di ogni tipo. In questo post vi mostrerò come configurare il nameserver locale (realizzato grazie a dnsmasq, vedi qui per ulteriori dettagli) in modo da ottenere il blocco dei suddetti domini, semplicemente facendoli puntare a 127.0.0.1 (localhost).

Occorre precisare, inoltre, che tale tecnica funziona solo ed esclusivamente nel caso in cui gli utenti non abbiano privilegi di amministrazione sulle loro macchine e che quindi non siano in grado di modificare le impostazioni delle schede di rete (lasciando come nameserver primario quello da noi configurato). In aggiunta, la manutenibilità dei siti da bloccare è di gran lunga superiore rispetto a quella offerta dai blocchi mediante file hosts di ciascuna macchina (poichè, nel primo caso, si ha a disposizione una lista “centralizzata” di domini malevoli).

Ma passiamo alla configurazione vera e propria di dnsmasq. I domini che intendiamo bloccare sono i seguenti:

doubleclick.net
scorecardresearch.com
criteo.com
imrworldwide.com

per cui le direttive da aggiungere a dnsmasq saranno le seguenti:

address=/doubleclick.net/127.0.0.1
address=/scorecardresearch.com/127.0.0.1
address=/criteo.com/127.0.0.1
address=/imrworldwide.com/127.0.0.1

da notare che verranno bloccati non solo i suddetti domini, ma anche tutti gli eventuali sottodomini ad essi riconducibili.

Riavviamo dnsmasq:

root@ubuntubox:~# service dnsmasq restart

e testiamo il funzionamento del blocco appena configurato, pingando uno dei domini che intendiamo “dirottare” su localhost:

root@ubuntubox:~# ping criteo.com
PING criteo.com (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_req=1 ttl=64 time=0.035 ms
64 bytes from localhost (127.0.0.1): icmp_req=2 ttl=64 time=0.037 ms
64 bytes from localhost (127.0.0.1): icmp_req=3 ttl=64 time=0.036 ms

ed anche qualche sottodominio:

root@ubuntubox:~# ping pippo.criteo.com
PING pippo.criteo.com (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_req=1 ttl=64 time=0.033 ms
64 bytes from localhost (127.0.0.1): icmp_req=2 ttl=64 time=0.051 ms
64 bytes from localhost (127.0.0.1): icmp_req=3 ttl=64 time=0.040 ms
64 bytes from localhost (127.0.0.1): icmp_req=4 ttl=64 time=0.039 ms

Infine, diamo una ripulita ai PC degli utenti utilizzando software specifici quali Malwarebytes (in modo da eliminare il problema alla radice), continuando anche a monitorare le hit del proxy alla ricerca di eventuali domini “sospetti”.

Alla prossima.

PS: tale tecnica, a mio avviso, è più performante (ma meno malleabile) rispetto al blocco realizzato mediante l’uso di un proxy (ad esempio squid + squidguard), poichè agendo direttamente sul meccanismo di risoluzione dei nomi, si crea meno overhead e si ottengono tempi di risposta molto più ridotti.