Molto spesso ci si ritrova a diagnosticare problemi, capire perchè una applicazione non parte o eseguire blandi compiti di reverse engineering sul funzionamento di parti del sistema.
La prima fonte da consultare per ogni operazione di troubleshooting sono i log, file di testo che tengono traccia di errori e particolari azioni eseguite dal sistema, come il cambiamento di una password, il login di un certo utente o il messaggio di errore di una applicazione.
I log del sistema vengono generalmente scritti in directory come /var/log
e var/adm
o dove definito nei file di configurazione dei singoli programmi.
In quasi tutti i sistemi Unix il demone syslogd si occupa della gestione dei log tramite il file di configurazione /etc/syslog.conf
.
Le recenti distribuzioni Linux utilizzano sysklogd, una versione evoluta di syslogd che gestisce anche il logging del kernel (tramite il demone klogd).
Sono inoltre disponibili versioni modificato o più sicure di syslog.
L'equivalente su Windows dei log Unix sono gli eventi.
Incrementare la sicurezza in un sistema operativo gnu/linux significa anche analizzare e gestire paranoicamente i log.
Ciò significa che se non vogliamo perdere d'occhio tutto quello che accade sul nostro sistema , anche dopo un eventuale attacco informatico, dobbiamo salvare on-the-fly (al volo) i log su un dispositvo fisico esterno alla memoria del pc, che potrebbe essere manomessa. Quindi una cosa buona e giusta, sarebbe quella di stampare al volo tutto quello che succede sulla nostra macchina.
Certamente, ci vuole tanta carta e una buona stampante (anche vecchia) che stampi a modulo continuo. Ecco un esempio per tener d'occhio i log del kernel in real time:
tail -f /var/log/messages | grep -v "Inbound" > /dev/lp0
verrà stampato (/dev/lp0) in modalità raw tutto il cat del log (/var/log/messages) on-the-fly (tail -f), filtrando gli eventuali inbound (grep -v) del firewall attivo.
E' il file di configurazione principale del demone syslog. Di solito ha questo path in Unix vari ed è comodo consultarlo per verificare in fretta dove il sistema scrive i suoi log.
Il file si puo' suddividere in due campi, suddivisi da uno o piu' spazi bianchi o TAB:
SELECTOR: Diviso a sua volta in due parti separate da un punto: facility (identifica chi o cosa ha prodotto il messaggio) e priority(identifica il livello di priorita' del messaggio)
ACTION:Identifica il "logfile" dove vengono scritti i log corrispondenti. Oltre ad un normale file può essere un device coem la stampante o una console.
Analizziamo un esempio preso da una macchina RedHat Linux:
[neo@dido neo]$ cat /etc/syslog.conf
[...]
Nel file /var/log/messages vengono loggati tutti i messaggi di livello informativo, tranne quelli relativi alla posta (mail), all'accesso al sistema (authpriv) e al cron
*.info;mail.none;authpriv.none;cron.none /var/log/messages
[...]
Tutti i log, di qualsiasi priorità, che hanno a che fare con l'accesso al sistema, sono loggati in /var/log/secure
authpriv.* /var/log/secure
[...]
Tutti i log riguardanti la posta sono scritti in /var/log/maillog
mail.* /var/log/maillog
[...]
Tutti i log di comandi eseguiti in cron sono scritti in /var/log/cron
cron.* /var/log/cron
[...]
Tutti i log con priorità di emergenza vengono inviati ai terminali di ogni utnete collegato al sistema
*.emerg *
I log relativi al boot (a cui è associata, su questo sistema la facility local7) sono scritti in /var/log/boot.log
local7.* /var/log/boot.log
Alcune interessanti opzioni che si possono configurare su questo file sono del tipo:
Tutti i log del sistema vengono inviati al syslog server chiamato pippo (il nome deve essere risolvibile)
*.* @pippo
Tutti i movimenti di posta vengono scritti sulla console tty10
mail.* /dev/tty10
Tutti gli accessi al sistema sono stampati direttamente su una stampante locale
authpriv.* /dev/lp0
Brief report of the installation of rsyslog on Centos 5, with mysql support and PhpLogCon web interface.
This procedure has been tested on Centos 5 using the EPEL rpm repository.
Ensure all necessary packages are installed:
yum install rsyslog rsyslog-mysql
If you want local mysql server and web interface:
yum install mysql-server
yum install httpd php php-mysyql php-gd
If not running, start mysqld:
service mysqld status || service mysqld start
Create mysql database for rsyslog (file path changes on other distros/releases ):
mysql < /usr/share/doc/rsyslog-mysql-2.0.0/createDB.sql
Set mysql permissions (must be the same in /etc/rsyslog.conf and /path/top/phplogcon/config.php )
mysql> grant all on Syslog.* to syslog@localhost identified by 'mypass';
mysql> flush privileges ;
vi /etc/rsyslog.conf
# Log to Mysql Settings
$ModLoad ommysql
*.* :ommysql:localhost,Syslog,syslog,phplogcon
#Standard Redhat syslog settings
*.info;mail.none;authpriv.none;cron.none /var/log/messages
authpriv.* /var/log/secure
mail.* -/var/log/maillog
cron.* /var/log/cron
*.emerg *
uucp,news.crit /var/log/spooler
local7.* /var/log/boot.log
Try rsyslog (disable sysklogd):
service syslog stop
service rsyslog start
If you get messages like:
Feb 23 23:43:30 mon rsyslogd:could not load module '/usr/lib/rsyslog/ommysql', dlopen: /usr/lib/rsyslog/ommysql: cannot open shared object file: No such file or directory
fix fast with:
ln -s /usr/lib/rsyslog/ommysql.so /usr/lib/rsyslog/ommysql
Enable rsyslog service at boot time (and disable default syslog)
chkconfig syslog off
chkconfig rsyslog on
CENTRAL RSYSLOG
As with standard syslogd edit /etc/sysconfig/rsyslog
with option -r:
SYSLOGD_OPTIONS="-m 0 -r"
to enable the listening of syslog on the default 514 UDP port.
This is necessary for a centralized syslog server.
PHPLOGCON
Get latest package from http://www.phplogcon.org/
Unpack and move relevant files under Apache documents:
tar -zxvf phplogcon-2.5.24.tar.gz
cd phplogcon-2.5.24
mkdir /var/www/html/syslog
cp -a src/* /var/www/html/syslog
cd /var/www/html/syslog
To permit web configuration:
chmod 666 config.php
Browse to web interface: http://yourserver/syslog/ and follow on screen instructions.
Enable a Mysql source and use the authentication settings defined before.
Note that the logs table name is SystemEvents
To restore safe settings (do it after web configuration):
chmod 644 config.php
In un precedente infobox era stata illustrata la procedura da seguire per fare in modo che syslog-ng potesse loggare verso un sistema remoto utilizzando una vpn creata tramite openvpn.
In questo infobox, verra' illustrato come ottenere lo stesso risultato utilizzando un tunnel SSL tramite stunnel.
La distribuzione di riferimento utilizzata e' stata una CentOS e si presume che syslog-ng sia gia' stato installato sui sistemi interessati.
Innanzitutto e' necessario installare stunnel sia sul syslog server locale che remoto:
yum install stunnel
Successivamente generare il certificato utilizzato per identificare il syslog server remoto al quale inviare i messaggi:
openssl req -new -x509 -days 3650 -nodes -out server.pem -keyout server.pem
Creare quindi una copia del certificato server e rimuovere la parte relativa alla chiave compresa tra -----BEGIN RSA PRIVATE KEY----- e -----END RSA PRIVATE KEY-----. Il nuovo file .pem andra' copiato sul sistema che dovra' inviare i messaggi verso il syslog centrale tramite il tunnel cifrato.
Nella directory /etc/stunnel del syslog centrale creare il file di configurazione stunnel.conf:
cert = /etc/stunnel/server.pem
CAfile = /etc/stunnel/client.pem
verify=3
[5140]
accept = 10.76.120.40:5140
connect = 127.0.0.1:514
Nell'esempio riportato l'indirizzo IP del syslog server che deve ricevere i messaggi e' 10.76.120.40, la porta sulla quale stunnel restera' in ascoto la tcp 5140, mentre syslog-ng ricevera' i messaggi syslog sulla porta 514 dell'indirizzo di loopback.
server.pem e' il certificato generato in precedenza con il comando openssl req
mentre client.pem dovra' contenere il certificato generato per il syslog client, privato della parte relativa alla chiave privata, ovvero -----BEGIN RSA PRIVATE KEY----- e -----END RSA PRIVATE KEY-----.
L'opzione verify, infine, indica il meccanismo di verifica dei certificati. 3 e' l'opzione piu' restrittiva disponibile e consente la creazione di un tunnel esclusivamente da sistemi il cui certificato sia presente nel file definito dalla direttiva CAfile.
In caso di problemi nell'instaurazione del tunnel, se si sospetta essi possano dipendere dai certificati e' possibile rimuovere l'opzione verify in modo che non venga fatta alcuna verifica e sia cosi' possibile circoscrivere il problema.
Il tunnel puo' venire semplicamente avviato con il comando stunnel
e non fara' altro che ricevere i messaggi cifrati sulla porta tcp 5140 e rigirarli sulla tcp 514 di localhost dove e' in ascolto syslog-ng.
Si riporta uno stralcio di configurazione del file /etc/syslog-ng/syslog-ng.conf che indica come fare in modo che syslog-ng centrale possa ricevere i messaggi sulla porta 514 tcp:
#sorgenti, compresi log da remoto
source s_all {
file ("/proc/kmsg" log_prefix("kernel: "));
unix-stream ("/dev/log");
internal();
#tcp 514 per client che supportano tcp e stunnel
tcp(ip(127.0.0.1) port(514) keep-alive(yes) max-connections(10));
};
Per fare in modo un sistema registri i propri log sul syslog server remoto e' innanzitutto necessario creare un certificato ssl per esso:
openssl req -new -x509 -days 3650 -nodes -out client.pem -keyout client.pem
Configurare quindi stunnel sul sistema in questione in modo da creare un tunnel verso la porta TCP 5140 dell'host 10.76.120.40. In particolare, il file di configurazione /etc/stunnel/stunnel.conf da creare sul client dovra' essere uguale al seguente:
client = yes
cert = /etc/stunnel/client.pem
CAfile = /etc/stunnel/server.pem
verify=3
[5140]
accept = 127.0.0.1:514
connect = 10.76.120.40:5140
Il certificato del syslog server, server.pem deve essere copiato sul sistema e rimossa dal file in questione il testo compreso tra -----BEGIN RSA PRIVATE KEY----- e -----END RSA PRIVATE KEY-----, lasciando esclusivamente la parte relativa al certificato.
Definiti i certificati ed il file di configurazione, il tunnel puo' essere instaurato semplicemente lanciando il comando stunnel
senza alcun parametro.
Infine, perche' syslog-ng dal sistema client possa inviare i propri messaggi al sistema remoto e' necessario inserire almeno le seguenti linee nel file /etc/syslog-ng/syslog-ng.conf:
[...]
destination d_loghost { tcp("127.0.0.1" port(514)); };
[...]
log { source(nomesorgente); filter(nomefiltro); destination(d_loghost); };
La direttiva filter(nomefiltro) puo' essere omessa. In tal caso tutti i messaggi syslog verranno inviati al sistema remoto.
Nell'esempio riportato syslog-ng inviera' i messaggi verso la porta tcp 514 del proprio indirizzo di loopback, ove e' in ascolto il tunnel cifrato che a sua volta redirigera' i messaggi verso la porta 5140 del syslog server remoto 10.76.120.40.
La gestione e l'analisi dei log è un'attività sistemistica che richiede le sue attenzioni.
Su macchine ad alto traffico, o sotto attacco DOS o con particolari problemi ricorrenti, le dimensioni dei log possono crescere a dismisura in pochissimo tempo, fino a saturare il file system.
Per questo motivo è sempre consigliabile montare la directory /var
, dove generalmente risiedono i log, in una partizione indipendente, che, anche se riempita, non blocca il funzionamento del sistema.
E' inoltre importante poterli gestire, ruotandoli ad intervalli fissi e compattando i log vecchi, preparandoli per un'archiviazione.
Su molte distribuzioni Linux è incluso Logrotate, un'applicazione che semplifica l'amministrazione dei log, permette di comprimere, rimuovere ed inviare il log via mail oltre a eseguire una rotazione di file con vari criteri.
Il file di configurazione è /etc/logrotate.conf
In sistemi che usano RPM , solitamente, le regole di gestione dei singoli log sono inserite nella directory /etc/logrotate.d/
.
Generalmente gli script che eseguono logrotate sono inseriti nel crontab e di default sono configurati per gestire i log standard di sistema.
Altra applicazione che viene spesso usata per gestire, in particolare, i log di Apache è Cronolog, che rende particolarmente semplice la segmentazione di log in file diversi generati secondo unità di tempo configurabili (es: un file diverso ogni giorno). E' particolarmente utile per gestire siti ad alto traffico, in cui le dimensioni dei log tendono a crescere in modo spropositato.
Viene tipicamente usato come un filtro che riceve un log dallo standard input e lo scrive in stdout su più diversi file, secondo le specifiche indicate in un template. La sintassi di base è /path/cronolog [opzioni] template
. Per esempio:
/usr/sbin/cronolog /web/logs/%Y/%m/%d/access.log
divide il log che riceve in stdout in tanto diversi log in diverse directory secondo il criterio /web/logs/anno/mese/giorno/access.log, con risultati tipo: /web/logs/2003/01/17/access.log.
Viene tipicamente usato in httpd.conf sfruttando la funzionalità di Apache di inviare i log ad un comando esterno:
TransferLog "|/usr/sbin/cronolog /web/logs/%Y/%m-%d-access.log"
ErrorLog "|/usr/sbin/cronolog /web/logs/%Y/%m-%d-errors.log"
Crea un file di log diverso ogni giorno e li mette in directory divise per anno.
Il vantaggio di simili programmi è quello di sollevare l'amministratore dalla noiosa e insidiosa pratica di gestione e archiviazione dei log, che se non automatizzata può portare a spiacevoli conseguenze quali file system riempiti al 100%, file di log enormi, perdita di dati e simili contrattempi.
E' l'applicazione inclusa in diverse distribuzioni Linux per la gestione dei log di sistema.
Logrotate permette di comprimere, rimuovere ed inviare via mail i file di log. Ogni file può essere gestito in base criteri temporali (giornalmente, settimanalmente, o mensilmente) oppure alle proprie dimensioni. Tipicamente l'utilizzo di logrotate viene schedulato tramite il demone cron ed i file di log da esso gestiti non vengono modificati più di una volta al giorno salvo che il criterio sia basato sulla dimensione e logrotate avviato più volte al giorno oppure che sia utilizzata l'opzione -f
o --force
e quindi logrotate sia forzato a rielaborare i file di log.
Logrotate utilizza /var/lib/logrotate/status
per tenere traccia dei log elaborati e /etc/logrotate.conf
per quanto riguarda la configurazione. Alcuni packages installano informazioni relative alla rotazione dei log in /etc/logrotate.d/
.
La sintassi è la seguente:
logrotate [-dvf?] [-m command] [-s statefile] [--usage]
-d
: Abilita il debug mode. Questa azione implica anche l'utilizzo automatico dell'opzione -v
. In modalità di debug, non vengono apportati cambiamenti ai log o al file di stato;
-v
: Abilita il verbose mode ovvero visualizza informazioni durante la rotazione dei log;
-f
: Forza la rotazione dei log;
-?
: Visualizza una breve guida in linea;
-m <comando>
: Indica a logrotate quale comando utilizzare per inviare via mail i log. Di default viene utilizzato /sbin/mail -s
;
-s <state-file>
: Indica a logrotate di utilizzare un file di stato diverso da quello di default ovvero /var/lib/logrotate/status
;
--usage
: Visualizza le opzioni disponibili per l'applicazione.
E' il file principale riguardante la configurazione di logrotate.
Attraverso il file di configurazione di logrotate è possibile definire il comportamento dell'applicazione in due contesti: a livello globale (nella prima parte del file) e a livello locale dove le regole ridefinite prevalgono su quelle globali. Per ogni file di cui si vuole effettuare la rotazione è necessario indicarne il percorso, al quale seguono tra parentesi graffe le direttive di gestione.
Tra le direttive più utili:
- Criteri di rotazione
daily
: Rotazione su base giornaliera;
weekly
: Rotazione su base settimanale;
monthly
: Rotazione su base mensile;
size <dimensione>
: Rotazione in base alla dimensione;
notifempty
: Non esegue la rotazione se il file è vuoto;
- Compressione
compress
: Una volta archiviato il file di log, viene compresso tramite gzip;
compresscmd
: Indica il programma da utilizzare al posto di gzip;
- Gestione File
create <mode> <owner> <group>
: Immediatamente dopo la rotazione viene creato un nuovo file con il nome identico al precedente. E' possibile specificare, modalità di accesso, proprietario e gruppo;
copy
: Crea una copia del file di log e non modifica l'originale che non viene mai rimosso;
copytruncate
: Utilizzata nel caso in cui non sia possibile chiudere il file di log. Viene archiviata parte del file di log mentre ne viene eseguita una copia;
olddir <directory>
: I file di log vengono spostati nella directory indicata prima di eseguire la rotazione;
- Configurazione
include <file o directory>
: Legge il file oppure tutti i file della directory indicata ed applica le direttive incontrate all'interno di essi. E' possibile trovare include /etc/logrotate.d
in quanto alcuni packages installano le proprie istruzioni in questa directory;
- Operazioni Pre-log e Post-log
postrotate endscript
: Tramite questo blocco di direttive è possibile eseguire delle operazioni in seguito alla rotazione;
prerotate endscript
: Tramite questo blocco di direttive è possibile eseguire delle operazioni prima che avvenga la rotazione e solo se questa avrà luogo;
Un esempio del file di configurazione:
#
# Parametri Globali
#
compress Abilita la compressione, di default con gzip, dei log dopo la rotazione
weekly La rotazione di default è stabilita con criterio temporale settimanale ovvero ogni settimana viene creato un nuovo file di log
# Parametri Locali
/var/log/debug {
rotate 2 Indica che verranno mantenuti due file di log, in particolare uno per ogni settimana. La rotazione in questo caso è settimanale in quanto la direttiva di default non è stata ridefinita.
postrotate Blocco postrotate ovvero istruzioni eseguite in seguito alla rotazione di un log. Possono esistere solamente all'interno di direttive locali
/sbin/killall -HUP syslogd Ferma e riavvia il logging da parte di syslogd in modo che possa riprendere a lavorare sul nuovo file una volta effettuata la rotazione del vecchio file di log
endscript Termine blocco postrotate
}
/var/log/faillog {
monthly Il criterio temporale viene ridefinito localmente e passa da settimanale a mensile
rotate 2 Rotazione ogni 2 mesi
postrotate
/sbin/killall -HUP syslogd
endscript
}
/var/log/lastlog {
rotate 3 Rotazione ogni 3 settimane
postrotate
/sbin/killall -HUP syslogd
endscript
}
/var/log/maillog {
monthly
rotate 2 Rotazione ogni 2 mesi
postrotate
/sbin/killall -HUP syslogd
endscript
}
/var/log/syslog {
rotate 4 Rotazione ogni 4 settimane
postrotate
/sbin/killall -HUP syslogd
endscript
}
/var/log/messages {
rotate 2 Rotazione ogni 2 settimane
postrotate
/sbin/killall -HUP syslogd
endscript
}
/var/log/proftpd.log { Log ProFTPD Server
rotate 3 Rotazione ogni 3 settimane
postrotate
/sbin/killall -HUP syslogd
endscript
}
L'utility colorize permette di visualizzare con sintassi colorata i file di log.
Colorize è un piccolo script, di Karaszi Istvan e rilasciato sotto GPL, scritto in linguaggio Perl, che permette di
visualizzare i log, con una sintassi colorata in modo da renderli più facilmente leggibili. Requisito di sistema il modulo Perl
Term::ANSIColor.
DOWNLOAD
E' possibile eseguire il download dal sito dell'autore:
[root@pluto azitti]# wget http://colorize.raszi.hu/downloads/colorize_0.3.4.tar.gz
--15:44:14-- http://colorize.raszi.hu/downloads/colorize_0.3.4.tar.gz <br>
=> `colorize_0.3.4.tar.gz'
Resolving colorize.raszi.hu... done.
Connecting to colorize.raszi.hu[212.108.197.149]:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 17,291 [application/x-tar]
100%[==================================================================================>] 17,291 12.52K/s ETA 00:00
15:44:15 (12.52 KB/s) - `colorize_0.3.4.tar.gz' saved [17291/17291]
SCOMPATTAZIONE E INSTALLAZIONE
Una volta scaricato lo script è sufficiente scompattarlo:
[root@pluto azitti]# tar xvfz colorize_0.3.4.tar.gz
colorize-0.3.4/README
colorize-0.3.4/THANKS
colorize-0.3.4/TIPS
colorize-0.3.4/TODO
colorize-0.3.4/changelog.gz
colorize-0.3.4/colorize
colorize-0.3.4/colorize.1.gz
colorize-0.3.4/colorizerc
colorize-0.3.4/copyright
colorize-0.3.4/examples/
colorize-0.3.4/examples/Xlog.tar
colorize-0.3.4/examples/colorize-fifo.sh
colorize-0.3.4/examples/colorize-tail.sh
A questo punto è sufficiente copiare l'utility in una directory presente nel PATH di sistema, ed il file di configurazione in /etc
:
[root@pluto colorize-0.3.4]# cp colorize /usr/bin/
copia dello script
[root@pluto colorize-0.3.4]# cp colorizerc /etc/
copia del file di configurazione globale
Infine l'utility puo' essere utilizzata tramite pipe o altri metodi di redirezione di input/output:
[root@pluto colorize-0.3.4]# less /var/log/messages | colorize
[root@pluto colorize-0.3.4]# colorize < /var/log/sudo.log
Registrare le operazioni svolte sul server e' un'attivita' di importanza fondamentale, sia come fonte di informazioni utili per risolvere eventuali malfunzionamenti, che come forma di controllo del sistema, verificando che esso non stia subendo attacchi o tentativi di intrusione.
Un attacker abile certamente sara' in grado di occultare al meglio le proprie tracce, ad esempio cancellando i segni del propria operato dai file dove il log server registra tutte le attivita'. Emerge quindi la necessita' di proteggere questi file nel migliore modo possibile, e quindi non memorizzandoli esclusivamente sulla macchina che si desidera monitorare: in caso di violazione della stessa essi sarebbero a piena disposizione dell'attacker.
Una prima possibilita', potrebbe essere quella di mantenere anche una copia cartacea dei log stessi. Certamente l'attacker, a meno di non avervi accesso fisicamente non potrebbe cancellare le sue tracce dalle stampe dei log. Questa scelta comporterebbe pero' un incremento mostruoso delle scartoffie, oltre che problemi pratici per la loro analisi ed archiviazione.
Scartando questa ipotesi, si potrebbe pensare all'utilizzo di un secondo log server, in modo da replicare anche in remoto i log che vengono memorizzati localmente. In un simile caso l'attacker dovrebbe cancellare le sue tracce in due posti diversi. Inoltre, presupponendo che il log server remoto preveda tutti i possibili accorgimenti ai fini della sicurezza del sistema, tra cui l'installazione solo del software strettamente necessario, non sarebbe cosi' semplice per l'attacker cancellare le proprie tracce anche da esso.
Si presume inoltre che tale log server non sia direttamente connesso ad internet, ma sia accessibile esclusivamente dalla rete interna, minimizzando quindi la sua esposizione.
Negli esempi riportati la macchina da monitorare e' l'host paranoid, mentre il log server remoto stargazer.
Su entrambe le macchine e' stato installato syslog-ng con il comando apt-get install syslog-ng
.
Sull'host paranoid e' stato modificato il file /etc/syslog-ng/syslog-ng.conf, nel seguente modo:
- sources: definisce tutte le “sorgenti” dalle quali raccogliere i dati da registrare nei log. Una sorgente e' un driver che raccoglie i messaggi usando un metodo predefinito. Nel mio caso sono state definite le seguenti sorgenti per l'host paranoid:
source s_all
{
# messaggi generati da Syslog-NG
internal();
#standard Linux log source
unix-stream("/dev/log" max-connections(10));
# messaggi dal kernel
file("/proc/kmsg" log_prefix("kernel: "));
};
La prima sorgente internal() indica i messaggi generati dallo stesso syslog-ng, in modo da potere registrare anche avvertimenti ed errori relativi al log-server, come ad esempio il suo arresto o riavvio.
Unix-stream apre invece un socket unix sul quale ascoltare i messaggi generati dal sistema. Per evitare attacchi di tipo DoS viene imposto anche un limite al massimo numero di connessioni accettate con l'opzione max-connections. Il valore 10 e' piuttosto ristretto, ma comunque adatto alla mia situazione, trattandosi di un server con poco carico di lavoro. Nel caso di sistemi con maggiore occupazione potrebbe essereopportuno aumentare questo valore.
L'ultimo driver file() infine legge i messaggi che il kernel scrive in /proc/kmesg.
- destination: le destinazioni costituiscono i punti dove inviare e memorizzare i messaggi raccolti dalle sources se le regole di filtraggio vengono soddisfatte. Come per le sorgenti esistono diversi driver che definiscono come distribuire tali messaggi.
# destinazioni standard
destination df_auth { file("/var/log/hostnames/$HOST/$YEAR/$MONTH/auth.log"); };
destination df_syslog { file("/var/log/hostnames/$HOST/$YEAR/$MONTH/syslog"); };
destination df_cron { file("/var/log/hostnames/$HOST/$YEAR/$MONTH/cron.log"); };
destination df_daemon { file("/var/log/hostnames/$HOST/$YEAR/$MONTH/daemon.log"); };
destination df_kern { file("/var/log/hostnames/$HOST/$YEAR/$MONTH/kern.log"); };
destination df_lpr { file("/var/log/hostnames/$HOST/$YEAR/$MONTH/lpr.log"); };
destination df_mail { file("/var/log/hostnames/$HOST/$YEAR/$MONTH/mail.log"); };
destination df_user { file("/var/log/hostnames/$HOST/$YEAR/$MONTH/user.log"); };
destination df_uucp { file("/var/log/hostnames/$HOST/$YEAR/$MONTH/uucp.log"); };
destination df_sshd { file("/var/log/hostnames/$HOST/$YEAR/$MONTH/sshd.log"); };
# destinazioni per le varie facility e livelli severity.
# Usate solo alcune per mail.info, mail.crit e mail.warn
destination df_facility_dot_info { file("/var/log/hostnames/$HOST/$YEAR/$MONTH/$FACILITY.info"); };
destination df_facility_dot_notice { file("/var/log/hostnames/$HOST/$YEAR/$MONTH/$FACILITY.notice"); };
destination df_facility_dot_warn { file("/var/log/hostnames/$HOST/$YEAR/$MONTH/$FACILITY.warn"); };
destination df_facility_dot_err { file("/var/log/hostnames/$HOST/$YEAR/$MONTH/$FACILITY.err"); };
destination df_facility_dot_crit { file("/var/log/hostnames/$HOST/$YEAR/$MONTH/$FACILITY.crit"); };
[...]
#debug e messaggi vari
destination df_debug { file("/var/log/hostnames/$HOST/$YEAR/$MONTH/debug"); };
destination df_messages { file("/var/log/hostnames/$HOST/$YEAR/$MONTH/messages"); };
#file con messaggi critici, situazione di emergenza!!!!
destination df_emergency { file ("/var/log/hostnames/$HOST/$YEAR/$MONTH/log.emerg"); };
#stampa su consoles virtuali
destination du_all { usertty("*"); };
#logging remoto su stargazer
destination stargazer { tcp(“10.0.1.2” port(15514)); };
Nel file di configurazione vengono definiti diversi file ove memorizzare i messaggi, a seconda della loro categoria. E' infatti possibile definire dei filtri sui messaggi, in base ai quali scegliere dove memorizzarli. Da qui l'utilizzo di destinazioni diverse, in modo da favorire successivamente la leggibilita' e l'analisi dei log.
Quasi tutte le destinazioni usano il driver file(), e quindi provvedono a memorizzare i messaggi che rispetteranno determinati criteri all'interno del file indicato come argomento.
Viene inoltre fatto ricorso alle macro quali $HOST, $YEAR e $MONTH. Esse verranno rispettivamente espanse nell'hostname della macchina che ha generato il messaggio, l'anno ed il mese in cui esso e' stato ricevuto. Per default le macro $YEAR, $MONTH ecc. verrebbero espanse con l'anno e il mese in cui il messaggio e' stato generato, ma tale comportamento e' stato modificato dall'opzione use_time_recvd() come si vedra' successivamente.
Ricorrendo a queste macro e' quindi possibile organizzare automaticamente i log registrandoli in cartelle a seconda della loro provenienza e di quando siano stati generati. Ad esempio i log del mese di dicembre 2005 generati da paranoid saranno memorizzati sotto la directory /var/log/hostnames/paranoid/2005/12 .
L'ultima destinazione, a cui e' stato associato l'alias stargazer utilizza il driver tcp() , e nel caso riportato consente di inviare i messaggi syslog alla porta tcp 15514 dell'indirizzo IP 10.0.1.2 ovvero l'indirizzo dell'host stargazer. Perche' questi messaggi possano essere ricevuti il log-server remoto all'indirizzo 10.0.1.2, dovra' avere tale porta tra i suoi sorgenti per la raccolta dei messaggi stessi.
- filter: specificano come syslog-ng debba eseguire l'instradamento dei diversi messaggi. In pratica essi sono costituiti da un'espressione booleana che verra' valutata per decidere se e dove un messaggio dovra' essere registrato. Ai filtri, come per destinazioni e sorgenti e' possibile associare dei nomi, in modo che essi possano venire utilizzati anche in diversi log statements.
I filtri sono stati impostati secondo i valori di facilitiy e severitiy indicate nella rfc 3164 (The BSD syslog protocol). Per la precisione i filtri definiti in base alle facility sono stati i seguenti:
#messaggi con facility 4 o 10 (autenticazione e sicurezza.)
filter f_auth { facility(auth, authpriv); };
#messaggi con facility diversa da auth ed authpriv.
filter f_syslog { not facility(auth, authpriv, mail, news); };
#messaggi con facility 9, relativi al demone cron
filter f_cron { facility(cron); };
#messaggi relativi agli altri demoni di sistema (facility 3)
filter f_daemon { facility(daemon); };
#messaggi dal kernel (0)
filter f_kern { facility(kern); };
#messaggi relativi al sistema di stampa (facility 6)
filter f_lpr { facility(lpr); };
#messaggi relativi a mail (facility 2 )
filter f_mail { facility(mail); };
#messaggi relativi allo user-space (facility 1)
filter f_user { facility(user); };
#sottosistema uucp
filter f_uucp { facility(uucp); };
#attivita' server ssh
filter f_sshd { facility(local0); };
Una seconda serie di filtri, sono stati invece definiti a seconda del livello di severity dei messaggi. Ad ogni livello di severity corrisponde un numero i cui significati sono rispettivamente messaggi di debug (livello 7), info (informazioni, livello 6), notice (informazioni significative, 5), warning (avvisi, 4), error (situazioni di errore, 3), critical (eventi critici, 2), alert (condizioni che richiedono intervento immediato, 1) ed infine emergency (sistema inutilizzabile, livello 0).
Tra i filtri definiti quindi :
#messaggi con severity < 6
filter f_at_least_info { level(info..emerg); };
#severity <5
filter f_at_least_notice { level(notice..emerg); };
#severity < 4
filter f_at_least_warn { level(warn..emerg); };
#severity <3
filter f_at_least_err { level(err..emerg); };
#severity < 2
filter f_at_least_crit { level(crit..emerg); };
#messaggi con severity debug e facility diversa da auth, authpriv,
# news e mail
filter f_debug { level(debug) and not facility(auth, authpriv, news, mail); };
# messaggi con severity da info a error, facility diversa da auth,
# authpriv,cron, daemon, news e mail
filter f_messages {
level(info..error) and not facility(auth,authpriv,cron,daemon,mail,news); };
#messaggi con severity critica
filter f_critical{ level(crit); };
# messages con severity emergenza!!!
filter f_emerg { level(alert, emerg); };
Alcuni filtri sono presenti perche' inclusi nella configurazione di default di syslog-ng, ma senza essere effettivamente utilizzati, come ad esempio tutti gli f_at_least_*. Per completezza si e' preferito lasciarli definiti, nel caso dovessero tornare utili in seguito. Inoltre, non venendo inseriti in alcun log statement non dovrebbero avere effetti negativi relativamente alle prestazioni del log server.
- log: log path o log statements, definiscono come collegare tra loro sorgenti destinazioni e filtri. In pratica uno statement indica la destinazione per i messaggi provenienti dalle sorgenti specificate e che rispettino il filtro filter.
Tutti i log statements vengono processati nell'ordine in cui sono definiti all'interno di syslog-ng.conf, e quindi un messaggio potra' anche essere inviato a destinazioni diverse se rispetta i rispettivi statements.
#registra messaggi con facility auth e authpriv in auth.log
log { source(s_all); filter(f_auth); destination(df_auth); };
#registra il messaggi che rispsettano f_syslog in df_syslog
log { source(s_all); filter(f_syslog); destination(df_syslog); };
#registra messaggi relativi allla facility 9 in cron.log
log { source(s_all); filter(f_cron); destination(df_cron);};
#registra messaggi con facility 3 in daemon.log
log { source(s_all); filter(f_daemon); destination(df_daemon);};
#registra i messaggi del kernel in kern.log
log {source(s_all); filter(f_kern); destination(df_kern); };
# registra i messaggi del sistema di stampa in lpr.log
log { source(s_all); filter(f_lpr); destination(df_lpr); };
#messaggi con facility mail in mail.log
log { source(s_all); filter(f_mail); destination(df_mail); };
#messaggi relativi allo user-space in user.log
log { source(s_all); filter(f_user); destination(df_user); };
#messaggi dal server sshd
log { source(s_all); filter(f_sshd); destination(df_sshd); };
# messaggi con facility mail e severity pari almeno ad in info in
# mail.info
log { source(s_all); filter(f_mail); filter(f_at_least_info); destination(df_facility_dot_info); };
# messaggi con facility mail e severity pari almeno a warning in
# mail.warn
log { source(s_all); filter(f_mail); filter(f_at_least_warn); destination(df_facility_dot_warn); };
# messaggi con facility mail e severity pari almeno a errori in
# mail.err
log { source(s_all); filter(f_mail); filter(f_at_least_err); destination(df_facility_dot_err); };
# messaggi severity debug e facility diversa da auth, authpriv,
# news e mail,vanno in debug
log { source(s_all); filter(f_debug); destination(df_debug); };
# severity tra info e error e facility diversa da
# auth,authpriv,cron,daemon,mail,news registrati nel file
# messages
log { source(s_all); filter(f_messages); destination(df_messages); };
# messaggi con severity critica in log.emerg
log { source(s_all); filter(f_critical); destination(df_emergency); };
# messaggi con severity emergency e alert in log.emerg e sulle
# tty
log { source(s_all); filter(f_emerg); destination(df_emergency); destination(du_all); };
Come si puo' notare all'interno dei filtri e dei files di destinazione e' presente anche un filtro con facility pari a local0. Esso e' relativo all'attivita' del servizio ssh., che e' stato configurato in modo da generare messaggi con questo livello di facility personalizzato, in modo da registrarli in un file separato, sshd.log appunto.
Vengono infine definite una serie di opzioni, nella sezione options del file di configurazione. Tra le opzioni modificate rispetto alla configurazione di default:
- sync(3) : indica il numero minimo di linee che debbono essere presenti nella coda di output dei messaggi, prima che vengano scritte in un file.
- group(sys_operators) e perm(0640): impone che i nuovi files creati da syslog-ng appartengano al gruppo sys_operators con permessi di lettura e scrittura per il proprietario e sola lettura per gli appartenenti al gruppo. Il proprietario dei files e' per default l'utente root, ma volendo e' possibile cambiarlo tramite l'opzione owner.
- dir_group(sys_operators) e dir_perm(0750): specifica che le nuove cartelle create da syslog-ng appartengano al gruppo sys_operators, ed abbiano permessi di lettura scrittura ed esecuzione per il proprietario (ovvero root), e di sola lettura ed esecuzione per gli appartenenti al gruppo. E' possibile cambiare l'owner delle directory tramite l'opzione dir_owner.
- check_hostname(yes) : consente di eseguire una verifica sull'hostname dei messaggi ricevuti, se esso contiene caratteri validi o meno.
- keep_hostname(no) : specifica se fidarsi o meno dell'hostname contenuto nei messaggi syslog. Impostandolo a no il valore di hostname dei messaggi dovrebbe venire riscritto a seconda della provenienza dei pacchetti che li contengono.
- use_time_recvd(yes): utilizzata per l'espansione delle macro, indica di sostituire le macro relative al tempo con il momento della ricezione del messaggio e non quello della spedizione del precedente log-server della catena.
La configurazione di syslog-ng su stargazer e' pressoche' identica a quella effettuata per paranoid. Le uniche differenze sono la mancanza della destinazione destination stargazer { tcp(“10.0.1.2” port(15514)); }; e l'aggiunta tra le sorgenti di tcp(ip("10.0.1.2" port(15514) keep-alive(yes)); .
In questo modo il log-server su stargazer registrera' anche i messaggi in arrivo sulla sua porta tcp 15514. Anche in questo caso l'indirizzo IP specificato non e' 192.168.1.2, ma 10.0.1.2, ovvero quello dell'interfaccia virtuale usata per la vpn.
Un'altro aspetto considerato per predisporre il sistema di logging e' stata la cifratura dei messaggi trasferiti. In caso contrario un eventuale attacker in grado di sniffare il traffico tra gli host paranoid e stargazer potrebbe avere la possibilita' di osservare i messaggi inviati e raccogliere informazioni relative alle attivita' effettuate.
Per cifrare il canale tra le due macchine le mia scelta iniziale era stata stunnel, ma non sono riuscito in alcun modo a farlo funzionare. Secondo i log generati non riusciva ad accettare connessioni dall'esterno, riportando un codice di errore 111.
In alternativa ho deciso di ricorrere a openvpn per la creazione di una vpn tra i miei due host, anche se forse si tratta di una soluzione un po' sovradimensionata rispetto alle mie necessita'.
Su entrambe le macchine e' quindi stato installato openvpn con il comando apt-get install openvpn
.
Per prima cosa e' stata generata su stargazer la chiave da utilizzare con il comando openvpn --genkey --secret vpn.key
, copiata all'interno di /etc/openvpn, ed assegnato il permesso di sola lettura all'utente root (chmod 400 /etc/openvpn/vpn.key
).
Per evitare che essa potesse essere cancellata erroneamente le e' stato associato anche l'attributo immutable con chattr +i /etc/openvpn/vpn.key
.
La chiave e' poi stata copiata anche su paranoid, associandole gli stessi permessi.
Per fare funzionare la vpn e' stato necessario l'utilizzo del dispositivo di rete virtuale tun/tap. Non e' stato necessario creare il device con il comando mknod, poiche' a quanto pare aveva gia' provveduto a farlo debconf dopo l'installazione del pacchetto openvpn.
Il file di configurazione per stargazer, /etc/openvpn/server.conf, e' stato il seguente :
#server vpn
dev tap
lport 5000
ifconfig 10.0.1.2 255.255.255.0
secret /etc/openvpn/vpn.key
verb 2
L'opzione dev indica il device utilizzato per il tunnel, lport specifica la porta usata lato server per la vpn, ifconfig l'indirizzo IP e la netmask dell'interfaccia virtuale, secret il percorso al file contenente la chiave, ed infine verb definisce il livello di verbosity.
Sull'host paranoid le operazioni eseguite sono state le medesime, a differenza di alcune differenze in /etc/openvpn/client.conf:
#client vpn
remote 192.168.1.2
dev tap
rport 5000
ifconfig 10.0.1.4 255.255.255.0
secret /etc/openvpn/vpn.key
verb 1
Remote specifica il vero indirizzo IP della macchina a cui ci si andra' a connettere, ovvero stargazer, rport la porta utilizzata all'altra estremita' per creare il tunnel, secret il file della chiave e ifconfig l'indirizzo dell'interfaccia virtuale su paranoid.
Infine, su stargazer, e' stato necessario abilitare l'ip forwarding, con il comando echo 1 > /proc/sys/net/ipv4/ip_forward
. Per automatizzare l'operazione si potrebbe inserire il comando in qualche script eseguito automaticamente all'avvio del sistema.
Eseguite queste operazioni si e' avviata la vpn su entrambe le macchine con la linea di comando /etc/init.d/openvpn start
.
Configurando in questo modo la vpn, un eventuale attacker che dovesse sniffare il traffico tra le due macchine vedrebbe solo dei pacchetti UDP con porta sorgente e destinazione pari a 5000, il cui contenuto sarebbe per lui privo di significato a causa della cifratura.
Per verificare il corretto funzionamento e' stato controllato con ethereal lo scambio dei messaggi syslog tra paranoid e stargazer durante il login di un utente sul primo host.
Come ci si poteva aspettare il traffico visibile era costituito dai pacchetti UDP della vpn, mentre su stargazer il login e' stato correttamente registrato nel file /var/log/hostnames/paranoid/2005/12/auth.log :
Dec 28 11:02:02 paranoid login[456]: (pam_unix) session opened for user andrea by LOGIN(uid=0)
Dec 28 11:02:02 paranoid login[456]: `andrea' logged in on `tty2'
In questo infobox verra' illustrato come fare in modo che syslog-ng anziche' loggare su normali files di testo scriva all'interno di un database mysql.
Una configurazione tipica per salvare i log all'interno di un database prevede l'utilizzo di una pipe, ma dopo alcuni test ho preferito scartare la soluzione poiche' troppo messaggi venivano persi al momento della scrittura tramite il client mysql. In questo caso si e' optato per una soluzione differente che prevede di salvarei i log come query all'interno di diversi file poi processati in modo asincrono da uno shellscript che provvedera' a memorizzarli all'interno del database.
Si presuppone sia syslog-ng, mysqlserver ed il client mysql siano gia' installati sul sitema.
Innanzitutto e' necessario connettendosi a mysql con il comando mysql -u username -p passwhord -h 127.0.0.1
e creare il database che conterra' i log con il comando create database db_log;
.
Si presuppone che mysql sia in esecuzione sullo stesso sistema del syslog server ed in ascolto sull'indirizzo di loopback.
Una voltra create il database si suggerisce di creare un utente apposito che abbia i privilegi sullo stesso, in modo di evitare di utilizzare l'utenza di root. Anche in questo caso e' necessario loggarsi al dbms con un mysql -u username -p password -h 127.0.0.1
ed eseguir eil seguente comando:
GRANT ALL PRIVILEGES ON db_syslog.* TO [email protected] IDENTIFIED BY 'syslog_password'
.
L'ultima operazione da eseguire sul database e' la creazione della tabella che conterra' i messaggi syslog salvati da syslog-ng. Tale operazione puo' essere portata a termine con il comando mysql -u syslog_user -p syslog_password -h 127.0.0.1 < syslog_table.sql
.
syslog_table.sql sara' un file di testo contenente le istruzione per creare la tabella, e dovra' contenere le seguenti linee:
#
# Table structure for table `logs`
#
CREATE TABLE logs (
host varchar(32) default NULL,
facility varchar(10) default NULL,
priority varchar(10) default NULL,
level varchar(10) default NULL,
tag varchar(10) default NULL,
date date default NULL,
time time default NULL,
program varchar(15) default NULL,
msg text,
seq int(10) unsigned NOT NULL auto_increment,
PRIMARY KEY (seq),
KEY host (host),
KEY seq (seq),
KEY program (program),
KEY time (time),
KEY date (date),
KEY priority (priority),
KEY facility (facility)
) TYPE=MyISAM;
Ovviamente nel caso il file syslog_table non sia nella stessa directory dalla quale viene lanciato il client mysql
sara' necessario specificare il percorso del file in questione.
Una volta predisposta la parte relativa al database, e' stata aggiunta la seguente destinazione al file di configurazione di syslog-ng /etc/syslog-ng/syslog-ng.conf:
#file di destinazione con query sql che saranno processate dal feeder
destination file_sql {
file("/var/log/sqllog/log_sql_$HOUR.$MIN"
template("INSERT INTO logs (host, facility, priority, level, tag, date, time, program, msg) VALUES ( '$HOST', '$FACILITY', '$PRIORITY', '$LEVEL', '$TAG', '$YEAR-$MONTH-$DAY', '$HOUR:$MIN:$SEC','$PROGRAM', '$MSG' );\n")
template_escape(yes));
};
Questa direttiva fa in modo che all'interno del file /var/log/sqllog/log_sql_ORA.MINUTO vengano inserite una serie di istruzioni INSERT SQL che una volta eseguite dal client mysql andranno ad inserire i dati nella tabella logs del database db_syslog.
A meno che nel file di configurazione di syslog-ng non sia posta a yes l'opzione create_dirs sara' necessario creare la directory /var/log/sqllog ed impostare dei permessi coerenti con le opzioni owner, group, perm, dir_owner, dir_group e dir_perm se definite nel file di configurazione di syslog-ng.
Inoltre, come si puo' notare dall'opzione file della direttiva destination, non verra' creato un singolo file ma diversi a seconda dell'ora e del minuto in cui verranno generati. Tale scelta si e' resa necessaria per semplificare la creazione e l'esecuzione dello shellscript che eseguira effettivamente gli inserimenti nek database e che verra' successivamente illustrato.
Infine, la nuova destinazione creata dovra' essere utilizzata all'interno di una direttiva log del file /etc/syslog-ng/syslog-ng.conf perche' qualcosa possa essere scritto all'interno del file /var/log/sqllog/log_sql_ORA.MINUTO:
#log query per il feeder
log { source(s_all); destination(file_sql); };
Con questa configurazione, pero', nessun dato viene ancora scritto all'interno del database ma vengono solo scritte delle istruzioni INSERT nei file /var/log/sqllog/log_sql_ORA.MINUTO.
E' quindi necessario creare uno script che prenda questi file e inserisca effettivamente i log all'interno del database, ad esempio /opt/syslg-db/feeder.sh:
#!/bin/bash
# Script adattato da process_logs di Casey Allen Shobe
dbhost="localhost"
dbuser="syslog_user"
dbpass="syslog_password"
dbname="db_log"
datadir="/var/log/sqllog"
while true; do
logfiles=`find $datadir -name "log_sql_[0-2][0-9].[0-5][0-9]"`
sleep 70 # This is to ensure we don't screw up a log currently being written.
for logfile in $logfiles; do
cat $logfile | mysql --user=$dbuser --password=$dbpass $dbname
if [ $? -ne 0 ]; then
echo "[ERRORE] Problema nel processare il file $logfile!!!" >> $datadir"/feeder_log.log"
#exit 1 #Comment out this line if you want the script to
else
echo "[OK] $logfile inserito nel db in data `date --rfc-3339=seconds`" >> $datadir"/feeder_log.log"
rm -f $logfile
fi
done
done
Nella parte iniziale dello script vengono definite alcune variabili d'ambiente che indicano i parametri da utilizzare per la connessione al database e la directory dove si trovano i files scritti da syslog-ng contenenti le istruzioni inserti da eseguire.
Un aspetto importante dello script e' l'istruzione sleep 70
eseguita all'interno del ciclo while dopo avere settato la variabile contenente i nomi dei file da processare durante l'iterazione corrente. Quando eseguita essa sospende l'esecuzione dello script per 70 secondi, in modo da impedire che possa essere processato un file in corso di scrittura da parte di syslog-ng.
Poiche' la destination definita nel file di configurazione di syslog-ng, prevede la creazione di un nuovo file di log ogni minuto (grazie all'utilizzo della macro $MIN), con una sleep di 70 secondi si avra' la sicurezza che i files definiti nella variabile logfiles non siano piu' oggetto di scrittura, essendo trascorsi almeno 60 secondi dalla loro creazione.
Per ognuno di questi file, infine, vengono eseguite le istruzioni INSERT in essi contenute passandole in input al client mysql tramite la linea cat $logfile | mysql --user=$dbuser --password=$dbpass $dbname
.
Una volta processato, il file viene rimosso tramite il comando rm -f
. Lo script verifica inoltre l'exit code del comando mysql ed in base ad esso scrive l'esito del processing del file in /var/log/sqllog. Questa operazione puo' anche essere considerata superflua ed evitata semplicemente commentando le due istruzioni echo
all'interno del ciclo for.
Infine, per automatizzare l'utilizzo dello script feeder.sh e' possibile modificare lo script /etc/syslog-ng/syslog-ng in modo da avviare e terminare automaticamente feeder.sh insieme al syslog server:
#!/bin/sh
#
[...]
start() {
echo -n $"Starting $prog: "
daemon $exec $SYSLOGNG_OPTIONS
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
echo "Starting Feeder"
/opt/syslg-db/feeder.sh &
return $retval
}
stop() {
echo "Stopping Feeder"
killall feeder.sh
echo -n $"Stopping $prog: "
killproc $prog
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
[...]
La scrittura dei log all'interno di un database potrebbe essere utile per semplificare la ricerca dei messaggi in base a determinati criteri o semplicemente visualizzarli tramite qualche interfaccia web scritta in php o con qualche altro linguaggio.
Una delle applicazioni piu' note in tal senso e' forse php-syslog-ng.
Nel caso specifico illustrato i log sono stati invece memorizzati su un database per potere poi essere consultati tramite un plugin di cacti chiamato h.aloe.
Anche se memorizzati in maniera il piu' sicura possibile su un log-server remoto, l'utilita' dei log sarebbe abbastanza ridotta se l'amministratore di sistema dovesse limitarsi ad ignorarli completamente.
Un sistemista oberato di lavoro difficilmente avra' il tempo per tenere controllati accuratamente i log dei propri sistemi. Uno strumento utile in casi del genere potrebbe quindi essere logcheck. Certamente non puo' sostituire un'analisi attenta fatta di persona, ma e' sempre meglio di niente.
Facendo riferimento all'esempio dell'infobox su Syslog-ng, paranoid e' il nome dell'host monitorato, e stargazer quello su cui vengono replicati in remoto i log.
Si e' quindi provveduto ad installare logcheck su stargazer con il comando apt-get install logcheck
.
Per la sua configurazione si e' intervenuti sui seguenti files nella directory /etc/logcheck:
logcheck.conf
logcheck.logfiles
header.txt
In logcheck.conf per prima cosa e' stato modificata l'opzione DATE nel modo seguente DATE="$(date+'%H:%M %d/%m/%Y')", in modo che la data riportata nei subject delle mail inviate all'amministratore sia nel formato italiano anziche' americano.
E' stato impostato anche il livello di controllo da applicare ai messaggi(REPORTLEVEL), scegliendo tra workstation, server e paranoid. Si e' optato per il livello server.
In questo modo logcheck analizzera' tutte le stringhe contenenti le keywords e le regexp riportate nei files sotto le directory /etc/logcheck/cracking.d e /etc/logcheck/violation.d escludendo quelle che rispettano le espressioni regolari definite sotto /etc/logcheck/ignore.d.paranoid (Nota:il paranoid nel nome della directory non ha nulla a che vedere con il nome della macchina d'esempio).
Se ad esempio si fosse scelto il livello workstation sarebbero state ignorate anche le entries che avrebbero rispettato le espressioni regolari definite in ignore.d.server.
All'interno del file logcheck.logfiles sono invece stati elencati i files da monitorare. Nel caso dell'esempio fatto con syslog-ng, avendo diviso i log in sottodirectory, e' necessario riportare tra le entry all'interno di questo file, tutti i files .log, contenuti nelle directory relative ad anno e mese corrente per ogni host monitorato.
Ad esempio per il mese di dicembre 2005 in logcheck.logfiles saranno elencati tutti i files che dovrebbero essere sotto /var/log/hostnames/stargazer/2005/12/ e /var/log/hostnames/paranoid/2005/12/ .
Per evitare l'incombenza della modifica mensile del file logcheck.files si potrebbe utilizzare il seguente shellscript, gen-logfiles.sh:
#!/bin/bash
#estraggo anno e mese corrente
year=$(date +%Y)
month=$(date +%m)
#svuoto logcheck.logfiles del mese scorso
cat /dev/null > /etc/logcheck/logcheck.logfiles
#inserisco le nuove voci
for hostname in $(ls /var/log/hostnames/) ; do
echo /var/log/hostnames/$hostname/$year/$month/auth.log >> /etc/logcheck/logcheck.logfiles
echo /var/log/hostnames/$hostname/$year/$month/syslog >> /etc/logcheck/logcheck.logfiles
echo /var/log/hostnames/$hostname/$year/$month/cron.log >> /etc/logcheck/logcheck.logfiles
echo /var/log/hostnames/$hostname/$year/$month/daemon.log >> /etc/logcheck/logcheck.logfiles
echo /var/log/hostnames/$hostname/$year/$month/kern.log >> /etc/logcheck/logcheck.logfiles
echo /var/log/hostnames/$hostname/$year/$month/lpr.log >> /etc/logcheck/logcheck.logfiles
echo /var/log/hostnames/$hostname/$year/$month/mail.log >> /etc/logcheck/logcheck.logfiles
echo /var/log/hostnames/$hostname/$year/$month/user.log >> /etc/logcheck/logcheck.logfiles
echo /var/log/hostnames/$hostname/$year/$month/sshd.log >> /etc/logcheck/logcheck.logfiles
echo /var/log/hostnames/$hostname/$year/$month/debug >> /etc/logcheck/logcheck.logfiles
echo /var/log/hostnames/$hostname/$year/$month/messages >> /etc/logcheck/logcheck.logfiles
echo /var/log/hostnames/$hostname/$year/$month/log.emerg >> /etc/logcheck/logcheck.logfiles
echo /var/log/hostnames/$hostname/$year/$month/mail.crit >> /etc/logcheck/logcheck.logfiles
echo /var/log/hostnames/$hostname/$year/$month/mail.info >> /etc/logcheck/logcheck.logfiles
echo /var/log/hostnames/$hostname/$year/$month/mail.warn >> /etc/logcheck/logcheck.logfiles
done
Per automatizzare tutte le operazioni di controllo dei log, sono state inserite le seguenti linee in /etc/cron.d/logcheck:
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
@reboot logcheck if [ -x /usr/sbin/logcheck ]; then nice -n10 /usr/sbin/logcheck -R; fi
3 * * * * logcheck if [ -x /usr/sbin/logcheck ]; then nice -n10 /usr/sbin/logcheck; fi
0 0 1 * * /etc/logcheck/gen-logfiles.sh
La prima linea imposta la variabile d'ambiente PATH, in modo che non ci siano problemi nell'invocare i vari programmi all'interno dello shellscript /usr/sbin/logcheck
.
La seconda indica di eseguire logcheck ad ogni reboot della macchina, mentre la terza al terzo minuto di ogni ora.
Oltre ad eseguire logcheck , inoltre, tramite il comando nice viene alzato di 10 unita' il valore relativo alla priorita' del processo. Poiche' Il range di valori ammissibile va infatti da -20 (priorita' massima) a 19 (priorita' minima), l'effetto del comando e' quello di assegnare una priorita' piu' bassa.
L'ultima linea consente di eseguire lo script gen-logfiles.sh alla mezzanotte del primo giorno del mese.
L'ultimo file di configurazione, header.txt, contiene l'intestazione delle mail di avviso inviate dopo i controlli da parte di logcheck. Nel mio caso ho lasciato invariata l'intestazione di default:
This email is sent by logcheck. If you wish to no-longer receive it, you can either deinstall the logcheck package or modify its
configuration file (/etc/logcheck/logcheck.conf).
Perche' l'utente logcheck possa accedere ai files sotto la directory /var/log/hostnames, e' stato necessario aggiungerlo al gruppo sys_operators, con il comando gpasswd -a logcheck sys_operators
. Nella configurazione di syslog-ng trattata nel relativo infobox, si e' infatti scelto di associare il gruppo sys_operators ai log ed alle loro directory, sensa consentire l'accesso ad altri utenti.
Infine, per non consentire il login al sistema all'utente logcheck, la sua password in /etc/shadow e' stata sostituita con il carattere *, e la sua shell in /etc/passwd impostata a /bin/false.
SuSE's log management is similar to the one used on every Unix.
The Syslog service, configured via the usual /etc/syslog.conf
file manages the system's logs.
Its default configurations are quite common in some parts:
/var/log/messages
receives every log except mail and news;
/var/log/mail
has all the logs about the mail system, who are also divided in further files according to the debug level: mail.info mail.warn mail.err
;
/var/log/news/
directory contains all the logs about the news service;
Other useful settings are:
/var/log/localmessages
receives all the messages from the local facilities (from local0 to local 7);
/dev/tty10
displays kernel warnings and all the errors (Alt+F10 to see them).
/var/log/warn
collects all the system warnings, errors and critical messages.
The syslogd used is the typical Linux variant of the BSD syslogd with support for a separated kernel logging daemon (klogd).
Log rotation facilities are, by deafult, left in the flexible hands of logrotate whose main configuration file /etc/logrotate.conf
is configured to add all the configuration includes in the /etc/logrotate.d/
directory.
The default settings provide a weekly rotation with a total retention of 4 weeks, but the configuration includes for single services (apache, samba, squid, fetchmail etc) tend to rotate logs when they reach a fixed size and keep a retention of 99 archived log files.
Other interesting logs are:
/var/log/update-messages
displays verbose messages and readmes about some updated packages;
/var/log/SaX.log /var/log/XFree86.0.log /var/log/kdm.log
all provide (similar) logs about the X Window system;
/var/log/boot.msg
sums up both the kernel and the system's services log related to the last boot;
/var/log/YaST2/
directory contains all the logs about YaST, amonth these you find y2logRPM
(the list of the installed RPMs).
If you install the sysreport package you can find the sar
logs in the /var/log/sa/
directory.
Logwatch e' uno strumento che permette l'analisi e il monitoraggio dei log.
E' molto semplice, versatile e flessibile in quanto permette di impostare il servizio che si vuole monitorare, il livello di monitoraggio, filtri customizzabili per il matching di pattern, periodi di tempo specifici ecc...
Oltre a questo e' possibile settare una mail a cui inviera' il report o un file dentro il quale salvarli.
I file e le directory principali di logwatch sono generalmente:
/etc/log.d/conf/logwatch.conf
: file di configurazione di logwatch;
/etc/log.d/conf/services/
: directory che contiene i file di configurazione per i diversi servizi i cui log possono essere processati da logwatch;
/etc/log.d/conf/logfiles/
: directory che contiene i file di configurazione per i file contenenti i log di diversi servizi;
/etc/log.d/scripts/shared/
: directory che contiene i filtri comuni per i servizi o logfiles;
/etc/log.d/scripts/logfiles/
: directory che contiene i filtri specifici per logfiles particolari;
/etc/log.d/scripts/services/
: directory che contiene i filtri attuali per i vari servizi.
Logwatch viene tipicamente schedulato in crontab per eseguire dei controlli periodici sui log di sistema ed inviarne il report via mail.
Per loggare su un syslog server Linux/Unix i log di un Cisco si deve intervenire sia sul router che sul server.
Su Cisco configurare lo IOS (conf term) per definire il syslog server (qui 10.0.0.20):
logging server 10.0.0.20
(opzionale, imposta il logging a livello 7: debug)
logging facility local2
logging trap 7
Sul syslog server Unix/Linux fare partire syslog con l'opzione di logging via rete (senza questo il syslogd non accetta messaggi via rete):
syslogd -r
e configurare /etc/syslog.conf per accettare i messaggi dal cisco (facility local2):
local2.* /var/log/cisco.log
La porta usata per il syslog via rete è la 514 UDP.
Considerare che syslog è un protocollo estremamente vulnerabile (accetta qualsiasi informazione, senza verificare contenuto o sorgente). E' opportuno limitare agli IP che servono (con packet filtering di vario tipo) l'accesso alla porta 514 di un syslog server.
la configurazione e il comportamento di syslog su Solaris è comune a quello di Linux e di altri Unix.
Il processo /usr/sbin/syslogd
viene fatto partire allo startup tramite un normale script di init, gestito da rc: /etc/init.d/syslog
.
Il suo file di configurazione è /etc/syslog.conf
e viene preprocessato da M4:
*.err;kern.notice;auth.notice /dev/sysmsg
*.err;kern.debug;daemon.notice;mail.crit /var/adm/messages
daemon.info /var/adm/messages
*.alert;kern.err;daemon.err operator
*.alert root
*.emerg *
#auth.notice ifdef(`LOGHOST', /var/log/authlog, @loghost)
mail.debug ifdef(`LOGHOST', /var/log/syslog, @loghost)
ifdef(`LOGHOST', ,
user.err /dev/sysmsg
user.err /var/adm/messages
user.alert `root, operator'
user.emerg *
)
Notare le righe con la stringa ifdef, queste, tramite m4, vengono considerate se il LOGHOST è associato ad un ip locale.
In /etc/hosts
si può definire quale IP corrisponde a LOGHOST. Per esempio:
127.0.0.1 localhost loghost
172.17.0.10 server.dominio.it server
Un comando utile, sopratutto in script custom, per scrivere una entry direttamente nel syslog è:
/usr/bin/logger [ -i ] [ -f file ] [ -p priority ] [ -t tag ] [ message ]
.