1227 lines
35 KiB
Markdown
1227 lines
35 KiB
Markdown
---
|
||
categories: web
|
||
title: Howto Apache
|
||
...
|
||
|
||
* Documentation : <https://httpd.apache.org/docs/2.4/>
|
||
* Rôle Ansible : <https://forge.evolix.org/projects/ansible-roles/repository/show/apache>
|
||
|
||
[Apache](https://httpd.apache.org/) est le serveur [HTTP](HowtoHTTP)
|
||
le plus utilisé sur le web depuis 1996.
|
||
|
||
## Installation
|
||
|
||
Nous utilisons la version [Apache-ITK](http://mpm-itk.sesse.net/)
|
||
depuis des années en production sur de nombreux serveurs critiques.
|
||
Apache-ITK permet de préciser pour chaque VirtualHost un utilisateur,
|
||
un groupe et une option *MaxClients* spécifiques, ce qui est utile
|
||
pour la sécurité d'un serveur multi-sites.
|
||
|
||
~~~
|
||
# apt install apache2 libapache2-mpm-itk libapache2-mod-evasive apachetop libwww-perl
|
||
|
||
# apache2ctl -V
|
||
Server version: Apache/2.4.25 (Debian)
|
||
Server built: 2017-07-18T18:37:33
|
||
Server's Module Magic Number: 20120211:68
|
||
Server loaded: APR 1.5.2, APR-UTIL 1.5.4
|
||
Compiled using: APR 1.5.2, APR-UTIL 1.5.4
|
||
Architecture: 64-bit
|
||
Server MPM: prefork
|
||
threaded: no
|
||
forked: yes (variable process count)
|
||
Server compiled with....
|
||
-D APR_HAS_SENDFILE
|
||
-D APR_HAS_MMAP
|
||
-D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
|
||
-D APR_USE_SYSVSEM_SERIALIZE
|
||
-D APR_USE_PTHREAD_SERIALIZE
|
||
-D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
|
||
-D APR_HAS_OTHER_CHILD
|
||
-D AP_HAVE_RELIABLE_PIPED_LOGS
|
||
-D DYNAMIC_MODULE_LIMIT=256
|
||
-D HTTPD_ROOT="/etc/apache2"
|
||
-D SUEXEC_BIN="/usr/lib/apache2/suexec"
|
||
-D DEFAULT_PIDLOG="/var/run/apache2.pid"
|
||
-D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
|
||
-D DEFAULT_ERRORLOG="logs/error_log"
|
||
-D AP_TYPES_CONFIG_FILE="mime.types"
|
||
-D SERVER_CONFIG_FILE="apache2.conf"
|
||
|
||
# systemctl status apache2
|
||
● apache2.service - The Apache HTTP Server
|
||
Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset:
|
||
Process: 32127 ExecReload=/usr/sbin/apachectl graceful (code=exited, status=0/
|
||
Process: 1857 ExecStart=/usr/sbin/apachectl start (code=exited, status=0/SUCCE
|
||
Main PID: 2031 (apache2)
|
||
Tasks: 6 (limit: 4915)
|
||
CGroup: /system.slice/apache2.service
|
||
├─ 2031 /usr/sbin/apache2 -k start
|
||
├─32134 /usr/sbin/apache2 -k start
|
||
├─32135 /usr/sbin/apache2 -k start
|
||
├─32136 /usr/sbin/apache2 -k start
|
||
├─32137 /usr/sbin/apache2 -k start
|
||
└─32138 /usr/sbin/apache2 -k start
|
||
~~~
|
||
|
||
> *Note* : Pour Debian 8, il faut installer ainsi :
|
||
>
|
||
> ~~~
|
||
> # apt install apache2-mpm-itk libapache2-mod-evasive apachetop libwww-perl
|
||
> ~~~
|
||
|
||
|
||
## Configuration de base
|
||
|
||
Fichiers de configuration :
|
||
|
||
~~~
|
||
/etc/apache2
|
||
├── apache2.conf
|
||
├── conf-available/
|
||
│ └── X.conf
|
||
├── conf-enabled/
|
||
│ └── X.conf -> ../conf-available/X.conf
|
||
├── envvars
|
||
├── magic
|
||
├── mods-available/
|
||
│ ├── X.load
|
||
│ └── X.conf
|
||
├── mods-enabled/
|
||
│ ├── X.load -> ../mods-available/X.load
|
||
│ └── X.conf -> ../mods-available/X.conf
|
||
├── ports.conf
|
||
├── sites-available/
|
||
│ ├── 000-default.conf
|
||
│ ├── default-ssl.conf
|
||
│ └── X.conf
|
||
└── sites-enabled/
|
||
│ ├── 000-default.conf -> ../sites-available/000-default.conf
|
||
└── X.conf -> ../sites-available/X.conf
|
||
~~~
|
||
|
||
La configuration principale se trouve dans le fichier
|
||
`/etc/apache2/apache2.conf` qui inclut de nombreux fichiers séparés.
|
||
|
||
Nous activons toujours au minimum les modules suivants :
|
||
|
||
~~~
|
||
# a2enmod rewrite expires headers rewrite cgi
|
||
~~~
|
||
|
||
Le fichier `/etc/apache2/conf-available/z-evolinux-defaults.conf`
|
||
contient nos optimisations basiques :
|
||
|
||
~~~{.apache}
|
||
ServerTokens Prod
|
||
Timeout 10
|
||
KeepAliveTimeout 2
|
||
MaxKeepAliveRequests 10
|
||
ServerLimit 250
|
||
#MaxClients 250
|
||
MaxRequestWorkers 250
|
||
StartServers 50
|
||
MinSpareServers 20
|
||
MaxSpareServers 30
|
||
MaxRequestsPerChild 100
|
||
<Directory /home/>
|
||
AllowOverride None
|
||
Require all granted
|
||
# "Require not env XXX" is not supported :(
|
||
Deny from env=GoAway
|
||
</Directory>
|
||
<IfModule mod_ssl.c>
|
||
SSLProtocol all -SSLv2 -SSLv3
|
||
SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!RC4
|
||
</IfModule>
|
||
~~~
|
||
|
||
que l'on active à l'installation via la commande :
|
||
|
||
~~~
|
||
# a2enconf z-evolinux-defaults.conf
|
||
~~~
|
||
|
||
Le fichier `/etc/apache2/ipaddr_whitelist.conf` centralise les
|
||
adresses IP privilégiées, on peut ainsi utiliser `Include
|
||
ipaddr_whitelist.conf` à différents endroits dans la configuration
|
||
d'Apache sans dupliquer ces adresses :
|
||
|
||
~~~{.apache}
|
||
Allow from 192.0.2.42
|
||
~~~
|
||
|
||
Pour la [#gestion-des-droits]() on ajoute dans le fichier `/etc/apache2/envvars` :
|
||
|
||
~~~{.apache}
|
||
umask 007
|
||
~~~
|
||
|
||
### Valider la configuration
|
||
|
||
Avant de redémarrer le serveur, vérifier que vous n'ayez pas introduit
|
||
des erreurs de syntaxes dans la configuration :
|
||
|
||
~~~
|
||
# apache2ctl configtest
|
||
Syntax OK
|
||
~~~
|
||
|
||
## VirtualHost
|
||
|
||
Le terme **VirtualHost** correspond à la séparation de plusieurs
|
||
sites sur un même serveur HTTP. Apache permet d'avoir des VirtualHost
|
||
basés sur des noms de domaine différents (ou des adresses IP
|
||
différentes).
|
||
|
||
Exemple d'un VirtualHost basé sur un nom de domaine via
|
||
`/etc/apache2/sites-available/example.conf` :
|
||
|
||
~~~{.apache}
|
||
<VirtualHost *:80>
|
||
ServerName www.example.com
|
||
ServerAlias example.com
|
||
|
||
DocumentRoot /home/example/www/
|
||
<Directory /home/example/www/>
|
||
Options SymLinksIfOwnerMatch
|
||
AllowOverride AuthConfig Limit FileInfo Indexes
|
||
</Directory>
|
||
|
||
ScriptAlias /cgi-foo /usr/lib/cgi-bin/
|
||
<Directory /usr/lib/cgi-bin/>
|
||
Options +ExecCGI -MultiViews
|
||
AllowOverride None
|
||
|
||
AuthType Basic
|
||
AuthName "Restricted"
|
||
AuthUserFile /home/example/.htpasswd
|
||
require valid-user
|
||
|
||
Deny from all
|
||
Include ipaddr_whitelist.conf
|
||
Allow from 192.0.2.43
|
||
Satisfy any
|
||
</Directory>
|
||
|
||
AssignUserID www-example example
|
||
MaxClientsVHost 150
|
||
|
||
CustomLog /var/log/apache2/access.log vhost_combined
|
||
CustomLog /home/example/log/access.log combined
|
||
ErrorLog /home/example/log/error.log
|
||
|
||
RewriteEngine On
|
||
UseCanonicalName On
|
||
RewriteCond %{HTTP_HOST} !^www.example.com$
|
||
RewriteRule ^/(.*) http://%{SERVER_NAME}/$1 [L,R]
|
||
|
||
</VirtualHost>
|
||
# vim: set filetype=apache expandtab shiftwidth=4 softtabstop=4 tabstop=4 :
|
||
~~~
|
||
|
||
~~~
|
||
# adduser example
|
||
# adduser --ingroup example www-example
|
||
# mkdir /home/example/{www,log,awstats} && chown example: /home/example/{www,log,awstats}
|
||
# a2ensite example
|
||
~~~
|
||
|
||
En cas de gestion de multiples VirtualHost nous utilisons l'interface
|
||
web <https://forge.evolix.org/projects/evoadmin-web>
|
||
|
||
## Gestion des droits
|
||
|
||
### Séparation complète des VirtualHost
|
||
|
||
L'utilisation d'Apache-ITK nous permet d'utiliser des utilisateurs/groupes
|
||
Unix distincts pour chaque VirtualHost. Il est donc impossible
|
||
pour un utilisateur d'accéder en lecture à des fichiers d'un autre
|
||
site, même si un langage dynamique comme PHP est utilisé.
|
||
|
||
|
||
~~~
|
||
# chmod 750 /home/example
|
||
~~~
|
||
|
||
### Restriction en écriture pour Apache
|
||
|
||
Par défaut on souhaite donner uniquement un droit de lecture à
|
||
Apache, sauf sur certains répertoires du type *uploads/*, *cache/*,
|
||
etc. On utilise pour cela un utilisateur distinct pour Apache
|
||
(`www-example`) et la gestion du code via FTP/SSH/SFTP/SCP/RSYNC
|
||
(example), le groupe étant identique. Ainsi on donnera la permission
|
||
**`g+w`** pour les répertoires nécessitant un droit en écriture
|
||
pour Apache. Les fichiers uploadés via Apache auront des permissions
|
||
adéquats (`g+rwX`) pour être lus/modifiés/effacés via
|
||
FTP/SSH/SFTP/SCP/RSYNC (l'opération `chmod` est impossible mais
|
||
n'est pas nécessaire car le umask d'Apache est forcé à 007).
|
||
|
||
|
||
~~~
|
||
# echo "umask 027" >> /etc/profile
|
||
# find /home/example -type f -user www-example -exec chmod 660 {} \;
|
||
# find /home/example -type d -user www-example -exec chmod 770 {} \;
|
||
~~~
|
||
|
||
Attention, il ne faut jamais forcer les droits récursivement sur
|
||
toute l'arborescence. Si la restriction en écriture pour Apache est
|
||
impossible à gérer, on n'utilisera pas d'utilisateur distinct en
|
||
indiquant `AssignUserID example example` ce qui éliminera 100% des
|
||
problèmes de droits (mais pose des problèmes de sécurité).
|
||
|
||
## SSL
|
||
|
||
Apache peut gérer des connexions sécurisées via HTTPS.
|
||
|
||
~~~
|
||
# a2enmod ssl
|
||
~~~
|
||
|
||
Il faut alors générer une clé privée et un certificat auto-signé
|
||
ou délivré par une autorité de certification.
|
||
|
||
Voir [HowtoSSL]()
|
||
|
||
Exemple pour générer un certificat auto-signé :
|
||
|
||
~~~
|
||
# openssl req -newkey rsa:2048 -sha256 -nodes -keyout private.key -out demande.csr
|
||
# openssl x509 -req -days 3650 -sha256 -in demande.csr -signkey private.key -out certificate.crt
|
||
# mv private.key /etc/ssl/private/ && chown root:ssl-cert /etc/ssl/private/private.key && chmod 640 /etc/ssl/private/private.key
|
||
# mv certificate.crt /etc/ssl/certs/ && chown root:root /etc/ssl/certs/certificate.crt && chmod 644 /etc/ssl/certs/certificate.crt
|
||
~~~
|
||
|
||
La configuration d'un VirtualHost pour HTTPS pourra ainsi ressembler à :
|
||
|
||
~~~{.apache}
|
||
<VirtualHost *:80 *:443>
|
||
ServerName secure.example.com
|
||
ServerAlias www.example.com example.com
|
||
|
||
SSLEngine on
|
||
SSLProtocol all -SSLv2 -SSLv3
|
||
SSLCertificateKeyFile /etc/ssl/private/private.key
|
||
SSLCertificateFile /etc/ssl/certs/certificate.crt
|
||
#SSLCertificateChainFile /etc/ssl/certs/certificates_chain.pem
|
||
|
||
RewriteEngine On
|
||
RewriteCond %{HTTPS} !=on [OR]
|
||
RewriteCond %{HTTP_HOST} !^secure.example.com$
|
||
RewriteRule ^/(.*) https://%{SERVER_NAME}/$1 [L,R=permanent]
|
||
</VirtualHost>
|
||
~~~
|
||
|
||
Pour une configuration avancée des paramètres SSL, voir
|
||
[HowtoSSL#configuration-apache]()
|
||
|
||
> *Note* : la syntaxe `<VirtualHost *:80 *:443>` n'est possible
|
||
qu'à partir de Debian 8.
|
||
|
||
|
||
## Logs
|
||
|
||
<https://httpd.apache.org/docs/2.4/fr/logs.html>
|
||
|
||
La directive **CustomLog** permet de définir le journal des accès
|
||
; plusieurs formats existent : combined, common, vhost_combined,
|
||
etc. Cette directive peut être utilisée plusieurs fois, il y aura
|
||
plusieurs fichiers de logs différents.
|
||
|
||
~~~{.apache}
|
||
CustomLog log/global_access.log vhost_combined
|
||
CustomLog log/access.log combined
|
||
~~~
|
||
|
||
Si besoin, on peut ignorer certaines requêtes HTTP ainsi :
|
||
|
||
~~~{.apache}
|
||
SetEnvIf User-Agent "Foo" dontlog
|
||
CustomLog log/access.log combined env=!dontlog
|
||
~~~
|
||
|
||
La directive **ErrorLog** permet de définir le journal d'erreurs Apache.
|
||
|
||
~~~{.apache}
|
||
ErrorLog log/error.log
|
||
~~~
|
||
|
||
### Logué la taille de la requête et le temps d’exécution
|
||
|
||
Si l'on veut loguer, dans un log séparé, la taille de la requête
|
||
et le temps d’exécution par Apache de cette requête, on peut créer
|
||
une configuration apache avec le LogFormat suivant, dans
|
||
*/etc/apache2/conf-available/access-log-time.conf* :
|
||
|
||
~~~
|
||
LogFormat "%h %t \"%r\" %B %D" measure-time
|
||
~~~
|
||
|
||
Et mettre dans le vhost concerné le CustomLog suivant :
|
||
|
||
~~~
|
||
CustomLog /home/example/log/access_log_time.log measure-time
|
||
~~~
|
||
|
||
## Configuration avancée
|
||
|
||
### mod_deflate
|
||
|
||
La compression des fichiers texte/Javascript/CSS/RSS en GZIP se
|
||
fait désormais par défaut car le module **mod_deflate** est activé
|
||
dès l'installation.
|
||
|
||
### mod_proxy_http
|
||
|
||
Le module [proxy](https://httpd.apache.org/docs/2.4/mod/mod_proxy.html)
|
||
permet d'utiliser Apache en tant que proxy, notamment reverse-proxy
|
||
HTTP :
|
||
|
||
~~~
|
||
# a2enmod proxy_http
|
||
~~~
|
||
|
||
Exemple avec un service HTTP local :
|
||
|
||
~~~{.apache}
|
||
ProxyPreserveHost On
|
||
ProxyPass /foo/ http://127.0.0.1:8080/bar
|
||
ProxyPassReverse /foo/ http://127.0.0.1:8080/bar
|
||
<Proxy *>
|
||
Allow from All
|
||
</Proxy>
|
||
~~~
|
||
|
||
Exemple avec un service HTTP distant (pratique pour une migration
|
||
immédiate d'un serveur vers un autre) :
|
||
|
||
~~~{.apache}
|
||
ProxyPreserveHost On
|
||
ProxyPass / http://192.0.2.17/
|
||
ProxyPassReverse / http://192.0.2.17/
|
||
<Proxy *>
|
||
Allow from All
|
||
</Proxy>
|
||
~~~
|
||
|
||
et pour un HTTPS distant, on ajoute `SSLProxyEngine On` :
|
||
|
||
~~~{.apache}
|
||
SSLProxyEngine On
|
||
ProxyPreserveHost On
|
||
ProxyPass / https://192.0.2.17/
|
||
ProxyPassReverse / https://192.0.2.17/
|
||
<Proxy *>
|
||
Allow from All
|
||
</Proxy>
|
||
~~~
|
||
|
||
|
||
### mod_rpaf / mod_remoteip
|
||
|
||
Le module
|
||
[mod_remoteip](https://httpd.apache.org/docs/2.4/mod/mod_remoteip.html)(**mod_rpaf** en Wheezy)
|
||
permet d'utiliser la 1ère adresse IP située
|
||
dans un entête HTTP type *X-Forwarded-For* pour les logs Apache et
|
||
directives **mod_access** (Allow/Deny From).
|
||
|
||
|
||
Voici un exemple d'utilisation en Wheezy pour un reverse-proxy avec
|
||
l'adresse IP 192.0.2.10 :
|
||
|
||
~~~
|
||
# apt install libapache2-mod-rpaf
|
||
# cat /etc/apache2/mods-enabled/rpaf.conf
|
||
<IfModule rpaf_module>
|
||
RPAFenable On
|
||
RPAFsethostname On
|
||
#RPAFheader X-Forwarded-For
|
||
RPAFproxy_ips 127.0.0.1 192.0.2.10
|
||
</IfModule>
|
||
~~~
|
||
|
||
*Note :* bien mettre l'IP du reverse-proxy dans `RPAFproxy_ips`
|
||
|
||
Voici un exemple d'utilisation en Stretch pour un reverse-proxy
|
||
avec le réseau 172.131.0.0/16 :
|
||
|
||
~~~
|
||
# a2enmod remoteip
|
||
# cat /etc/apache2/conf-available/zzz-evolinux-custom.conf
|
||
RemoteIPHeader X-Forwarded-For
|
||
RemoteIPInternalProxy 172.31.0.0/16
|
||
|
||
# systemctl reload apache2
|
||
~~~
|
||
|
||
Attention au niveau des logs cela ne suffit pas. L'astuce est de
|
||
modifier le `LogFormat`, en remplaçant `%h` par `%a`.
|
||
|
||
~~~
|
||
# cat /etc/apache2/conf-available/zzz-evolinux-custom.conf
|
||
|
||
LogFormat "%v:%p %a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
|
||
LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
|
||
LogFormat "%a %l %u %t \"%r\" %>s %O" common
|
||
~~~
|
||
|
||
### mod_xsendfile
|
||
|
||
Le module [xsendfile](https://tn123.org/mod_xsendfile/) permet de
|
||
rediriger l'envoi d'un fichier vers Apache via un Header HTTP,
|
||
notamment utilisé pour servir des fichiers via Apache tout en
|
||
permettant de gérer le contrôle d'accès via une application web.
|
||
|
||
~~~
|
||
# apt install libapache2-mod-xsendfile
|
||
~~~
|
||
|
||
Pour autoriser son utilisation via *.htaccess*, on ajoute `Options`
|
||
à `AllowOverride`.
|
||
|
||
### mod_negotiation
|
||
|
||
Le module
|
||
[negotiation](https://httpd.apache.org/docs/2.4/mod/mod_negotiation.html)
|
||
permet de servir des documents en fonction de critère, notamment
|
||
la langue acceptée par le client HTTP.
|
||
|
||
~~~
|
||
# a2enmod negotiation include alias
|
||
~~~
|
||
|
||
Vous pouvez éditer le fichier
|
||
`/etc/apache2/conf-enabled/localized-error-pages.conf` qui permet
|
||
d'afficher des pages d'erreur en différentes langues, et décommenter
|
||
cette partie :
|
||
|
||
Exemple avec un service HTTP local :
|
||
|
||
~~~{.apache}
|
||
<IfModule mod_negotiation.c>
|
||
<IfModule mod_include.c>
|
||
<IfModule mod_alias.c>
|
||
|
||
Alias /error/ "/usr/share/apache2/error/"
|
||
|
||
<Directory "/usr/share/apache2/error">
|
||
Options IncludesNoExec
|
||
AddOutputFilter Includes html
|
||
AddHandler type-map var
|
||
Order allow,deny
|
||
Allow from all
|
||
LanguagePriority en cs de es fr it nl sv pt-br ro
|
||
ForceLanguagePriority Prefer Fallback
|
||
</Directory>
|
||
|
||
ErrorDocument 400 /error/HTTP_BAD_REQUEST.html.var
|
||
ErrorDocument 401 /error/HTTP_UNAUTHORIZED.html.var
|
||
ErrorDocument 403 /error/HTTP_FORBIDDEN.html.var
|
||
ErrorDocument 404 /error/HTTP_NOT_FOUND.html.var
|
||
ErrorDocument 405 /error/HTTP_METHOD_NOT_ALLOWED.html.var
|
||
ErrorDocument 408 /error/HTTP_REQUEST_TIME_OUT.html.var
|
||
ErrorDocument 410 /error/HTTP_GONE.html.var
|
||
ErrorDocument 411 /error/HTTP_LENGTH_REQUIRED.html.var
|
||
ErrorDocument 412 /error/HTTP_PRECONDITION_FAILED.html.var
|
||
ErrorDocument 413 /error/HTTP_REQUEST_ENTITY_TOO_LARGE.html.var
|
||
ErrorDocument 414 /error/HTTP_REQUEST_URI_TOO_LARGE.html.var
|
||
ErrorDocument 415 /error/HTTP_UNSUPPORTED_MEDIA_TYPE.html.var
|
||
ErrorDocument 500 /error/HTTP_INTERNAL_SERVER_ERROR.html.var
|
||
ErrorDocument 501 /error/HTTP_NOT_IMPLEMENTED.html.var
|
||
ErrorDocument 502 /error/HTTP_BAD_GATEWAY.html.var
|
||
ErrorDocument 503 /error/HTTP_SERVICE_UNAVAILABLE.html.var
|
||
ErrorDocument 506 /error/HTTP_VARIANT_ALSO_VARIES.html.var
|
||
</IfModule>
|
||
</IfModule>
|
||
</IfModule>
|
||
~~~
|
||
|
||
### mod_geoip
|
||
|
||
Ce module permet de pouvoir traiter différemment des visiteurs par
|
||
rapport à leur pays d'origine directement depuis la configuration
|
||
d'Apache. Il utilise pour cela la base GeoIP de
|
||
[Maxmind](https://www.maxmind.com).
|
||
|
||
~~~
|
||
# apt install geoip-database-extra libapache2-mod-geoip
|
||
~~~
|
||
|
||
Note: geoip-database-contrib (dans les dépots contrib) va installer
|
||
un cron qui va mettre à jour les fichiers de la base GeoIP. Ces
|
||
fichiers de base se trouvent dans `/usr/share/GeoIP/`
|
||
|
||
Quand on va avoir besoin de GeoIP, il faut penser à l'activer dans
|
||
le(s) fichier(s) de confs
|
||
|
||
~~~
|
||
<IfModule mod_geoip.c>
|
||
GeoIPEnable On
|
||
GeoIPDBFile /usr/share/GeoIP/GeoIP.dat
|
||
</IfModule>
|
||
~~~
|
||
|
||
De là, le pays d'origine du visiteur, ainsi que d'autres informations
|
||
sont placées dans des variables d'environnement utilisables dans
|
||
le VHOST.
|
||
|
||
Exemple : Autoriser que les visiteurs venant de France pour un
|
||
accéder à un dossier précis :
|
||
|
||
~~~
|
||
<Directory /var/www/foo/bar>
|
||
Require expr %{GEOIP_COUNTRY_CODE } == 'FR'
|
||
</Directory>
|
||
~~~
|
||
|
||
Faire une redirection suivant le pays :
|
||
|
||
~~~
|
||
RewriteEngine on
|
||
RewriteCond %{ENV:GEOIP_COUNTRY_CODE} ^FR$
|
||
RewriteRule ^(.*)$ https://www.example.fr$1 [R,L]
|
||
~~~
|
||
|
||
La documentation complète du module est là Pour plus d'info, il y
|
||
a la [documentation complète du
|
||
module](https://dev.maxmind.com/geoip/legacy/mod_geoip2/)
|
||
|
||
### mod_davfs
|
||
|
||
Ce module permet de prendre en charge WebDAV.
|
||
|
||
Pour l'activer :
|
||
|
||
~~~
|
||
# a2enmod davfs
|
||
~~~
|
||
|
||
Ensuite pour activer le module, il suffit de rajouter `Dav On` dans
|
||
le virtualhost voulu.
|
||
|
||
Exemple de vhost :
|
||
|
||
~~~
|
||
<VirtualHost *:443>
|
||
|
||
ServerName dav.example.com
|
||
|
||
DocumentRoot /home/webdav/
|
||
<Directory "/home/webdav/">
|
||
Dav On
|
||
|
||
AuthType Basic
|
||
AuthName DAV
|
||
AuthUserFile "/etc/apache2/webdav.htpasswd"
|
||
Require valid-user
|
||
</Directory>
|
||
|
||
ErrorLog ${APACHE_LOG_DIR}/dav_error.log
|
||
CustomLog ${APACHE_LOG_DIR}/dav_access.log combined
|
||
|
||
SSLEngine on
|
||
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
|
||
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
|
||
</VirtualHost>
|
||
~~~
|
||
|
||
## Authentification HTTP
|
||
|
||
### HTTP Basic Authentication (mod_auth_basic)
|
||
|
||
[Basic](http://httpd.apache.org/docs/2.4/mod/mod_auth_basic.html)
|
||
est la méthode d'authenfication HTTP la plus simple et la plus
|
||
répandue. La configuration se fait via *VirtualHost* ou *.htaccess*
|
||
:
|
||
|
||
~~~{.apache}
|
||
AuthType Basic
|
||
AuthName "Restricted"
|
||
AuthUserFile /foo/.htpasswd
|
||
AuthGroupFile /dev/null
|
||
require valid-user
|
||
~~~
|
||
|
||
La gestion du fichier *.htpasswd* se gère via la commande `htpasswd`.
|
||
|
||
Pour créer l'utilisateur *foo* :
|
||
|
||
~~~{.bash}
|
||
$ htpasswd -c /foo/.htpasswd foo
|
||
New password:
|
||
Re-type new password:
|
||
Adding password for user foo
|
||
~~~
|
||
|
||
### HTTP Digest Authentication (mod_auth_digest)
|
||
|
||
Il est possible d'utiliser la méthode d'authentification Digest
|
||
plutôt que Basic en activant le module :
|
||
|
||
~~~
|
||
# a2enmod auth_digest
|
||
~~~
|
||
|
||
La configuration est quasi-identique au type Basic :
|
||
|
||
~~~{.apache}
|
||
AuthType Digest
|
||
AuthName "Restricted"
|
||
AuthUserFile /foo/.htpasswd
|
||
Require valid-user
|
||
~~~
|
||
|
||
La gestion du fichier *.htpasswd* se gère alors via la commande `htdigest`.
|
||
|
||
### Authentification via LDAP (mod_authnz_ldap)
|
||
|
||
~~~
|
||
# a2enmod authnz_ldap
|
||
~~~~
|
||
|
||
Voici un exemple de configuration :
|
||
|
||
~~~{.apache}
|
||
AuthBasicProvider ldap
|
||
AuthName "Restricted"
|
||
AuthType Basic
|
||
AuthLDAPURL ldaps://ldap.example.com/ou=people,dc=example,dc=com?uid?one?(filter)
|
||
Require valid-user
|
||
~~~
|
||
|
||
Note : pour utiliser *ldaps* avec un certificat non reconnu par le
|
||
système, il faut ajouter la directive suivante dans la configuration
|
||
globale d'Apache `LDAPVerifyServerCert off`.
|
||
|
||
## Rewrite Rules
|
||
|
||
* mod_rewrite : <http://httpd.apache.org/docs/2.4/mod/mod_rewrite.html>
|
||
* drapeaux utilisables : <https://httpd.apache.org/docs/2.4/rewrite/flags.html>
|
||
|
||
Voici quelques motifs classiques de redirection vers un nouveau
|
||
domaine (HTTP 302) … du plus simple au plus compliqué :
|
||
|
||
~~~
|
||
# rediriger la page d'accueil avec un code 301
|
||
RedirectPermanent / http://new.example.com
|
||
|
||
# rediriger n'importe quelle requête en conservant le chemin
|
||
RedirectMatch ^/(.*)$ http://new.example.com/$1
|
||
|
||
# rediriger la page d'accueil vers un autre chemin
|
||
RedirectMatch ^/$ /sub/
|
||
|
||
# rediriger n'importe quelle requête en conservant le chemin avec des exceptions
|
||
RewriteCond %{REMOTE_ADDR} !^192\.0\.2\.129
|
||
RewriteRule ^/(.*) http://new.example.com/$1 [L,R=permanent]
|
||
|
||
# rediriger vers HTTPS sauf pour certaines requetes
|
||
RewriteCond %{REQUEST_URI} !^/.well-known/pki-validation/
|
||
RewriteRule ^/(.*) https://%{SERVER_NAME}/$1 [L,R]
|
||
|
||
# le drapeau NC permet de ne pas tenir compte de la casse
|
||
RewriteRule ^/FoO.tXt /sub/ [L,R,NC]
|
||
|
||
# empêcher des requêtes POST sur une URL particulière
|
||
RewriteCond %{REQUEST_METHOD} POST
|
||
RewriteRule ^/foo.txt [L,F]
|
||
|
||
# rediriger vers HTTPS dans un VirtualHost mixte HTTP/HTTPS
|
||
RewriteCond %{HTTPS} !=on
|
||
RewriteRule ^/(.*) https://%{SERVER_NAME}/$1 [L,R=permanent]
|
||
|
||
# mettre un site en maintenance (code 503) avec des exceptions
|
||
RewriteCond %{REMOTE_ADDR} !^192\.0\.2\.129
|
||
RewriteRule ^.*$ / [R=503,L]
|
||
ErrorDocument 503 "Maintenance temporaire, veuillez patienter. Merci."
|
||
#ErrorDocument 503 http://maintenance.evolix.org/
|
||
#Header Set Cache-Control "no-cache, no-store"
|
||
#Header Set Pragma "no-cache"
|
||
|
||
# Afficher une page de maintenance si elle existe et le contenu du site s'affiche pour ceux ayant l'IP spécifié.
|
||
RewriteCond %{REMOTE_ADDR} !^123\.456\.X\.X
|
||
RewriteCond %{DOCUMENT_ROOT}/maintenance.html -f
|
||
RewriteCond %{SCRIPT_FILENAME} !maintenance.html
|
||
RewriteRule ^.*$ /maintenance.html [R=503,L]
|
||
ErrorDocument 503 /maintenance.html
|
||
Header Set Cache-Control "max-age=0, no-store"
|
||
|
||
# Rediriger sur une page sans ses paramètres et valeurs.
|
||
RewriteCond %{REQUEST_URI} ^/index\.php$
|
||
RewriteCond %{QUERY_STRING} ^parametre=valeur$
|
||
RewriteRule (.*) /page-destination [QSD,R=301,L]
|
||
~~~
|
||
|
||
Pour supprimer un Query String avec une Rewrite Rule :
|
||
<https://www.philipphoffmann.de/blog/2012/08/16/how-to-discard-the-query-string-in-a-rewriterule-apache-mod_rewrite/>
|
||
|
||
### Redirection https
|
||
|
||
Dans le cas où le serveur n'écoute que sur le port 80, derrière un
|
||
proxy qui fait la terminaison SSL mais ne gère pas les redirections
|
||
(exemple Amazon ELB), on peut forcer la redirection directement
|
||
dans Apache en utilisant la valeur de l'en-tête `X-Forwarded-Proto`
|
||
:
|
||
|
||
~~~
|
||
RewriteEngine On
|
||
RewriteCond %{HTTP:X-Forwarded-Proto} =http
|
||
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
|
||
~~~
|
||
|
||
## Conditions
|
||
|
||
À partir de la version Apache 2.4, on peut utiliser des conditions
|
||
pour l'application des directives (l'imbrication de multiples <If>
|
||
n'est disponible que pour les versions >= 2.4.26).
|
||
|
||
~~~{.bash}
|
||
<If "%{HTTP_HOST} == 'test.example.com'">
|
||
SetEnv APP_ENV "test"
|
||
</If>
|
||
<If "%{HTTP_QUERY} =~ /wp-admin*/">
|
||
...
|
||
</If>
|
||
~~~
|
||
|
||
Expressions possibles : [https://httpd.apache.org/docs/2.4/expr.html](https://httpd.apache.org/docs/2.4/expr.html)
|
||
|
||
## Attaques DOS (Denial Of Service) ou XSS
|
||
|
||
### mod_evasive
|
||
|
||
Le module **mod_evasive** permet de limiter certaines attaques DoS
|
||
en limitant l'accès à une ou plusieurs pages par un temps de
|
||
banissement d'une IP source. Par défaut, nous ajustons la configuration
|
||
de façon à ce que si une adresse IP accède plus de 5 fois à la même
|
||
page en 30s, ou à plus de 30 requêtes sur tout le site en 1s, il
|
||
sera banni (erreur HTTP 403) pendant 60s. Une notification sera
|
||
alors envoyée à syslog et par email.
|
||
|
||
~~~{.apache}
|
||
<IfModule mod_evasive20.c>
|
||
DOSHashTableSize 3097
|
||
DOSPageCount 5
|
||
DOSSiteCount 30
|
||
DOSPageInterval 3
|
||
DOSSiteInterval 1
|
||
DOSBlockingPeriod 60
|
||
DOSEmailNotify security@example.com
|
||
</IfModule>
|
||
~~~
|
||
|
||
Attention, pour certains sites avec de nombreuses ressources statiques
|
||
sur le même serveur HTTP, il faut souvent désactiver **mod_evasive**
|
||
pour éviter des faux-positifs et ne l'utiliser qu'en cas d'attaques
|
||
récurrentes.
|
||
|
||
On peut mettre en liste blanche une ip ou une plage d'ip, pour que
|
||
le mod_evasive ignore les requêtes venant de ceux-ci :
|
||
|
||
~~~
|
||
DOSWhitelist 192.168.0.*
|
||
~~~
|
||
|
||
On peut aussi utiliser un wildcard * peut être autorisé sur les 3
|
||
derniers octets, si nécessaire.
|
||
|
||
### Fail2Ban
|
||
|
||
[Fail2Ban](HowtoFail2Ban) est indépendant d'Apache, mais peut être
|
||
utilisé pour de la détection plus précise que *mod_evasive* : il
|
||
va lire en permanence les journaux générés par Apache (ce qui peut
|
||
être coûteux en ressources) et il pourra bannir des adresses IP si
|
||
cela répond à certaines règles comme trop de connexions à une page
|
||
d'authentification par exemple.
|
||
|
||
Voir <https://wiki.evolix.org/HowtoFail2Ban#apache-nginx>
|
||
|
||
### ModSecurity
|
||
|
||
L'utilisation de [ModSecurity](http://www.modsecurity.org) permet
|
||
de bloquer certaines requêtes HTTP (attaques XSS connues, etc.) au
|
||
niveau d'Apache. On l'installe avec le [OWASP ModSecurity Core Rule Set](https://coreruleset.org/) (CRS)
|
||
qui est un ensemble de règles ModSecurity couvrant un large spectre d'attaques possibles.
|
||
|
||
~~~
|
||
# apt install libapache2-mod-security2 modsecurity-crs
|
||
~~~
|
||
|
||
Nous faisons une configuration minimale via
|
||
`/etc/apache2/conf-available/modsecurity.conf` :
|
||
|
||
~~~{.apache}
|
||
<IfModule mod_security2.c>
|
||
|
||
# enable mod_security
|
||
SecRuleEngine On
|
||
# access to request bodies
|
||
SecRequestBodyAccess On
|
||
#SecRequestBodyLimit 134217728
|
||
#SecRequestBodyInMemoryLimit 131072
|
||
# access to response bodies
|
||
SecResponseBodyAccess Off
|
||
#SecResponseBodyLimit 524288
|
||
SecResponseBodyMimeType (null) text/html text/plain text/xml
|
||
#SecServerSignature "Apache/2.2.0 (Fedora)"
|
||
|
||
SecUploadDir /tmp
|
||
SecUploadKeepFiles Off
|
||
|
||
# default action
|
||
SecDefaultAction "log,auditlog,deny,status:406,phase:2"
|
||
|
||
SecAuditEngine Off
|
||
#SecAuditLogRelevantStatus "^[45]"
|
||
# use only one log file
|
||
SecAuditLogType Serial
|
||
# audit log file
|
||
SecAuditLog /var/log/apache2/modsec_audit.log
|
||
# what is logged
|
||
SecAuditLogParts "ABIFHZ"
|
||
|
||
#SecArgumentSeparator "&"
|
||
SecCookieFormat 0
|
||
SecDebugLog /var/log/apache2/modsec_debug.log
|
||
SecDebugLogLevel 0
|
||
|
||
SecDataDir /tmp
|
||
SecTmpDir /tmp
|
||
|
||
#########
|
||
# RULES
|
||
#########
|
||
|
||
# Removed because it does not play well with apache-itk
|
||
# Can be removed when modsecurity 2.9.3 hits debian
|
||
# See https://github.com/SpiderLabs/ModSecurity/issues/712
|
||
SecRuleRemoveById "910000-910999"
|
||
|
||
</IfModule>
|
||
|
||
~~~
|
||
|
||
Nous désactivons le log d'audit par défaut, puisque l’information
|
||
enregistrée dans le log d'erreur Apache est suffisante pour connaître
|
||
la raison d'un bloquage. Par contre, il est utile de le réactiver (avec `SecAuditEngine RelevantOnly`) lorsque
|
||
vous faites un audit des règles applicables a un serveur ou lors de la rédaction
|
||
de nouvelles règles. Dans ce cas, il existe des [outils](https://github.com/Apache-Labor/labor/blob/master/bin/.apache-modsec.alias)
|
||
pour faciliter l’obtention de statistiques du audit log.
|
||
|
||
On peut aussi ajuster certains paramètres de ModSecurity Core Rule
|
||
Set en modifiant le fichier `/etc/modsecurity/crs/crs-setup.conf`.
|
||
C'est notamment ici qu'il faudra ajuster si on utilise d'autres
|
||
méthodes HTTP (comme PATCH, PUT, DELETE...) qui sont bloquées par défaut.
|
||
|
||
On pourra désactiver modsecurity dans des vhosts ou sur des dossiers
|
||
en particulier en jouant avec la directive `SecRuleEngine Off`.
|
||
Ceci peut être utile en cas de problèmes, mais il est toujours mieux
|
||
de faire un léger audit afin d’identifier les règles problématiques
|
||
et les désactiver avec `SecRuleRemoveById XXXX`, comme nous le
|
||
faisont avec les règles 910*.
|
||
|
||
~~~
|
||
<Directory "/home/monsite/www/wp-admin">
|
||
<IfModule security2_module>
|
||
SecRuleEngine Off
|
||
</IfModule>
|
||
</Directory>
|
||
~~~
|
||
|
||
Le Wiki À propos de [ces directives](https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual)
|
||
|
||
## Awstats
|
||
|
||
[AWStats](http://www.awstats.org/) est un outil pour générer des
|
||
statistiques en fonction d'un fichier de logs.
|
||
|
||
Voir <https://wiki.evolix.org/HowtoLAMP/AwStats>
|
||
|
||
*Note :* une configuration AWStats peut être forcée au sein d'un
|
||
VirtualHost grâce à la directive `SetEnv AWSTATS_FORCE_CONFIG
|
||
example`
|
||
|
||
## Monitoring
|
||
|
||
### log2mail
|
||
|
||
Pour être alerté en cas de *Segmentation fault*, on ajoute la
|
||
configuration suivante au logiciel
|
||
[log2mail](https://wiki.evolix.org/HowtoLog2mail) :
|
||
|
||
~~~
|
||
file = /var/log/apache2/error.log
|
||
pattern = "Segmentation fault"
|
||
mailto = alert@example.com
|
||
~~~
|
||
|
||
~~~
|
||
# adduser log2mail adm
|
||
# servicectl restart log2mail
|
||
~~~
|
||
|
||
### apachetop
|
||
|
||
L'indispensable **apachetop** permet de surveiller en direct
|
||
l'activité d'Apache via un fichier d'access_log (format *combined*)
|
||
:
|
||
|
||
~~~
|
||
$ apachetop -f access.log -T 3600 -q
|
||
~~~
|
||
|
||
On peut alors visualiser les URLs les plus sollicitées (querystrings
|
||
inclus grâce à l'option *-q*), et switcher à l'aide de la touche
|
||
**d** pour voir les adresses IP source ; à l'aide de la touche
|
||
**n** pour voir la répartition en codes HTTP 2xx/3xx/4xx/5xx.
|
||
|
||
Voici l'ensemble des commandes disponibles :
|
||
|
||
~~~
|
||
d : switch l'affichage entre URLs/IPs source/Referrers
|
||
n : switch l'affichage entre le nombre de requêtes et la répartition en codes HTTP 2xx/3xx/4xx/5xx
|
||
h or ? : afficher l'aide
|
||
p : (un)freeze l'affichage
|
||
q : quitter
|
||
up/down : sélectionner une ligne (affichage d'une '*' sur la ligne)
|
||
right/left : entrer/sortir dans les détails pour la ligne sélectionnées
|
||
|
||
DÉTAILS:
|
||
s: TRI PAR:
|
||
r) requêtes R) reqs/sec b) bytes B) bytes/sec
|
||
2) 2xx 3) 3xx 4) 4xx 5) 5xx
|
||
|
||
t: AFFICHE DANS LE SOUS-MENU:
|
||
u) urls r) referrers h) adresses IP source
|
||
|
||
f: FILTRES:
|
||
a) ajout d'un filtre c) suppression des filtres s) montrer les filtres actifs
|
||
a: AJOUT D'UN FILTRE TYPE REGEX
|
||
u) appliqué à l'URL r) appliqué au Refferer h) appliqué à l'adresse IP source
|
||
~~~
|
||
|
||
|
||
### server-status
|
||
|
||
L'activation du *server-status* est utile pour une observation
|
||
manuelle ou automatique.
|
||
|
||
~~~{.apache}
|
||
<IfModule mod_status.c>
|
||
ExtendedStatus On
|
||
<Location /server-status-XXXX>
|
||
SetHandler server-status
|
||
Deny from all
|
||
Include ipaddr_whitelist.conf
|
||
Allow from 192.0.2.43
|
||
Allow from 127.0.0.1
|
||
</Location>
|
||
</IfModule>
|
||
~~~
|
||
|
||
### Munin
|
||
|
||
Pour activer les plugins Munin pour Apache :
|
||
|
||
~~~
|
||
# cd /etc/munin/plugins
|
||
# ln -s /usr/share/munin/plugins/apache_accesses
|
||
# ln -s /usr/share/munin/plugins/apache_processes
|
||
# ln -s /usr/share/munin/plugins/apache_volume
|
||
~~~
|
||
|
||
Les plugins Apache pour Munin se base *server-status*, on configure
|
||
ainsi via le fichier `/etc/munin/plugin-conf.d/munin-node` :
|
||
|
||
~~~
|
||
[apache_*]
|
||
env.url http://127.0.0.1:%d/server-status-XXXX?auto
|
||
env.port 80
|
||
~~~
|
||
|
||
Pour tester le bon fonctionnement des plugins Apache pour Munin :
|
||
|
||
~~~
|
||
# sudo -u munin munin-run apache_accesses
|
||
~~~
|
||
|
||
Ceci doit vous renvoyer une valeur du type accesses80.value 19372070.
|
||
Si la commande vous renvoie U, vous avez un soucis d'accès à la
|
||
page *server-status*, à vérifier via
|
||
`GET http://127.0.0.1:%d/server-status-XXXX?auto`.
|
||
|
||
## FAQ
|
||
|
||
### Autorisation DirectoryIndex via .htaccess ?
|
||
|
||
Ajouter `Indexes` dans `AllowOverride`.
|
||
|
||
### Autorisation directives mod_expires ou mod_caches via .htaccess ?
|
||
|
||
Ajouter `Indexes` dans `AllowOverride`.
|
||
|
||
### Autorisation de rewrite rules (mod_rewrite) via .htaccess ?
|
||
|
||
Ajouter `FileInfo` dans `AllowOverride` et `+SymLinksIfOwnerMatch`
|
||
ou `+FollowSymLinks` dans `Options`.
|
||
|
||
### Autorisation Options via .htaccess ?
|
||
|
||
Si l'on modifie l'option `php_admin_value memory_limit` : un
|
||
_reload_/_graceful_ suffit pour prendre en compte la modification.
|
||
|
||
Exemple pour le AllowOverride :
|
||
|
||
~~~
|
||
AllowOverride Options=All,MultiViews Indexes AuthConfig Limit FileInfo
|
||
~~~
|
||
|
||
### Authentification LDAP avec serveur LDAP en local
|
||
|
||
Quand on utilise l'authentification LDAP avec un serveur en local,
|
||
il faut démarrer **slapd** avant de démarrer Apache, sinon celui-ci
|
||
se plaint qu'il ne peut pas contacter le serveur LDAP, et bloque
|
||
l'accès aux pages … (erreur 500).
|
||
|
||
Pour cela, dans le script d'init d'apache2 ajouter slapd dans la
|
||
directive `Required-Start:`
|
||
|
||
~~~
|
||
# Required-Start: $local_fs $remote_fs $network $syslog $named slapd
|
||
~~~
|
||
|
||
Supprimer les liens logiques et ré-générer les.
|
||
|
||
~~~
|
||
# insserv -r apache2
|
||
# insserv apache2
|
||
~~~
|
||
|
||
### Page personnalisée lors code erreur HTTP
|
||
|
||
On peut ajouter une configuration générale à tous les vhosts afin
|
||
de faire apparaître le contenu d'une page personnalisée selon le
|
||
code de retour HTTP.
|
||
|
||
Pour cela on ajoute un nouveau fichier de configuration à l'intérieur
|
||
de la racine apache, car cela concernera tout les vhosts.
|
||
|
||
`/etc/apache2/error.conf` :
|
||
|
||
~~~{.apache}
|
||
ErrorDocument XXX /YYYYYY/page.html
|
||
Alias /YYYYYY /var/www/
|
||
<Directory /var/www/>
|
||
Order allow,deny
|
||
Allow from all
|
||
DirectoryIndex page.html
|
||
</Directory>
|
||
~~~
|
||
|
||
*Remplacer XXX par le code erreur HTTP souhaité et YYYYY par le nom
|
||
de Location souhaité (URL) - vu que global à tous les vhosts, prendre
|
||
une chaîne aléatoire.*
|
||
|
||
Ensuite, il suffit simplement d'ajouter le fichier dans la configuration
|
||
générale d'Apache :
|
||
|
||
`/etc/apache2/apache2.conf` :
|
||
|
||
~~~{.apache}
|
||
Include error.conf
|
||
~~~
|
||
|
||
### Site web cassé en https avec un reverse proxy
|
||
|
||
Il est possible que l'application (joomla par exemple) pense qu'elle
|
||
est accédée en HTTP à tort parce qu'en réalité c'est un reverse
|
||
proxy qui fait la terminaison ssl. On peut indiquer dans le vhost
|
||
|
||
~~~{.apache}
|
||
SetEnvIfNoCase X-Forwarded-Proto https HTTPS=on
|
||
~~~
|
||
|
||
Ainsi l'application saura qu'elle est accédée en HTTPS à condition
|
||
que le reverse proxy soit bien configuré et envoie X-Forwarded-Proto.
|
||
|
||
### Interdire en fonction du User-Agent
|
||
|
||
~~~{.apache}
|
||
SetEnvIf User-Agent "^BadBot$" GoAway=1
|
||
SetEnvIf User-Agent "Nutch" GoAway=1
|
||
<Directory />
|
||
Deny from env=GoAway
|
||
</Directory>
|
||
~~~
|
||
|
||
### Site avec accents cassés
|
||
|
||
Si vous avez des vieux fichiers sources (TXT, HTML), il est probable
|
||
qu'ils utilisent l'encodage ISO-8859 au lieu d'Unicode. On peut
|
||
alors forcer la reconnaissance de cet encodage (ajout de charset=
|
||
dans l'entête HTTP Content-Type) via l'option `AddDefaultCharset`
|
||
utilisable globalement, dans un VirtualHost, dans un Directory ou
|
||
même un .htaccess si autorisé :
|
||
|
||
|
||
~~~
|
||
AddDefaultCharset ISO-8859-15
|
||
~~~
|
||
|
||
> *Note* : si vous avez des fichiers PHP en ISO-8859, vous devrez
|
||
> forcer l'option `default_charset` de PHP :
|
||
>
|
||
>
|
||
> ~~~
|
||
> php_value default_charset ISO-8859-15
|
||
> ~~~
|
||
|
||
### php_value error_reporting
|
||
|
||
Pour régler la valeur PHP `error_reporting` par vhost, il ne faut
|
||
pas utiliser les constantes PHP mais le masque binaire.
|
||
|
||
Extrait de <http://php.net/manual/fr/errorfunc.constants.php> : «
|
||
Note: Vous pouvez utiliser ces constantes dans le fichier `php.ini`
|
||
mais pas hors de PHP, comme dans le fichier `httpd.conf`, où vous
|
||
devez utiliser les valeurs des champs de bits. »
|
||
|
||
Exemple :
|
||
|
||
`E_ALL` et `~E_DEPRECATED` et `~E_STRICT`
|
||
→ `php_value error_reporting 22527`
|
||
|
||
Vous pouvez le calculer à la main ou avec un outil comme celui-ci :
|
||
<http://www.bx.com.au/tools/ultimate-php-error-reporting-wizard>
|
||
|
||
### Ne pas logguer le query-string dans le access.log
|
||
|
||
On peut ajouter un nouveau format de log dans `/etc/apache2/apache.conf`
|
||
et l'utiliser après dans les définitions de fichier de logs :
|
||
|
||
~~~
|
||
LogFormat "%h %l %u %t \"%m %U %H\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combinednoqtring
|
||
~~~
|
||
|
||
### Proxy WebSocket socket.io
|
||
|
||
~~~
|
||
# a2enmod proxy_wstunnel
|
||
~~~
|
||
|
||
~~~
|
||
# Socket.io
|
||
RewriteRule /socket.io/websocket/ - [R=200,L]
|
||
ProxyPass /socket.io/socket.io.js http://127.0.0.1:8080/socket.io/socket.io.js
|
||
ProxyPassReverse /socket.io/socket.io.js http://127.0.0.1:8080/socket.io/socket.io.js
|
||
ProxyPass /socket.io/websocket ws://127.0.0.1:8080/socket.io/websocket
|
||
ProxyPassReverse /socket.io/websocket ws://127.0.0.1:8080/socket.io/websocket
|
||
ProxyPass /socket.io/ http://127.0.0.1:8080/socket.io/
|
||
ProxyPassReverse /socket.io/ http://127.0.0.1:8080/socket.io/
|
||
RewriteCond %{REQUEST_URI} ^/socket.io [NC]
|
||
RewriteCond %{QUERY_STRING} transport=websocket [NC]
|
||
RewriteRule /(.*) ws://127.0.0.1:8080/$1 [P,L]
|
||
ProxyPass / http://127.0.0.1:8080/
|
||
ProxyPassReverse / http://127.0.0.1:8080/
|
||
~~~
|