From 03aaeb0bbbdcb5a6d7a92a335beac664268e9bf8 Mon Sep 17 00:00:00 2001 From: gcolpart Date: Wed, 5 Oct 2016 03:30:41 +0200 Subject: [PATCH] sprint migration doc --- HowtoApache.md | 313 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 307 insertions(+), 6 deletions(-) diff --git a/HowtoApache.md b/HowtoApache.md index 64d442b2..c3754771 100644 --- a/HowtoApache.md +++ b/HowtoApache.md @@ -1,11 +1,15 @@ -# Howto Apache +--- +categories: web +title: Howto Apache +... +Apache est le serveur [HTTP](HowtoHTTP) le plus utilisé sur le web depuis 1996. + ## Installation -Nous utilisons [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/groupe/MaxClients spécifique, ce qui est utile pour la sécurité. +Nous utilisons [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/groupe/*MaxClients* spécifique, ce qui est utile pour la sécurité d'un serveur multi-sites. ~~~ # aptitude install apache2-mpm-itk libapache2-mod-evasive apachetop libwww-perl @@ -26,14 +30,13 @@ Fichiers de configuration : `-- sites-enabled `-- *.conf - Activation des modules suivants : ~~~ # a2enmod rewrite expires headers rewrite cgi ~~~ -Fichier `/etc/apache2/conf-available/z_evolix.conf` : +Le fichier `/etc/apache2/conf-available/z_evolix.conf` contient nos optimisations basiques : ~~~{.apache} ServerTokens Prod @@ -46,12 +49,310 @@ StartServers 50 MinSpareServers 20 MaxSpareServers 30 MaxRequestsPerChild 0 + + AllowOverride None + Require all granted + ~~~ ~~~ # a2enconf z_evolix.conf ~~~ +Le fichier `/etc/apache2/ipaddr_whitelist.conf` contient les adresses IP privilégiées : + +~~~{.apache} +Allow from 192.0.2.42 +~~~ + +Pour la [#gestion-des-droits]() on ajoute dans le fichier `/etc/apache2/envvars` : + +~~~{.apache} +umask 007 +~~~ + +## VirtualHost + +Le terme *VirtualHost* réfère à la pratique de séparer 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} + + ServerName www.example.com + ServerAlias example.com + + DocumentRoot /home/example/www/ + + Options SymLinksIfOwnerMatch + AllowOverride AuthConfig Limit FileInfo Indexes + + + ScriptAlias /cgi-foo /usr/lib/cgi-bin/ + + Options ExecCGI -MultiViews + AllowOverride None + + AuthType Basic + AuthName "Restricted" + AuthUserFile /home/example/.htpasswd + AuthGroupFile /dev/null + require valid-user + + Deny from all + Include /etc/apache2/ipaddr_whitelist.conf + Allow from 192.0.2.43 + Satisfy any + + + 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] + + +# vim: set filetype=apache expandtab shiftwidth=4 softtabstop=4 tabstop=4 : +~~~ + +~~~ +# adduser example +# adduser --ingroup example www-example +# a2ensite example +~~~ + +## Gestion des droits + +### Séparation complèe des différents VirtualHosts + +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 écrite 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 -## Awstats \ No newline at end of file +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 + +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} + + RewriteEngine On + RewriteRule ^/(.*) https://example.com/$1 [L,R=permanent] + + +[...] + 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 + +~~~ + +Pour une configuration avancées des paramètres SSL : + +## Configuration avancée + +### mod_deflate + +La compression des fichiers texte/Javascript/CSS/RSS en GZIP se fait désormais par défault car le module mod_deflate est activé dès l'installation. + +### mod_xsendfile + +Le module 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. + +~~~ +# aptitude install libapache2-mod-xsendfile +# a2enmod xsendfile +~~~ + +Pour autoriser son utilisation via .htaccess, on ajoute *Options* à `AllowOverride`. + +## mod_spdy (deprecated) + +C'est un module qui permet d'activer le protocole SPDY (de Google). + +On récupère le package Debian via Google : + +~~~ +# wget https://dl-ssl.google.com/dl/linux/direct/mod-spdy-beta_current_amd64.deb +# dpkg -i mod-spdy-beta_current_amd64.deb +~~~ + +Pour désactiver globalement mod_spdy, on peut utiliser la directive `SpdyEnabled off`. + +Pour vérifier que le protocole SPDY est bien en place : + +## 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`. + +### 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 + +## 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} + + DOSHashTableSize 3097 + DOSPageCount 5 + DOSSiteCount 30 + DOSPageInterval 3 + DOSSiteInterval 1 + DOSBlockingPeriod 60 + DOSEmailNotify security@example.com + +~~~ + +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. + +### 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. + + + +### ModSecurity + +L'utilisation de [ModSecurity](http://www.modsecurity.org) permet d'interdire certaines requêtes (attaques XSS connues, etc.) au niveau d'Apache. + +~~~ +# apt install libapache2-mod-security2 modsecurity-crs +~~~ + +Nous faisons une configuration minimale via `/etc/apache2/conf-available/modsecurity.conf` : + +~~~{.apache} + + + SecRuleEngine On + SecRequestBodyAccess On + #SecRequestBodyLimit 134217728 + #SecRequestBodyInMemoryLimit 131072 + SecResponseBodyAccess Off + #SecResponseBodyLimit 524288 + SecResponseBodyMimeType (null) text/html text/plain text/xml + #SecServerSignature "Apache/2.2.0 (Fedora)" + SecUploadDir /tmp + SecUploadKeepFiles Off + SecDefaultAction "log,auditlog,deny,status:406,phase:2,t:none" + SecAuditEngine RelevantOnly + #SecAuditLogRelevantStatus "^[45]" + SecAuditLogType Serial + SecAuditLog /var/log/apache2/modsecurity_audit.log + SecAuditLogParts "ABIFHZ" + #SecArgumentSeparator "&" + SecCookieFormat 0 + SecDebugLog /var/log/apache2/modsec_debug.log + SecDebugLogLevel 0 + SecTmpDir /tmp + + SecRule REQUEST_FILENAME "modsecuritytest1" + SecRule REQUEST_URI "modsecuritytest2" + SecRule REQUEST_FILENAME "(?:n(?:map|et|c)|w(?:guest|sh)|cmd(?:32)?|telnet|rcmd|ftp)\.exe" + + #Include /usr/share/modsecurity-crs/*.conf + + ErrorDocument 406 http://SERVERNAME/406.html + +~~~ + +Pour une configuration avancée, on ajuste l'utilisation du jeu de règles *modsecurity-crs* et l'on gère nos propres règles personnalisées. + +## Awstats + +SetEnv AWSTATS_FORCE_CONFIG example + +## Monitoring +