Apache e Log

Apache e i Log

Apache è il più famoso WebServer in circolazione, usato da milioni di siti web per fornire contenuti agli utenti.

Anche questo sito si appoggia ad Apache e, essendo dedicato alla sicurezza informatica, ovviamente ci sono alcuni accorgimenti che lo rendono più sicuro e performante!

L’aspetto fondamentale di ogni sito web e in generale di ogni server, è poter capire se, quando e perchè qualcosa non funziona a dovere. Come avrai intuito questo lavoro è demandato alle fasi di logging.

Apache ha due tipi di log principali: un log per gli errori e uno per gli accessi. Senza scendere troppo nei dettagli, ovviamente ogni volta che qualcuno visita il tuo sito viene generata una o più righe di log che, qualora i visitatori siano centinaia, tendono a sovrapporsi e “nascondere” le informazioni importanti.

I formati standard

Partiamo dal formato dei file di log standard.

LogFormat “%v:%p %h %l %u %t \”%r\” %>s %O \”%{Referer}i\” \”%{User-Agent}i\”” vhost_combined
LogFormat “%h %l %u %t \”%r\” %>s %O \”%{Referer}i\” \”%{User-Agent}i\”” combined
LogFormat “%h %l %u %t \”%r\” %>s %O” common
LogFormat “%{Referer}i -> %U” referer
LogFormat “%{User-agent}i” agent

Questi sono i 5 tipi predefiniti dei formati di log. L’ultima “parola” è ciò che a noi interessa. Serve per definire quel tipo/formato di log, ovvero se volessimo usare il formato che ci dice semplicemente “da dove arriva il visitatore” dovremo usare “referer” nella dichiarazione di log del virtual host che ci interessa

DocumentRoot /var/www/pippo.it
…..
CustomLog /var/log/httpd/pippo.com/referente.log referer

Niente di più facile ma…..un log che abbia veramente senso DEVE comprendere almeno i dati definiti nel “common”. Il problema è che nel file di log ci finirà TUTTO, cioè le richieste alla pagina pluto.html, la richiesta per il file css/stile.css, per il file script/jquery.js ecc ecc e, visto che noi siamo metodici, non vogliamo questo mischione difficile da leggere. Come possiamo fare allora?
Beh, usiamo le variabili env!!

Le variabili ENV

Se nel nostro virtual andiamo a inserire questa stringa

SetEnvIf Request_URI ^/assets/.* asset_path

stiamo dicendo ad Apache che, se nella Request_URI, ovvero nella richiesta al server, trova qualsiasi cosa che punta alla cartella /assets/, deve segnare questa richiesta con un “nome”, asset_path.
Cosa significa in parole povere?

Semplificando un po’, ipotizziamo che tu chieda al tuo browser di visitare il sito pippo.com. La richiesta arriva al server Apache che in pratica va nella DocumentRoot relativa a cercare la pagina principale (solitamente index.html o index.php ecc). Se la trova la manda al browser, che comincia a elaborarla e al suo interno troverà ad esempio un paio di css e un paio di javascript

A questo punto il browser richiederà i file css e js perchè deve “costruire” la pagina index.html affinchè noi si veda qualcosa e si possa iniziare a interagire col sito.
Come sicuramente avrai intuito quindi Apache genera una riga di log per ogni file css, js, immagine, icona ecc e le scrive nel file di log relativo. Se andiamo a vedere cosa c’è scritto nel file troveremo qualcosa del tipo

172.16.0.10 – – [25/Jun/2022:11:58:02 +0200] “GET /landing HTTP/2.0” 200 13763 “-” “Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36”
172.16.0.10 – – [25/Jun/2022:11:58:02 +0200] “GET /assets/css/jquery/jquery-ui.min.css HTTP/2.0” 200 8035
172.16.0.10 – – [25/Jun/2022:11:58:02 +0200] “GET /assets/img/bootstrap-icons/bootstrap-icons.css HTTP/2.0” 200 11718
172.16.0.10 – – [25/Jun/2022:11:58:02 +0200] “GET /assets/css/landing/theme.min.css?v=1.0 HTTP/2.0” 200 49651
172.16.0.10 – – [25/Jun/2022:11:58:02 +0200] “GET /assets/js/landing/theme.min.js HTTP/2.0” 200 3213
172.16.0.10 – – [25/Jun/2022:11:58:02 +0200] “GET /assets/js/xajax_messages.js?rnd=73080 HTTP/2.0” 200 2054

In un log reale tutto questo ti garantisco che sarà piuttosto confuso. Possiamo però impostare il nostro vhost con qualcosa di questo tipo:

LogFormat “%h %l %u %t \”%r\” %>s %b” common
LogFormat “%404h %404v %404t %404r %404>s” 404log
SetEnvIf Request_URI ^/assets/.* asset_path
SetEnvIf Request_URI ^/pluto/.* pluto_path
SetEnvIf Request_URI ^/admin/.* admin_path
CustomLog /var/log/ispconfig/httpd/pippo.com/assets.log common env=asset_path
CustomLog /var/log/ispconfig/httpd/pippo.com/pluto.log common env=pluto_path
CustomLog /var/log/ispconfig/httpd/pippo.com/admin.log common env=admin_path
CustomLog /var/log/ispconfig/httpd/pippo.com/access.log combined “expr=reqenv(‘asset_path’) != 1 && reqenv(‘pluto_path’) != 1 && reqenv(‘admin_path’) != 1”
CustomLog /var/log/ispconfig/httpd/pippo.com/404_vhosts_access.log 404log

Spiegazione

Setto il “common” nel classico modo.
Imposto che se è un errore 404, deve considerare il log 404log.
Se nella richiesta al server c’è /assets/qualsiasiCosa, setto la variabile env “asset_path”.
Se nella richiesta c’è /pluto/qualsiasiCosa, setto una env “pluto_path”
Se nella richiesta c’è /admin/QualsiasiCosa, setto “admin_path”
Se arriva una richiesta che corrisponde a “asset_path”, scrive nel file /var/log/ispconfig/httpd/pippo.com/assets.log
Se arriva una richiesta che corrisponde a “pluto_path”, scrive nel file /var/log/ispconfig/httpd/pippo.com/pluto.log
Se arriva una richiesta che corrisponde a “admin_path”, scrive nel file /var/log/ispconfig/httpd/pippo.com/admin.log
Se NON si tratta di asset_path, nè di pluto_path nè di admin_path scrive nel access.log
Se si tratta di una richiesta 404, scrive nel 404_vhost_access.log

Quindi, riassumendo,
una richiesta per pippo.com/assets/css/foglio_stile.css sarà loggata in /var/log/ispconfig/httpd/pippo.com/assets.log
una richiesta per pippo.com/assets/css/foglio_stile_ulteriore.css sarà loggata in /var/log/ispconfig/httpd/pippo.com/assets.log
una richiesta per pippo.com/admin/cartella/index.php sarà loggata in /var/log/ispconfig/httpd/pippo.com/admin.log
una richiesta per pippo.com/assets/css/foglio_stile_non_esistente.css sarà loggata in /var/log/ispconfig/httpd/pippo.com/404_vhost_access.log

In questo modo abbiamo la possibilità di avere un log specifico in cui abbiamo tutte le richieste agli “assets”, uno per le richieste a “admin” ecc.
Ovviamente non bisogna strafare e impostare log per ogni virgola/cartella/risorsa ma si deve ragionare bene sul perchè abbiamo necessità di separare i log. Un buon motivo può essere per l’integrazione con un sistema di analisi del traffico, che solitamente non necessita di conteggiare gli accessi ai css/js/immagini ecc ma solo alle pagine visitate.

Tutto qui…!!