Configurazioni Apache

Character set e language

Per default ogni pagina pubblicata da Apache viene annunciata come charset ISO-8859-1 (direttiva AddDefaultCharset on). Per servire delle specifiche pagine in altro set di caratteri (esempio cirillico con il set WINDOWS-1251 o cinese semplificato con il set GB2312), si aggiungono le seguenti direttive nel file di configurazione di Apache:

<Directory /home/vill-ftp/www/>
    AddLanguage ru .ru
    AddLanguage zh .zh
    AddCharset WINDOWS-1251 .cp-1251 .win-1251
    AddCharset GB2312 .gb2312 .gb
</Directory>

Questo significa che rinominando i file .html con il suffisso .win-1251 oppure .gb2312 si forza il relativo set di caratteri. Con la doppia estensione si imposta lingua e set di caratteri; ad esempio index.html.zh.gb verrà annunciato come un file in lingua cinese e set di caratteri cinese semplificato.

Per i file PHP si possono aggiungere degli header in questo modo:

header("Content-Type: text/html; charset=gb2312");
header("Content-Language: zh");

oppure

header("Content-Type: text/html; charset=windows-1251");
header("Content-Language: ru");

Usare Unicode invece di ISO-8859-1

Per impostare il charset di default su Apache2 si mette la seguente riga dentro la sezione relativa al VirtualHost:

AddDefaultCharset utf-8

La direttiva può altrimenti essere specificata solo per una sezione <Directory>. Ovviamente si devono creare pagine in codifica UTF-8.

Bisogna stare attenti alla funzione htmlentities() del PHP, ad esempio la seguente sequenza di byte esadecimali <E2><80><99> rappresenta l'apostrofo rovesciato (backtik) in UTF-8, ma data in pasto ad htmlentities() viene convertita in &acirc;<80><99>.

Per fortuna la funzione htmlentities() accetta un terzo parametro, il charset. Purtroppo non si trova una combinazione per far funzionare tutto e sempre. Ad esempio htmlentities(UTF-8) non converte la o-umlaut in modo adatto all'Apache con DefaultCharset UTF-8:

Codifica Intenzione htmlentities(ISO-8859-1) htmlentities(UTF-8) Buono per Apache UTF-8
<E2><80><99> apostrofo &acirc;<80><99> &rsquo; <E2><80><99>
<F6> o-umlaut &ouml; <F6> &#246;

NOTA E' sbagliato codificare la o-umlaut in <F6>, quella sarebbe la codifica in Unicode puro, non la codifica UTF-8 che è invece <C3><B6>! Vedere codifica UTF-8 su http://www1.tip.nl/~t876506/utf8tbl.html.

NOTA Per convertire in/da UTF-8 in Perl vedere http://userpage.fu-berlin.de/~ram/pub/pub_jf47hxhHHt/perl_unicode_en.

Per la codifica UTF-8 in PHP si suggerisce:

echo htmlentities($string, ENT_COMPAT, 'UTF-8');

Configurare un modulo

Come specificare alcune opzioni valide per il modulo mod_autoindex. In una sezione Directory o VirtualHost, oppure al top level del file di configurazione di Apache:

# Allow more room for file names in auto indexes.
<IfModule mod_autoindex.c>
    IndexOptions NameWidth=45
</IfModule>

Autenticazione Base

Supportata da quasi tutti i browser, però la password transita in chiaro sulla rete (a meno che non si stia usando https). Nella directory da proteggere si mette un file di nome .htaccess con qualcosa del tipo:

AuthType Basic
AuthName "Area protetta"
AuthUserFile /etc/apache2/htpasswd
Require valid-user

Il file con le password va indicato con percorso assoluto oppure relativo alla directory di configurazione di Apache. Per gestire le password si usa il comando htpasswd, possibilmente con l'opzione -m. Il file .htpasswd può essere messo anche direttamente nella directory da proteggere, leggibile ad Apache ma possibilmente non a tutti gli altri:

-rw-r--r--  1 root root     143 Feb 23 12:02 .htaccess
-rw-r-----  1 root www-data  50 Feb 23 12:00 .htpasswd

A livello di configurazione generale, verificare che l'accesso ai file .ht sia inibito e che la directory da proteggere abbia il giusto AllowOverride:

<Files ~ "^\.ht">
    Order allow,deny
    Deny from all
</Files>

<Directory /path/to/directory/>
    AllowOverride AuthConfig Limit
</Directory>

Autenticazione Digest

Rispetto all'autenticazione base c'è una maggiore sicurezza in quanto la password non transita in chiaro sulla rete, viene trasmesso un digest della password invece del clear text. Per attivare l'autenticazione di tipo Digest su una directory si aggiunge questa sezione al file di configurazione di Apache:

<Directory /var/www/niccolo/>
    BrowserMatch "MSIE" AuthDigestEnableQueryStringHack=On
    AllowOverride AuthConfig
</Directory>

Notare l'hack che Apache deve fare in modo che l'autenticazione Digest funzioni anche con il difetto di Internet Explorer. Nella directory da proteggere si salva questo file .htaccess e il relativo file .htpasswd:

Per Apache 2.2

# Per aggiungere un utente al file delle password:
# htdigest [-c] .htpasswd realm_name user1
AuthType Digest
AuthName "private area"
AuthDigestDomain /private/ http://mirror.my.dom/private/
AuthDigestProvider file
AuthUserFile /var/www/niccolo/.htpasswd
Require valid-user

Per Apache 2.0 e precedenti

# Per aggiungere un utente al file delle password:
# htdigest [-c] .htpasswd realm_name user1
AuthType Digest
AuthName "private area"
AuthDigestFile /var/www/niccolo/.htpasswd
Require user user1 user2

Il file con le password si gestisce con htdigest e contiene righe del tipo:

username:realm:0762ba1444823379febd9e3f9eb7c0aa

Autenticazione MySQL

Per Debian 4.0 (Sarge) non c'è il pacchetto libapache2-mod-auth-mysql, per fortuna si riesce ad installare quello per Debian Testing, almeno per ora. Giusto per sicurezza lo salvo anche qui: libapache2-mod-auth-mysql_4.3.9-3_i386.deb.

Nella configurazione globale di Apache ci vuole:

#--------------------------------------------------------------------------
# MySQL authentication: default access to the database.
#--------------------------------------------------------------------------
AuthMySQL_DefaultHost localhost
AuthMySQL_DefaultUser guest
AuthMySQL_DefaultPassword guest
AuthMySQL_AllowOverride On

Poi nella directory da proteggere si crea il file .htaccess con:

AuthName "Accesso riservato"
AuthType Basic
AuthBasicAuthoritative Off
Auth_MYSQL on

AuthMySQL_Host localhost
AuthMySQL_User username
AuthMySQL_Password secret

Auth_MySQL_DB dbname
Auth_MySQL_Password_Table user_auth
Auth_MySQL_Username_Field user_name
Auth_MySQL_Password_Field user_passwd

Auth_MySQL_Encrypted_Passwords Off
Auth_MySQL_Scrambled_Passwords Off
Auth_MySQL_Empty_Passwords Off

Auth_MySQL_Group_Table user_group
Auth_MySQL_Group_Field user_group

require valid-user

Importante è la direttiva AuthBasicAuthoritative Off, che non si trova documentata (forse non serviva con Apache 2.0?). In pratica senza questa direttiva viene comunque tentata l'autenticazione su file che fallisce e quindi quella su MySQL non viene neanche provata.

Autenticazione su /etc/shadow

Per autenticare gli utenti su /etc/passwd e /etc/shadow si potrebbe usare il modulo Apache di autenticazione PAM, però sarebbe necessario che apache avesse i permessi di lettura su /etc/shadow, il che non è il massimo del godimento.

Per fortuna esiste il modulo Apache mod-auth-shadow, che deve essere espressamente compilato per Apache oppure per Apache2.

In Debian il pacchetto ha subito varie vicissitudini, entrando ed uscendo dalla distribuzione ufficiale. Il risultato purtroppo è che non esiste per Apache2 né in Etch né in Lenny. Per forunta è facile ricompilarlo dai sorgenti Debian o Ubuntu.

Qui trovate un backport per Etch della versione 2.1, qui invece la versione per Lenny.

Il file di configurazione di Apache deve essere qualcosa di simile:

<Directory /var/www/admin/>
     AuthType Basic
     AuthName "Area riservata di amministrazione"
     AuthShadow on
     # AuthAuthoritative for Apache 2.0
     # AuthBasicAuthoritative for Apache 2.2
     AuthBasicAuthoritative Off
     AuthUserFile /dev/null
     Require user niccolo angela
</Directory>

Attenzione, la direttiva AuthUserFile /dev/null serve perché Apache comunque tenta l'autenticazione Basic (sebbene non autoritativa) aprendo un file password, se non lo specifichiamo si ottengono continui messaggi di errore nel log di Apache:

[Fri Sep 07 16:14:46 2007] [error] Internal error: pcfg_openfile() called with NULL filename

Controllo di accesso su indirizzo IP

Per consentire l'accesso ad una directory solo a determinati indirizzi IP:

<Directory /var/www/private_dir>
    Order deny,allow
    Deny from all
    Allow from 88.57.16.27 87.241.56.133
</Directory>

La notazione supportata da Allow è molteplice:

Allow from .net example.edu A (partial) domain-name
Allow from 192.168.1.104 192.168.1.205 Full IP address
Allow from 10 172.20 192.168.2 Partial IP address
Allow from 10.1.0.0/255.255.0.0 Network/netmask pair
Allow from 10.1.0.0/16 Network/nnn CIDR specification

Logging degli errori PHP

In un sito pubblico conviene nascondere gli errori PHP (non farli vedere nella pagina web), ma piuttosto loggarli in un file apposito, questa non è la configurazione predefinita Debian Lenny. Per attivare questo:

mkdir /var/log/php
touch /var/log/php/error.log
chown www-data:adm /var/log/php/error.log
chmod 640 /var/log/php/error.log

mentre nel file /etc/php5/apache2/php.ini ci deve essere:

display_errors = Off
log_errors = On
error_log = /var/log/php/error.log

Ricordarsi di ruotare il file di log con un opportuno /etc/logrotate.d/.

Per un sito in fase di sviluppo è comodo visualizzare gli errori direttamente nella pagina web, se questo è disabilitato a livello globale, è possibile abilitarlo localmente con delle direttive in un file .htaccess:

php_flag display_errors on
php_flag display_startup_errors on
# See http://www.php.net/manual/en/errorfunc.constants.php
# 1     E_ERROR
# 2     E_WARNING
# ...
# 32767 E_ALL
php_value error_reporting 32767

Directory e Location

Le direttive <Directory> e <Location> si assomigliano molto, la differenza sostanziale è che Directory è intesa per lavorare a livello di filesystem, mentre Location è intesa a livello di URL.

Rewrite

Esempio di rewrite da impostare in un file .htaccess per ridirigere tutte le richieste example.com verso www.example.com o viceversa:

RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^/(.*)$ http://www.example.com/$1 [L,R=301]
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteRule ^/(.*)$ http://example.com/$1 [L,R=301]

Il flag [NC] significa no case sensitive, il flag [L] significa last rule (non se ne applicano altre), il flag [R] indica di effettuare un redirect con status code 301 Moved Permanently.

Per vedere quali regole di rewrite vengono appicalte si abilita temporaneamente nella sezione VirtualHost:

RewriteLog "/tmp/rewrite.log"
RewriteLogLevel 2

Certificato SSL

Per creare una chiave RSA e il certificato autofirmato si crea un file di configurazione /etc/apache2/ssl/www.rigacci.org.cnf:

#----------------------------------------------------------------
# Create an RSA key and a self-signed Certificate with the
# following command:
#
# openssl req -config /etc/apache2/ssl/file.cnf \
#     -new -x509 -days 1095 -nodes \
#     -keyout /etc/apache2/ssl/file.pem \
#     -out /etc/apache2/ssl/file.pem
#
# The resulting file (unencrypted otherwise Apache can't start
# automatically) will contains the RSA private key, so be sure
# to set its mode to 0400.
#----------------------------------------------------------------

[ req ]
prompt                          = no
default_bits                    = 1024
distinguished_name              = www.rigacci.org_distinguished_name

[ www.rigacci.org_distinguished_name ]
countryName                     = IT
stateOrProvinceName             = Italy
localityName                    = Firenze
organizationName                = Niccolo Rigacci
organizationalUnitName          = computer consultant
commonName                      = www.rigacci.org
emailAddress                    = webmaster@rigacci.org

Poi si esegue il comando openssl come scritto nel commento sopra. Invece nel file di configurazione di Apache (in default o in qualche VirtualHost) si mette:

SSLCertificateFile ssl/www.rigacci.org.pem
doc/appunti/linux/sa/apache.txt · Last modified: 2011/09/15 09:02 by niccolo
 
Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki