Per determinare se un dato client può accedere ad una risorsa, Apache esegue una serie di controlli divisa in più fasi:
1- Apache tramite il modulo mod_access verifica se l'IP del client può accedere alla risorsa richiesta
2- Si richiedono informazioni aggiuntive al client come username e password.
Il modulo mod_access viene comunemente utilizzato per l'host-based authentication ed è possibile eseguire il matching delle regole per il controllo degli accessi tramite alcuni parametri come ip, hostname e HTTP headers.
Le direttive gestite dal modulo sono allow, deny e order.
Controllo dell'accesso tramite il nome di un host
Abilita l'accesso ad uno specifico host openskills.info
allow from
openskills.info
Abilita l'accesso a tutti gli host del dominio openskills.info
allow from
.openskills.info
Nega l'accesso a tutti gli host del dominio openskills.info
deny from
.openskills.info
Le direttive allow e deny, rispettivamente, permettono o negano l'accesso alle risorse quando l'host client matcha il criterio per cui è valida la direttiva. Nel caso in cui si debbano includere nella configurazione entrambe le direttive per gestire l'accesso alla stessa risorsa bisogna affiancarle alla direttiva order per determinare l'ordine con cui vengono lette le direttive allow e deny. Per esempio:
Implementa policy permissive: lascia accedere tutti gli Host tranne quelli del dominio openskills.info:
order allow,deny
allow from all
deny from openskills.info
Implementa policy restrittive: blocca tutti gli accessi tranne quelli di host del dominio openskills.info
order deny,allow
deny from all
allow from openskills.info
Controllo dell'accesso tramite IP
Soluzione ideale rispetto all'utilizzo dei nomi, poichè non obbliga il web server a eseguire reverse lookup DNS per ottenere i nomi di host dall'IP. Nell'esempio che segue viene permesso l'accesso solo dai range di IP specificati:
<Directory />
order deny,allow
deny from all
allow from 127.0.0.1 192.168.208 10.0.0.0/8 192.168.215.0/255.255.249.0
</Directory>
E' possibile specificare un singolo IP oppure una network intera o una subnet, in questi due ultimi casi occorre specificare la netmask, è permesso utilizzare la nomenclatura in cui si specificano semplicemente i bit che identificano l'indirizzo di rete (permessi solo 8 16 24) o semplicemnte evitando di scrivere gli zeri (192.168) oppure scrivendo la netmask in formato esteso (255.255.255.0).
Controllo degli accessi tramite i HTTP header
Una possibile alternativa è quello di affiancare alle direttive allow e deny le direttive BrowserMatch e SetEnvIf per negare o abilitare l'accesso ad una risorsa a seconda di una definibile variabile d'ambiente.
BrowserMatch ^Mozilla*
<Directory /mozilla/>
order deny,allow
deny from all
allow from env=netscape_browser
</Directory>
Questa funzionalità apre un universo di possibilità che permettono operazioni piuttosto sofisticate come permettere l'accesso solo se il Referrer è di un certo tipo, impedire l'accesso a robot che si presentano con User Agent identificabili, a spider/crawler/site grabbers ecc.
L'user authentication è un modo avanzato per eseguire un controllo degli accessi via web a determinati file o directory sulla base di login e password configurabili.
Tramite moduli autonomi, Apache supporta diversi metodi per gestire i dati relativi a login e password, che si basano su basi date diverse.
Moduli standard
- mod_auth : Autenticazione base con file di testo
- mod_auth_anon : Autenticazione anonima
- mod_auth_dbm : Autenticazione con DBM database
- mod_auth_db : Per i sistemi che DB database
- mod_digest : Digest Authentication con file
Moduli sviluppati da terze parti
- mod_auth_msql : Autenticazione base con supporto di MSQL
- mod_auth_mysql : Autenticazione base con supporto di MYSQL
- mod_auth_ldap : Autenticazione base con supporto di LDAP
- mod_auth_kerberos : Autenticazione base con supporto di kerberos
- mod_auth_radius : Autenticazione base con supporto di radius
- mod_auth_smb : Autenticazione base con Windows
- mod_auth_oracle : Autenticazione base con supporto di Oracle
Per avere una lista completa si può fare riferimento al sito ufficiale http://modules.apache.org/
Da tenere conto che i moduli sviluppati da terze parti, cioè non sviluppati dal core team di Apache, non sono stati testati a fondo e richiedono a volte un'intervento massiccio per l'installazione causa dipendenze con librerie che nell'installazione standard di Linux e di Apache sono escluse.
Qualunque sia il modulo utilizzato vengono sempre richieste le seguenti direttive per abilitare l'user authentication:
AuthName
Il nome o il realm che Apache invia al modulo che si occupa dell'autenticazione per definire le varie "zone" che richiedono l'autenticazione. E' una stringa di testo definibile arbitrariamente, che viene visualizzata nella finestra di richiesta Nome Utente e Password del browser.
AuthName "Area Clienti"
AuthType
E' la direttiva che si occupa di inviare username e password, può acquisire due valori Basic e Digest, la differenza primaria è che la configurazione "Digest", a differenza di quella "Basic", invia username e password criptati utilizzando MD5, sfortunatamente non è del tutto supportata.
AuthType Basic
Auth???UserFile
Ogni modulo ha una specifica direttiva per indicare dove Apache troverà le informazioni per eseguire il check su password ed utente.
Per il modulo mod_auth avremo
AuthUserFile /usr/local/apache/private/passwd
Oppure per il modulo mod_auth_dbm
AuthDBMUserFile /usr/local/apache/private/passwd.dbm
Direttiva opzionale per definire il gruppo
E' possibile tramite la direttiva Auth???GroupFile aggiungere un ulteriore check per l'autenticazione, aggiungendo il criterio del gruppo di appartenenza. Come sopra avremo una direttiva specifica per ogni modulo (non tutti i moduli la supportano)
Per il modulo mod_auth avremo
AuthGroupFile /usr/local/apache/private/group
Oppure per il modulo mod_auth_dbm
AuthDBMGroupFile /usr/local/apache/private/group.dbm
Require
Direttiva che permette di determinare quale criterio è assolutamento valido per abilitare l'accesso alla risorsa:
require valid-user
Auth???Authoritative
Altra direttiva opzionale che permette di determinare quale tipo di autenticazione è autoritativa rispetto ad un altra, quando si hanno più tipi di autenticazioni attive sulla stessa risorsa.
Genericamente tutti i tipi di autenticazione seguono il seguente schema:
<Location /private>
AuthName "Nome del realm"
AuthType Basic | Digest
Auth???UserFile /path/to/user/file
Auth???GroupFile /path/to/group/file
require valid-user | user utente1 utente2... | group gruppo1 gruppo2 ...
Auth???Authoritative on | off
</Location>
Anche nel caso dell'user authentication è possibile utilizzare il file .htaccess, anche se non è abilitato di default. Per abilitare tutte le direttive per l'autenticazione occorre appoggiarsi ad AllowOverride:
AllowOverride AuthConfig
Se host-based e User authentification sono applicati alla stessa risorsa bisogna specificare se dovranno essere soddisfatte entrambe o solo una delle due per accedere la risorsa.
Questo è possibile tramite la direttiva Satisfy
Per accedere alla risorsa occorre soddisfare entrambe le direttive
Satisfy all
Per accedere alla risorsa occorre soddisfare solo una delle direttive
Satisfy any
Segue un esempio di configurazione che permette libero accesso da IP specificati (una rete interna) e richiede username e password per client esterni.
<Location /user/>
AuthName "STAFF ONLY"
AuthType Basic
AuthDBMUserFile /usr/local/apache/conf/pwd.dbm
require valid-user
order deny,allow
deny from all
allow from 192.168.100
Satisfy any
</Location>
L'autenticazione "Base" è quella più comunemente utilizzata più che altro per il fatto che è supportata da tutti i browser.
Di fatto tutti i moduli tranne mod_digest utilizzano l'autenticazione base anche se richiedono di specificarla tramite la direttiva AuthType.
Quando un Browser richiede una risorsa protetta, Apache replica con un messaggio di mancata autorizzazione per accedere alla risorsa (status code 401) che contiene l'header WWW-Authentificate: ed il nome della zona (o realm) configurata tramite la direttiva AuthName:
WWW-Authentification: Basic realm="Area Clienti"
Quando il client riceve la risposta, apre un pop-up in cui e' possibile inserire user e password e reinvia la richiesta al server aggiungendo le informazioni aggiuntive (pwd e user) nell'Authorization header.
Prima parte dell'header
Authorization: BASIC kheSrkSlrJflvbFvaFfsgHhl
Seconda parte dell'header contenente user e pwd (in chiaro)
user:password
A livello di configurazione su httpd.conf si trova:
<Location /private>
AuthName "Area Clienti"
AuthType "Basic"
AuthUserFile /usr/local/apache/auth/passwd.file
AuthGroupFile /usr/local/apache/auth/group.file
require user user1 user2
</Location>
Se al posto dell'autenticazione basata su normale file di testo, ci si basa un un DBM (tramite il mod_auth_dbm) la sintassi in httpd.conf diventa:
<Location /private>
AuthName "Configuration Example"
AuthType "Basic"
AuthDBMUserFile /usr/local/apache/auth/passwd.dbm
AuthDBMGroupFile /usr/local/apache/auth/group.dbm
require user user1 user2
</Location>
E' il secondo tipo di autenticazione supportato da Apache ed è gestito dal modulo mod_digest.
Lo scopo di questa autenticazione è quello di inviare user e password cryptati tramite MD5.
Ecco un esempio di configurazione:
<Directory /private>
AuthName "Area Clienti"
AuthType Digest
AuthDigestFile /usr/local/apache/auth/passwd.md5
require valid-user
</Directory>
Sfortunatamente l'uso della digest authentication è una soluzione poco sfruttabile poiché sono pochi i browser che supportano questo tipo di autenticazione. La soluzione comunemente utilizzata per inviare password e user in modalità cryptata è quella di abbinare la basic Authentication al protocollo HTTPS.
Gestita dal modulo mod_auth_anon richiede parametri aggiuntivi rispetto ad altri moduli.
E' paragonabile ad un accesso FTP anonimo, ma rimane comunque una soluzione poco utilizzata.
Le direttive disponibili sono:
Anonymous [list of user]
Lista di utenti che possono accedere alla risorsa. Questa direttiva disabilitata di default e non può essere utilizzata se la direttiva Anonymous_NoUserID è settata ad on
Anonymous_MustGiveEmail on | off
Se settata ad on (valore di default), richiede una e-mail come password
Anonymous_VerifyEmail on | off
Se settata ad on verifica l'esistenza dei caratteri "." e "@" nell'e-mail inserita. Di Default è disabilitata
Anonymous_LogEmail on | off
Se settata ad on, viene loggato l'indirizzo e-mail nell'access log ad ogni login effettuato con successo. Di default è disabilitata
Anonymous_NoUserID on |off
Se settata ad on il campo user può essere lasciato in bianco, disabilitata di default.
Esempio di configurazione:
<Location /private>
AuthName "Area Clienti"
AuthType Basic
Anonymous guest anonymous visitor operator
require valid-user
Anonymous_Authoritative on
Anonymous_MustGiveEMail on
Anonymous_VerifiEmail on
Anonymous_LogEmail on
Anonymous_NoUserID off
</Location>
La direttiva require permette di specificare per la singola area protetta, quali utenti ci possono accedere, l'authentication stage si preoccupa solo di verificare la corrispondenza user e password ma tramite questa direttiva si può avere un ulteriore filtro, permettendo così di utilizzare un singolo file di password per più aree (scelta sconsigliata).
La sintassi è la seguente:
require [user | group | valid-user] [lista di utenti o lista di gruppi]
Consente l'accesso solo all'utente pluto, dopo che ha superato con successo l'authentication stage, altri utenti, anche se correttamente autenticati, non possono accedere:
require user pluto
Consente l'accesso solo agli utenti pluto, pippo e admin dopo che hanno superato con successo l'authentication stage:
require user pippo pluto admin
Consente l'accesso a tutti gli utenti, dopo che hanno superato con successo l'authentication stage:
require user valid-user
Consente l'accesso a tutti gli utenti che appartengono al gruppo admin ovviamente solo dopo che ha superato con successo l'authentication stage:
require group admin
La sintassi delle entry del file contenente le correlazioni gruppo/utente, sono simili al file /etc/group, con la differenza che i singoli utenti di uno stesso gruppo non sono separati da un virgola ma da uno spazio.
Esempio delle entry del file /etc/group
[neo@dido neo]$ head -3 /etc/group
root:x:0:root
bin:x:1:root,bin,daemon
daemon:x:2:root,bin,daemon
Esempio delle entry del file group da specificare con la direttiva Auth???GroupFile
neo@dido neo]$ head -2 /usr/local/apache/auth/group
admin: webmaster pippo webmaster
operator: operator pluto neo
Apache permette l'utilizzo delle direttive order,allow,deny e Satisfy nella configurazione per-directory e tramite il file .htaccess se la direttiva Limit override è abilitata (di default lo è).
Per abilitare le direttive relative all'accesso:
AllowOverrides +Limit
Per disabilitare le direttive:
AllowOverrides -Limit
Tecnicamente la direttiva Satisfy è comunque permessa poichè non viene gestita dal modulo mod_access ma dal core di Apache, ma questo fa ben poca differenza se le direttive allow e deny sono disabilitate.
Il passo successivo alla configurazione del proprio server web con un accesso tramite login e password è quello di creare un file di password e, eventualmente uno di gruppi.
A seconda del tipo di autenticazione utilizzata (Basic o Digest) e dal modulo che gestice il check esistono varie utility, già presenti nel pacchetto base di Apache.
htpasswd
Utility per creare e gestire i file (plain-text no db o dbm) che contengono la corrispondenza user e password per l'autenticazione Basic. L'uso è molto simile al comando passwd:
Creazione del file passwd con l'inserimento del primo utente pippo
htpasswd -c /usr/local/apache/auth/passwd pippo
Aggiunta dell'utente paperino ad un file esistente
htpasswd /usr/local/apache/auth/passwd paperino
dbmmanage
Script in perl che permette di gestire i file (o meglio database) db e dbm:
Creazione dell'utente pippo con dbmmanage
dbmmanage password.dbm adduser pippo
htdigest
Utility equivalente a htpasswd (in piu' occorre specificare il realm) ma per l'autenticazione digest:
Creazione del file passwd con l'inserimento del primo utente
htdigest -c /usr/local/apache/auth/passwd "area clienti" pippo
Per creare e gestire i file per l'autenticazione utente Basic di Apache.
Per la creazione di un nuovo passwd file
htpasswd -c [opzioni] passwdfile username
Per aggiungere semplicemente un utente ad un passwd esistente
htpasswd [opzioni] passwdfile username
Per printare in stdout quello che verrebbe scritto nel passwd file, utile se si deve copiare il risultato in un db come mysql
htpasswd -nb [opzioni] username password
-b
Abilita il batch mode, la password viene presa dalla linea di comando, con tutti gli incovenienti del caso.
-c
Crea il passwd file se non esiste, altrimenti lo sovrascrive.
-n
Mostra il risultato del comando in stdout, non può essere combinata con l'opzione -c
Utility per la creazione e management del file contenente la correlazione password e utente per l'autenticazione di tipo Digest di Apache.
htdigest [ -c ] passwdfile realm username
-c
crea il file passwd, se esiste lo sovrascrive.
Perl script per la gestione e creazione dei file dbm, utilizzati, fra le altre cose, per l'autenticazione utente tramite Apache.
dbmmanage filename-db [ command ] [ username [ encpasswd ] ]
Comandi:
add
Aggiunge un utente ed è l'unico comando che permette di specificare la password cryptata e i gruppi a cui appartiene il nuovo utente
adduser
Aggiunge un utente, viene richiesto di inserire la password
check
Esegue il check della password inserita nel db con quella fornita da noi per un utente esistente
delete
Cancella un utente
import
Legge "User:password" dallo stdin
update
Esegue un update della password
view
Mostra il contenuto del db
Utilizzi più comuni del comando dbmmanage.
[root@morpheus auth]# ls -l
totale 0
Creazione dell'utente pippo, se il db non esiste viene creato
[root@morpheus auth]# dbmmanage passwd.dbm adduser pippo
New password:
Re-type new password:
User pippo added with password encrypted to E73kpaKh4du3I using crypt
[root@morpheus auth]# ls -l
totale 8
-rw-r--r-- 1 root root 8192 nov 15 13:49 passwd
Visualizzazione della entry relativa all'utente pippo
[root@morpheus auth]# dbmmanage passwd.dbm view pippo
pippo:E73kpaKh4du3I
Creazione dell'utente tramite il comando adduser
[root@morpheus auth]# dbmmanage passwd.dbm adduser pluto
New password:
Re-type new password:
User pluto added with password encrypted to C5tErlEabAsUw using crypt
Cancellazione dell'utente
[root@morpheus auth]# dbmmanage passwd.dbm delete pluto
`pluto' deleted
Inserimento definitivo specificando i gruppi:
[root@morpheus auth]# dbmmanage passwd.dbm add pluto C5tErlEabAsUw:user,admin
User pluto added with password encrypted to C5tErlEabAsUw:user,admin using crypt
Verifica della password dell'utente pluto
[root@morpheus auth]# dbmmanage passwd.dbm check pluto
Enter password:
crypt password ok
Visualizzazione di tutto il db
[root@morpheus auth]# dbmmanage passwd.dbm view
pippo:E73kpaKh4du3I
pluto:C5tErlEabAsUw:user,admin
Prassi per la creazione di un passwd per Apache con htpasswd.
[root@morpheus /root]# cd /usr/local/apache/auth/
[root@morpheus auth]# ls -l
totale 0
Creazione del file passwd e inserimento del primo utente pippo
[root@morpheus auth]# htpasswd -c passwd pippo
New password:
Re-type new password:
Adding password for user pippo
[root@morpheus auth]# ls -l
totale 4
-rw-r--r-- 1 root root 20 nov 15 13:14 passwd
Visualizzazione del contenuto del file passwd
[root@morpheus auth]# cat passwd
pippo:50JjuGahgWGg2