Outils pour utilisateurs

Outils du site


apache

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

apache [2018/03/09 11:52] (Version actuelle)
Ligne 1: Ligne 1:
 +
 +{{tag> apache}}
 +
 +===== Apache =====
 +
 +{{indexmenu>:​apache}}
 +
 +==== Présentation ====
 +
 +=== Architecture ​ ===
 +
 +Modulaire donc souple et adaptable aux cas d'​utilisation et aux plateformes utilisées. Il est ainsi possible d'​étendre les fonctionnalités ou de limiter les ressources utilisées en activant (ou pas) les modules au démarrage du serveur, ou lors de la compilation.
 +
 +Cette modularité s'​étend aux mécanismes utilisés pour démarrer les processus chargés d'​attendre et de traiter les requêtes. On va pouvoir choisir un //mpm// spécifiquement adapté au système d'​exploitation (mpm_winnt),​ pouvant supporter une forte montée en charge (//​worker//​) ou privilégiant la stabilité et la rétrocompatibilité (//​prefork//​)
 +
 + ==== MPM prefork ===
 +1 requete -> 1 fork => un processus
 +
 +Peut être utilisé avec des modules non thread-safe. Propose la meilleure isolation possible entre 2 requêtes.
 +
 +Le serveur principal se charge de maintenir un //pool// de processus prêt à traiter des requêtes entrantes. Les directives à régler sont //​MaxClients//,​ //​MaxSpareServers//,​ //​MinSpareServer//,​ //​MaxRequestsPerChild//​ et //​StartServers//​
 +
 + === MPM Worker ====
 +MPM hybride basé sur des processus et des threads. Ces derniers sont utilisés pour traiter les requêtes entrantes.
 +
 +1 processus principal -> StartServers Procesus -> ThreadsPerChild threads
 +
 + === Choix d'un MPM sur RedHat ===
 +
 +<​code>​
 +[[:​vim|vim]]/​etc/​sysconfig/​httpd
 +</​code>​
 +
 +=== How it starts ===
 +
 +un 1er processus s'​exécute en //root// et ouvre les ports adéquats. Un certain nombre de processus //​non-privilégiés//​ sont ensuite lancés par ce processus principal.
 +
 +Le démarrage se fait par l'​intermédiaire du script //​apachectl//,​ qui se contente d'​invoquer l'​exécutable ///​usr/​sbin/​httpd//​ avec les même paramètres qui lui ont été passés.
 +
 +À noter les options **-l** et **-M** qui listent respectivement les modules //​compilés//​ et chargés dynamiquement.
 +
 +Erreur au démarrage: un message plus ou moins détaillé est affiché soit sur la console, soit dans le fichier pointé par //​LogError//​.
 +
 +<​code>​
 +apachectl: Configuration syntax error, will not run "​graceful":​
 +Syntax error on line 1018 of /​etc/​httpd/​conf/​httpd.conf:​
 +Invalid command '​llow',​ perhaps misspelled or defined by a module not included in the server configuration
 +</​code>​
 +
 + ​=== ​ How it stops ===
 +
 +Par l'​intermédiaire de signaux à envoyer au processus //​principal//​ ( cf //PidFile// ). Signaux possibles:
 +  * TERM ( apachectl -k stop )
 +  * USR1 ( apachectl -k graceful )
 +  * HUP  ( apachectl -k restart )
 +  * WINCH (apachectl -k graceful-stop )
 +
 +__Remarque sur le graceful__ : le procesus principal demande à ses enfants de bien vouloir se terminer une fois la requête en cours traitée, ou de se terminer immédiatement s'ils ne font rien, de manière à ce qu'ils soient remplacés par de nouveaux processus utilisant la nouvelle configuration.
 +
 +__Remarque sur le restart__ : s'il y a des erreurs, le service sera arrété, mais non redémarré !
 +
 +__Remarque sur la vérification de la configuration__ : un configtest n'est pas forcément suffisant. On peut tenter de lancer //httpd// en utilisateur non-root pour être sur de la validité de cette configuration.
 +
 +
 +== TP : étude script init Redhat ==
 +Noter que le //reload// fait un test de configuration.
 +
 +==== cgi ====
 +
 +=== Principe ===
 +[[:​apache|Apache]]a la possibilité de déléguer à des programmes externes la génération de contenu, qui sera renvoyé tel quel au client.
 +
 +=== Activation ===
 +
 +=== Méthode 1 ===
 +
 +ScriptAlias /cgi   /​rep/​cgi
 +
 +Fonctionne de manière similaire à //Alias//, à la différence prêt que tout élément disponible via cet url sera considéré comme un script cgi.
 +
 +D'un point de vue [[apache.securite|sécurité]] c'est la méthode la plus sûre dans la mesure où l'​administrateur à la possibilité de controler précisemment qui peut accéder au répertoire de scripts.
 +
 +=== Méthode 2 ===
 +
 +(Add|Set)Handler et Options ExecCGI
 +
 +L'​Option //​+ExecCGI//​ doit être positionné pour le répertoire voulu.
 +
 +La directive //​AddHandler cgi-script .cgi .pl // indique quels fichiers doivent être considérés comme des scripts.
 +
 +=== Exemple ===
 +<​code>​
 +#​!/​usr/​bin/​perl
 +print "​Content-type:​ text/​html\n\n";​
 +print "​Hello,​ World."; ​
 +</​code>​
 +
 +
 +=== Divers ===
 +
 +  * ScriptLog ​ (attention à la taille...)
 +
 +=== cgid ===
 +
 +Fonctionnement identique à mod_cgi. Utilisé conjointement au mpm //worker//. Un //Daemon// cgi se charge de la création des processus chargés d'​exécuter les programmes externes.
 +
 +
 +Par contre, à l'​heure actuelle, impossible de lancer le daemon ...
 +
 +=== remarques ===
 +
 +En testant avec [[apache.benchmark|ab]] un appel de script cgi (le perl ci-dessus), on a déclenché l'​action de [[apache.securite|mod_evasive]] (84 requêtes bloquées sur 100)
 +
 +==== mod_fcgid ====
 +
 +=== Intérêt ===
 +
 +Offre une plus grand séparation entre [[:​apache|apache]] et[[:php| ]]
 +
 +  * [[:​php|PHP]] some times crashes[[:​apache| ]]
 +  * [[:​apache|apache]] memory usage grows and grows
 +  * Can't use non thread safe [[:​php|php]] binaries which offers more speed
 +  * [[:​php|PHP]] over cgi is to slow. Too much overhead when starting the process for every request
 +  * want to run different [[:​php|PHP]] version on one server.
 +
 +=== Principe ===
 +
 +fastcgid se charge de lancer un certain nombre de processus au seins desquels vont tourner nos scripts. Ces processus continuent de tourner une fois les scripts traités.
 +
 +=== Installation ===
 +
 +Via les paquets adéquats. Sous [[:​old:​debian|Debian]],​ attention de ne pas confondre avec le module non libre //​libapache2-mod-fastcgi//​.
 +
 +=== Exemple ===
 +<​code>​
 +<​Directory /​var/​www/​fcgi/>​
 +SetHandler fcgid-script
 +Options +ExecCGI
 +FcgidWrapper ​   /​usr/​bin/​php-wrapper .php
 +Order allow,deny
 +Allow from all
 +</​Directory>​
 +</​code>​
 +
 +<​code>​
 +vim  /​usr/​bin/​php-wrapper
 +#!/bin/sh
 +# Set desired PHP_FCGI_* environment variables.
 +# Example:
 +# php FastCGI processes exit after 500 requests by default.
 +PHP_FCGI_MAX_REQUESTS=10000
 +export PHP_FCGI_MAX_REQUESTS
 +PHP_FCGI_CHILDREN=0
 +
 +# Replace with the path to your FastCGI-enabled php executable
 +exec /​usr/​bin/​php-cgi
 +</​code>​
 +
 +=== inconvénients ===
 +
 +Les processus php-cgi ainsi créés ne pourront pas partager le cache apc.
 +
 + === Débogage ===
 +
 +  * Attention à la différence entre //​SetHandler//​ et //​AddHandler//​ et l'​ordre dans lequel ces directives sont interprétées. Ainsi sous [[:​old:​debian|debian]],​ la configuration serait la suivante:
 +
 +<​code>​
 +<​FilesMatch "​\.ph(p3?​|tml)$">​
 +  SetHandler fcgid-script
 +</​FilesMatch>​
 +  FcgidWrapper ​   /​home/​tom/​Documents/​Dokuwiki/​php-wrapper .php
 +</​code>​
 +
 +==== php-fpm ====
 +
 +Permet de faire tourner apache avec le mpm work **et** php.
 +
 +Paquets à installer:
 +  - mod_fcgid
 +  - php-fpm
 +Il suffit de définir un vhost comme suit:
 +<​code>​
 +<​VirtualHost *:80>
 +        ServerName 192.168.10.230
 +        DocumentRoot /​var/​www/​php
 +        <​Directory /​var/​www/​php>​
 +        DirectoryIndex disabled
 +        Options Indexes
 +        </​Directory>​
 +
 +        ProxyPassMatch ^/​(.*\.php(/​.*)?​)$ fcgi://​127.0.0.1:​9000/​var/​www/​php/​$1
 +</​VirtualHost>​
 +</​code>​
 +
 +sachant que les [[:​apache#​benchmark|tests]] n'ont pas été très concluants.
 + === php-fpm status ===
 +
 +Activer pm.status dans la conf de php-fpm
 +
 +Rajouter une directive [[:nginx]]:
 +<​code>​
 +        server {                                                                                                                                                                                                   
 +        listen 8082 ;
 +        access_log /​var/​log/​nginx/​localhost.log ;
 +        root /var/www ;
 +
 +        location ~ ^/​(status|ping)$ {
 +             #​access_log off;
 +             allow 127.0.0.1;
 +             allow 195.154.164.103 ;
 +             allow 78.193.182.235 ;
 +             deny all;
 +             ​fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;​
 +             ​include fastcgi_params;​
 +              fastcgi_pass php-handler;​
 +        }
 +
 +}
 +</​code>​
 +
 +==== Virtual Host ====
 +
 +PLusieurs site sur un même serveur
 +
 +Différenciation en fonction de l'ip ou du nom
 +
 + ​=== ​ Directives === 
 +
 +  * NameVirtualHost spécifie l'​adresse et le port du "​conteneur"​ de serveur virtuel. **obsolète depuis la v2.4**
 +  * <​VirtualHost>​ permet de définir un hôte virtuel voir aussi // virtualhost ​ _default_ //
 +# l'​argument de VirtualHost doit être le même que NameVirtualHost
 +  * ServerName
 +  * DocumentRoot
 +  * ServerAlias
 +
 +# chemin d'une requete: le serveur vérifie si elle correspond à l'​adresse spécifiée par NameVirtualHost,​ et si c'est le cas, à un vhost particulier. Dans la négative, c'est le 1er vhost qui est utilisé ​
 +
 + ​=== ​ Hébergement en masse ===
 +
 +//​mod_vhost_alias//​ propose des directives //​VirtualDocumentRoot//​
 +pouvant prendre en paramètre des éléments de la requête:
 +  * %0 : nom de domaine complet
 +  * %N:M la Mième lettre de la Nième partie du nom
 +  * %N+ tout le nom à partir de la Nième partie (inclue)
 +  * %p : port number
 +
 + === UseCanonicalName ===
 +UseCanonicalName on : utilisation de //​ServerName//​
 +
 +UseCanonicalName off: utilisation du nom fourni par le client
 +
 + ​=== ​ on peut également === 
 +
 +script de déploiement d'un vhost
 +Fichiers/​ApacheNewVHost.sh
 +
 + === Message : //"​NameVirtualHost ​ *:80 has no VirtualHosts"//​ ===
 +
 +Cause : 
 +
 +  * plus d'une directive //​namevirtualhost//​
 +  * pas d'​entrée //​virtualhost//​ correspondant ​
 +
 +
 +==== Les logs ====
 +
 + ​=== ​ sécurité === 
 +
 +Le répertoire où sont enregistrés les logs ne doivent pas être accessibles à l'​utilisateur [[:​apache|apache]].
 +Les logs peuvent contenir des données en provenance //directe// de l'​utiliateur,​ donc susceptible de contenir du code malicieux.
 +
 + ​=== ​ limite système (vhost) === 
 +
 +Beaucoup de vhost => beaucoup de log.
 +La limite système du nombre de fichiers ouverts peut être atteinte.
 +
 + ​=== ​ fichier d'​erreur === 
 +
 +Directive //​ErrorLog//​
 +et
 +//​LogLevel//​
 +
 +Seront également enregistrées tous les messages écrits par les scripts cgi sur stderr.
 +
 + ​=== ​ fichier d'​acces === 
 +//CustomLog fichier|pipe nomFormat//
 +//LogFormat format nomFormat//
 +avec format:
 +  * http://​httpd.apache.org/​docs/​2.2/​mod/​mod_log_config.html#​formats
 +  * %200{User-agent}i
 + ​=== ​ format === 
 +
 +LogFormat nom format
 +
 +Le format //​combined//​ est plus informatif, car contenant referer et user-agent.
 +
 +Ex permettant de centraliser les logs de tous les [[apache.vhost|vhosts]] dans un même fichier, avec enregistrement du nom du vhost:
 +<​code>​
 +LogFormat "%v %h %l %u %t \"​%r\"​ %>s %b \"​%{Referer}i\"​ \"​%{User-Agent}i\""​ comonvhost
 +CustomLog logs/​access_log comonvhost
 +</​code>​
 +
 +
 + === piped log ===
 +
 +Il suffit de remplacer le nom du log par "|nom du programme"​ . Ce programme va tourner avec la même identité que le processus principal (càd root). Il doit donc rester simple. Il permet notamment d'​autoriser la rotation des logs sans avoir à relancer le serveur via la commande //​rotatelog//​
 +
 + ​=== ​ rotation === 
 +
 +2 possibilités,​ une avec //​[[logrotate|logrotate]]//,​ qui implique un redémarrage //Soft// du serveur afin que les fichiers de logs soient fermés, et une avec la commande //​Rotatelogs//:​
 +
 +<​code>​
 +CustomLog "​|bin/​rotatelogs -l /​var/​logs/​logfile.%Y.%m.%d 86400" common ​
 +</​code>​
 +
 +<​code>​
 +ErrorLog "​|bin/​rotatelogs /​var/​logs/​errorlog.%Y-%m-%d-%H_%M_%S 5M" ​
 +</​code>​
 +
 +=== TP ===
 +
 +Mettre en place un log centralisé de tous les vhosts, avec rotation sans interruption de service.
 +
 +==== Authentification apache 2.2 et ldap ====
 +
 +Faire un include vers le fichier ///​etc/​apache2/​ldap.auth.conf//:​
 +<​code>​
 +AuthBasicProvider ldap
 +AuthName "​prive.opendoor.fr"​
 +AuthBasicAuthoritative off
 +AuthType Basic
 +AuthLDAPURL "​ldap://​ldap/​ou=WebUsers,​dc=opendoor,​dc=fr?​uid"​
 +require valid-user
 +</​code>​
 +
 +==== Authentification apache 2.4 sur groupe ldap ====
 +Be warned you will need //​mod_ldap//​ package first
 +
 +<​code>​
 +AuthName "​Statistiques"​
 +AuthType Basic
 +AuthBasicProvider ldap
 +AuthLDAPGroupAttribute memberuid
 +AuthLDAPGroupAttributeIsDN off
 +AuthLDAPUrl ldap://​ldap.sciencespo-lyon.fr/​dc=sciencespo-lyon,​dc=fr?​uid
 +require ldap-group cn=adminfo,​ou=groups,​dc=sciencespo-lyon,​dc=fr
 +</​code>​
 +==== Monitoring ====
 +
 +=== Les éléments à surveiller: ===
 +
 +  * joignable
 +  * temps de réponse
 +  * ressources système
 +  * nb processus
 +  * quantité mémoire
 +  * charge cpu
 +
 +=== mod-status ===
 +
 +Activer le module\\
 +Voir les informations:​
 +  *    The number of worker serving requests
 +  * The number of idle worker
 +  *  The status of each worker, the number of requests that worker has performed and the total number of bytes served by the worker (*)
 +  *  A total number of accesses and byte count served (*)
 +  *  The time the server was started/​restarted and the time it has been running for
 +  *  Averages giving the number of requests per second, the number of bytes served per second and the average number of bytes per request (*)
 +  *  The current percentage CPU used by each worker and in total by Apache (*)
 +  *  The current hosts and requests being processed (*)
 +
 +=== plugin nagios check_apache2.sh ===
 +
 +Plusieurs plugin de plus ou moins bonne qualité sont publiés sur nagiosexchange. Ils s'​appuient en général sur le contenu de /​server-status pour déterminer le plus ou moins bon état de santé d'​apache.
 +
 +  * Télécharger ( http://​exchange.[[:​nagios|nagios]].org/​components/​com_mtree/​attachment.php?​link_id=619&​cf_id=24 )
 +  * Modifier (script orienté [[:​old:​debian|debian]],​ remplacer //apache2// par //httpd//
 +  * Lancer:
 +
 +<​code>​
 +[[:​sudo|sudo]][[:​bash|bash]] check_[[:​apache|apache2]].sh -p /​var/​run/​httpd -n httpd.pid
 +</​code>​
 +
 +=== Vérifier le temps de chargement d'une page ===
 +http://​exchange.[[:​nagios|nagios]].org/​directory/​Plugins/​Websites%2C-Forms-and-Transactions/​check_webpage-2Esh/​details
 +
 +
 +==== Proxy ====
 +
 +Se connecte à internet à la place des utilisateurs.
 +
 +Intérêt: sécurité, contrôle d'​accès et cache
 +
 +=== Config apache ===
 +
 +Activer les modules //proxy// et //​proxy_http//​
 +
 +** Ne pas oublier les directives de controle d'​accès**
 +<​code>​
 +<​IfModule mod_proxy.c>​
 +ProxyRequests On
 +<Proxy *>
 +Order deny,allow
 +Deny from all
 +Allow from 192.168.0.0/​255.255.255.0
 +</​Proxy>​
 +</​IfModule>​
 +</​code>​
 +
 +=== Bloquer ===
 +On peut avec **ProxyBlock domain | ip **
 +
 +=== Reverse Proxy ===
 +
 +rendre public un site hébergée sur une machine interne.
 +
 +peut servir pour la réperatition ​ de charge ou la mise en place d'un cache
 +<​code>​
 +ProxyPass /​ http://​interne/​
 +ProxyPassReverse ​ /​ http://​interne/​
 +</​code>​
 +
 +LEs directives //​ProxyPass//​ sont évalués dans l'​ordre.
 +
 +Une url peut être ignorée via la syntaxe (en début):
 +<​code>​
 +ProxyPass /​url_a_ignorer ​ !
 +</​code>​
 +
 +Il est possible de limiter le pool de connexions établi par le proxy avec le backend
 +
 +À noter que cela ne peut pas fonctionner avec toutes les applications.
 +
 +Ainsi, les applications doivent être **modifiée** pour utiliser le cache de manière optimale (par exemple de servir les pages demandées par les connexions anonyme via le cache).
 +
 +un simple appel à ///​start_session//​ en début de page [[:​php|php]] entraîne probablement ​
 +
 +Voir [[varnish]]
 +
 +=== Load Balancing ===
 +
 +Installer et activer //​mod_proxy_balancer//​
 +
 +Activer le gestionnaire:​
 +<​code>​
 +<​Location /​balancer-manager>​
 +SetHandler balancer-manager
 +
 +Order Deny,Allow
 +Deny from all
 +Allow from 192.168
 +</​Location>​
 +</​code>​
 +
 +Définir un ensemble:
 +<​code>​
 +<Proxy balancer://​mycluster>​
 +  BalancerMember http://​serveur1:​80 route=rte1
 +
 +  # cluster member 2
 +  BalancerMember http://​serveur2:​80 route=rte2
 +</​Proxy>​
 +
 +ProxyPass /​balancer-manager !
 +ProxyPass / balancer://​mycluster/​ lbmethod=byrequests stickysession=BALANCEID
 +ProxyPassReverse / http://​serveur1/​
 +ProxyPassReverse / http://​serveur2/​
 +</​code>​
 +
 +Sur les serveurs 1 et 2, activer l'​écriture d'un cookie pour s'​assurer que toutes les requêtes soient associées au même serveur:
 +<​code>​
 +RewriteEngine On
 +RewriteRule .* - [CO=BALANCEID:​balancer.lb1:​.mydomain.com]
 +</​code>​
 +
 +=== tester ===
 +
 +s'​assurer (c'est idiot mais visible) que les 2 serveurs n'ont pas les même données. faire un curl -n sur le proxy. Voir le résultat dans le gestionnaire.
 +=== Cache ===
 +<​code>​
 +<​IfModule mod_disk_cache.c>​
 +CacheRoot "/​usr/​local/​apache/​proxy"​
 +CacheSize 500
 +CacheDirLevels 5
 +CacheDirLength 3
 +</​IfModule>​
 +</​code>​
 +
 +==== mod_rewrite ====
 +
 +réécriture d'url très (trop?) puissant
 +
 +À utiliser en dernier recours.
 +
 +Intérêt principal: peut être utilisé dans un //​htaccess//​
 +
 +Son utilisation peut souvent être remplacée par //​mod_alias//​
 +# petit rappel sur les expressions régulière ?
 +
 +--
 +//​RewriteRule MODELE SUBSTITUTION [DRAPEAUX]//​
 +
 +  * MODELE se base sur REQUEST URI
 +  * SUBSTITUTION:​
 +   * - : ne rien faire
 +   * s'​appliquer sur la partie détectée par le modele
 +   * url absolue
 +   * url relative
 +
 + <​code>​
 +RewriteRule ^/jeux.* /​usr/​local/​jeux/​web
 +</​code>​
 +
 +
 +<​code>​
 +RewriteRule ^/foo$ /bar
 +</​code>​
 +
 +<​code>​
 +RewriteRule ^/​produits/​vues$ http://​site2.example.com/​voirproduits.html [R]
 +</​code>​
 +
 +Références arrières
 +
 + <​code>​
 +RewriteRule ^/​produits/​(.*)/​view$ /​var/​web/​produitsdb/​$1
 +</​code>​
 +
 +Les drapeaux modifient le comportement de la règle
 + voir http://​httpd.[[:​apache|apache]].org/​docs/​2.2/​rewrite/​flags.html
 +  * C règle chainée avec la suivante
 +  * F forbidden
 +  * L fin du traitement
 +  * NC (nocase)
 +  * P proxy 
 +  * PT permet de traiter SUBSTITUTION comme une url et nom pas comme un chemin.
 +  * R=CODE redirection
 +
 +
 +RewriteCond ChaîneATester Condition [drapeaux]
 +  * ChaîneATester : généralement une variable serveur
 +  * Condition: regexp, comparaison de chaîne, test sur fichier
 +
 +Références arrières : le contenu capturé par les () est accessible via les variable **%**N
 +
 +<​code>​
 +RewriteCond %{HTTP_HOST} (.*)
 +RewriteRule ^/(.*) /​sites/​%1/​$1
 +</​code>​
 +
 +
 +rassembler un ensemble de correspondance dans un fichier
 +
 +RewriteMap NOM TYPE:SOURCE
 +  * TYPE: txt, rnd ou dbm
 +  *  SOURCE: chemin vers le fichier
 +
 +ex de fichier rnd: 
 +<​code>​
 +# static www1|www2|www3|www4|www1
 +# dynamic www5|www6
 +</​code>​
 +
 + avec le TYPE <​i>​int</​i>​
 +  * int:toupper
 +  *  int:tolower
 +  * int:escape
 +  * int:​unescape
 +
 +RewriteMap lc int:tolower
 +
 +RewriteRule (.*[A-Z]+.*) ${lc:$1} [R] 
 +
 +=== Exercices ===
 +
 +  * renommage d'une page (visible ou pas)
 +  * déplacement d'une page
 +
 +
 +=== Exercice ===
 +si .[[:​php|php]] exists et si .html n'​existe pas,
 +   alors toute requête sur .html renvoie .php
 +<​code>​
 +<​Directory /​var/​www/​htdocs>​
 +  RewriteEngine on
 +  RewriteBase /​var/​www/​htdocs
 +  RewriteCond $1.php -f
 +  RewriteCond $1.html !-f
 +  RewriteRule ^(.*).html$ $1.php
 +  </​Directory>​
 +</​code>​
 +
 +Exercice : Empécher l'​accès aux images du site depuis un lien externe
 +<​code>​
 +RewriteCond %{HTTP_REFERER} !^$
 +RewriteCond %{HTTP_REFERER} !www.example.com [NC]
 +RewriteRule \.(gif|jpg|png)$ /​images/​go-away.png [R,​NC] ​
 +</​code>​
 +
 +=== Exercice ===
 +publier des url "​[[:​clients:​iep:​sympa|sympa]]"​ (ex: http://​example.org/​catalogue/​tele)
 +
 +À convertir en "​idProduit"​ pour les besoin du backend.
 +
 +<​code>​
 +RewriteMap product2id txt:/​etc/​apache2/​productmap.txt
 +RewriteRule ^/​product/​(.*) /​prods.php?​id=${product2id:​$1|NOTFOUND} [PT]
 +television 993
 +stereo 198
 +fishingrod 043
 +basketball 418
 +[[:​perso:​telephone|telephone]]328 ​
 +</​code>​
 +
 +
 +==== Sécurité ====
 +
 +=== Les risques ===
 +
 + deni de service
 + ​dégradation
 + vol d'​information
 + ...
 +
 +=== Permissions ===
 +
 +Tout est lié aux privilèges du compte//​apache//​g
 +et à ce qu'il peut faire (ou pas) dans
 +le répertoire //​ServerRoot//​g
 +le répertoire //​DocumentRoot//​g
 +le reste du système
 +
 +Il peut être intéressant de s'​assurer de la nom modification du binaires httpd
 +
 +=== Protection système de fichier ===
 +Protection système de fichier
 +
 +Tout interdire, et n'​ouvrir que le strict nécessaire.
 +<​code>​
 +<​Directory />
 +Order Allow, Deny
 +AllowOverride None
 +Options -FollowSymlinks -Index
 +</​Directory>​
 +</​code>​
 +
 +===  Informations renvoyées par le serveur ===
 +
 +ServerToken Prod
 +ServerSignature Off
 +
 +=== Lien Symboliques ===
 +#TODO
 +
 +=== CGI ===
 +ils tournent avec les privilèges du compte[[:​apache| ]]
 +
 +Ils ne doivent pas pouvoir être modifiés par tout un chacun.
 +
 +=== suexec ===
 +SuExec permet de faire tourner des script sous des identités distincts.
 +
 +répertoire parent et fichiers doit appartenir à l'​utilisateur / groupe référencé par la directive //​SuexecUserGroup//​.
 +
 +le module [[:​php|php]] doit être désactivé et le support php-cgi actif:
 +<​code>​
 + ​php_admin_flag engine off
 + ​Options Indexes FollowSymLinks ExecCGI ​
 + ​AddHandler cgi-script ​
 +</​code>​
 +la directive cgi_force_redirect doit être à 0 dans le [[:​php|php]].ini
 +
 +Ça marche aussi avec des cgi classiques. Dans cet exemple // /​var/​www/​cgi // et son contenu doivent appartenir à //​foo2:​bar//​
 +<​code>​
 +suexecusergroup foo2 bar
 +ScriptAlias /cgi /​var/​www/​cgi
 +<​Directory /​var/​www/​cgi>​
 +  require all granted
 +</​Directory>​
 +</​code>​
 +
 +Les logs d'​erreur sont dans message, pas dans les logs apache.
 +
 +
 +=== controle d'​acces ===
 +Order allow, deny
 +Allow from 127.0.0.1
 +
 +=== authentification ===
 +
 +modules mod_auth*
 +directives AuthName, AuthType, AuthUserFile,​ (AuthGroupFile),​ require et satisfy
 +
 +=== restreindre les actions possibles ===
 +
 +=== mod_security ===
 +
 +Permet de contrôler et d'​enregistrer finement les requêtes arrivant sur le serveur, et de se prémunir contre les attaques de type XSS, injection SQL, etc.
 +
 +
 +=== installation ===
 +
 +yum install mod_security
 +
 +=== Principes de fonctionnement ===
 +
 +Activer //​SecRuleEngine On//
 +
 +Relancer [[:​apache|apache]].
 +
 +=== Désactiver / diagnostiquer ===
 +
 +Voir le fichier de log
 +
 +Utiliser l'​**id** en paramètre d'une directive //​SecRuleRemoveById//​ dans un //​LocationMatch//​ adéquat.
 +
 +=== Détail d'une directive SecRule ===
 +
 +<​code>​
 +SecRule VARIABLES OPERATOR [ACTION]
 +</​code>​
 +
 +VARIABLES: les variables (d'​entête ?) à vérifier (par ex: REQUEST_URI|QUERY_STRING)
 +OPERATOR: expressions déclenchant la règle. Peut être une expression régulière,​ une comparaison numérique, etc.
 +ACTION: la ou les actions à réaliser ( enregistrer dans les logs, transformer les variables traitées, autoriser, etc.
 +
 +=== Conclusion ===
 +
 +mod_security apporte à la fois des mécanismes de protection efficace et des risques de dysfonctionnement importants.
 +
 +Il est basés sur des règles en réponse à des attaques connues et existantes. L'​adaptation ou la création de règles demeurent un exercice difficile.
 +
 +Il rend par exemple l'​utilisation d'un [[:​wiki|wiki]] pour centraliser de la documentation sur [[:​apache|apache]] difficile.
 +
 +=== mod_evasive ===
 +
 +mod_evasive permet de blacklister un utilisateur demandant //trop de page dans un court délai//.
 +
 +Par défaut, pas plus de 2 pages par secondes, et pas plus de 50 requêtes par seconde.
 +
 +
 +
 +=== Exercices ===
 +  * Protection de l'​accès au serveur par authentification "​simple"​
 +  * Protection de l'​accès au serveur par authentification sur le serveur ldap du [[:​clients:​crealys:​poste|poste]] du formateur. compte //​uid=webuser,​ou=users,​dc=tc//,​ mot de passe //web//
 +  * Accès sans mot de passe autorisé depuis la machine [[:​locale|locale]].
 +  * Mise en place de [[apache.suexec|suexec]].
 +
 +
 + ==== Ajouter le support ssl sur un serveur Debian/​apache2 ====
 +
 + ​=== ​ prérequis: ==
 +
 +  * le module [[:ss|ssl]]
 +  * Une installation d'​[[:​apache|apache]] fonctionnelle.
 +  * Un certificat serveur, la clé correspondante,​ le certificat de l'​autorité de certification.
 +
 + ​=== ​ activation du module: ===
 +<​code>​
 +a2enmod ssl
 +</​code>​
 +
 + ​=== ​ Configuration globale: ===
 +
 +  * Copier les certificats et la clé dans le répertoire de configuration [[:​apache|apache]].
 +  * Vérifier les permissions ( owner root et mode 400 ).
 +  * Rajouter la ligne **Listen 443** dans **/​etc/​apache2/​ports.conf**.
 +
 + ​=== ​ Configuration d'un site: ===
 +
 +Pour convertir un vhost existant, il suffit de changer le **numéro de port** et de rajouter les lignes **SSL  ***.
 +
 +Ne pas oublier d'​ajouter la directive **"​NameVirtualHost ​  ​*:​443"​**au tout début du fichier:
 +<​code>​
 +NameVirtualHost ​  *:443
 +<​VirtualHost ​  ​*:​443>​
 +   ​ServerName backup.opendoor.fr
 +   ​ServerAlias backup
 +   ​DocumentRoot /​var/​www/​pmwiki
 +   <​cLocation />
 +
 +      Options Indexes FollowSymLinks
 +      DirectoryIndex pmwiki.php
 +      AllowOverride All
 +      Order deny,allow
 +   </​Location>​
 +
 +   ​SSLEngine on
 +   ​SSLCACertificateFile /​etc/​apache/​ssl.crt/​cacert.pem
 +   ​SSLCertificateFile /​etc/​apache/​ssl.crt/​cert.pem
 +   ​SSLCertificateKeyFile ​ /​etc/​apache/​ssl.key/​key.pem
 +
 +</​VirtualHost>​
 +</​code>​
 +
 + ​=== ​ forcer la redirection http -> https ===
 +
 +Ajouter le code suivant dans le fichier de configuration de votre site:
 +<​code>​
 +RewriteEngine On 
 +RewriteCond ​ %{SERVER_PORT} ​ = ^443$ =
 +RewriteRule ^(.  *)$ https://​serveur_https/​$1 [L,R]
 +</​code>​
 +
 +<​code>​
 +RewriteCond %{HTTPS} !=on
 +RewriteRule ^.*$ https://​%{SERVER_NAME}/​%{REQUEST_URI} [R,L]
 +</​code>​
 +
 + === Configuration SSL avancée ===
 + == log ==
 +
 +En utilisant le //Custom Log Format//, on peut enregistrer dans les logs la valeur des variables définies par le module //​mod_ssl//,​ Ex:
 +<​code>​
 +CustomLog logs/​ssl_request_log "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"​%r\"​ %b"
 +</​code>​
 +
 + == Contrôler le niveau de chiffrement ==
 +
 +On peut influer sur la liste des algos utilisables via la directive CipherSuite:​
 +
 +Cette directive prend des //​spécifications de cipher// séparés par : 
 +
 +Des alias de simplifier la tâche.
 +
 +Exemple : forcer l'​utilisation d'une crypto forte:
 +<​code>​
 +SSLProtocol all
 +SSLCipherSuite HIGH:MEDIUM
 +</​code>​
 +
 + == Portée ==
 +
 +Normalement global, mais il est possible d'​inclure la directive //​SSLCipherSuite//​ dans une clause //​Location//​ ou //​Directory//​ de manière à forcer une //​renégociation SSL//.
 +
 + == Considérations ==
 +
 +Le //​SSLProtocol//​ SSLv2 est obsolète et présente des faiblesses d'un point de vue sécurité.
 +
 +L'​alias CypherSuite //EXPORT// regroupe des algo de chiffrement //faibles//
 +
 + == Authentification client ==
 +
 +Le serveur doit "​connaître"​ le certificat de la CA ayant signé les certificats client (//​SSLCACertificateFile//​) et positionner la directive //​SSLVerify//​ à
 +  * none
 +  * require
 +  * optional
 +  * optional_no_ca
 +
 +
 +==== SuExec ====
 +
 +=== prequis ===
 +
 +principe de la séparation des privilèges,​ permissions suid et sgid.
 +
 +permet de faire tourner des script sous des identités distincts, avec un certain nombre de restrictions.
 +
 +répertoire parent et fichier doit appartenir à l'​utilisateur / groupe
 +référencé par la directive //​SuexecUserGroup//​
 +
 +Les scripts doivent être à un endroit bien précis (définis lors de la compilation de //​suexec//​):​
 +<​code>/​usr/​sbin/​suexec -V
 + -D AP_DOC_ROOT="/​var/​www"​
 + -D AP_GID_MIN=100
 + -D AP_HTTPD_USER="​[[:​apache|apache]]"​
 + -D AP_LOG_EXEC="/​var/​log/​httpd/​suexec.log"​
 + -D AP_SAFE_PATH="/​usr/​local/​bin:/​usr/​bin:/​bin"​
 + -D AP_UID_MIN=500
 + -D AP_USERDIR_SUFFIX="​public_html"​
 +</​code>​
 +
 +le module [[:​php|php]] doit être désactivé et le support php-cgi actif:
 +<​code>​
 + ​[[:​php|php]]_admin_flag engine off
 + ​Options Indexes FollowSymLinks ExecCGI ​
 + ​AddHandler cgi-script [[:php|.]]
 +</​code>​
 +
 +la directive //​cgi_force_redirect//​ doit être à 0 dans le [[:​php|php]].ini
 +
 +Enfin, pour éviter de devoir insérer un //shebang// au début de chaque script [[:​php|php]] pour une interprétation correcte:
 +<​code>​
 +echo ':​[[:​php|PHP]]:​E::​[[:​php|php]]::/​usr/​bin/​php-cgi:'​ > /​proc/​sys/​fs/​binfmt_misc/​register
 +</​code>​
 +ou en plus propre avec sysctl:
 +<​code>​
 +fs.binfmt_misc.[[:​php|PHP]] = disabled
 +fs.binfmt_misc.[[:​php|PHP]] = interpreter /​usr/​bin/​php-cgi
 +fs.binfmt_misc.[[:​php|PHP]] = flags: ​
 +fs.binfmt_misc.[[:​php|PHP]] = extension [[:php|.]]
 +</​code>​
 +
 +=== Débogage ===
 +
 +Tout est dans les permissions.
 +
 +Source d'​informatin principale, le log, que l'on peut obtenir via la commande ​
 +<​code>​suexec -V</​code>​
 +
 +Ce sont en général des problèmes de permissions sur:
 +  * le répertoire contenant le script //wrapper// (user.user)
 +  * le script //wrapper// lui-même (user.user)
 +  * l'​exécutable // /​usr/​sbin/​suexec // (root.[[:​apache|apache]] et SUID)
 +
 +Des erreurs se traduisent par l'​apparition des messages suivants dans les log [[:​apache|apache]]:​
 +
 +  * //​fcgid_warn connection reset by peer//
 +  * //error reading data from fastCGI server//
 +  * ...
 +
 +
 +====  WebDAV et apache ====
 +
 +Installation et configuration des modules //dav// et //dav_fs// pour[[:​apache| ]]
 +
 + ​=== ​ Prérequis: ===
 +
 +Un serveur [[:apache]] fonctionnel,​ avec si possible [[:​ss|ssl]].
 +
 + ​=== ​ Installation ===
 +
 +Il suffit d'​activer les modules //dav_fs// et de donner à l'​utilisateur //​www-data//​ le droit d'​écriture sur le répertoire ///​var/​lock/​apache2//:​
 +  ​
 +<​code>​
 +chmod 770 /​var/​lock/​apache2
 +chown .www-data /​var/​lock/​apache2
 +</​code>​
 +
 +
 + ​=== ​ Configuration:​ ===
 +Il suffit de rajouter la directive //Dav On// au contexte //​Directory//​ que l'on veut rendre accessible par webDAV. Ce répertoire doit être accessible en lecture-écriture par l'​utilisateur ww-data.
 +
 +Il est conseillé de rajouter des directives d'​authentification de type //digest//.
 +
 + ​=== ​ Utilisation:​ ===
 +  * Avec //​nautilus//,​ menu //fichier// -> //se connecter à un serveur//
 +
 +
 +==== Apache sur Windows ====
 +
 +=== Biblio / sources ===
 +https://​httpd.[[:​apache|apache]].org/​docs/​2.4/​platform/​windows.html
 +
 +=== Installation ===
 + 
 +Télécharger une version binaire depuis apachelounge.com
 +
 +Décompresser
 +
 +Adapter le fichier de configuration à votre répertoire d'​installation (qui s'​attend à retrouver ses fichiers dans c:​\apache24)
 +
 +=== Principaux répertoires ===
 +
 +Tout dans un même répertoire.
 +  * bin - exécutables,​ notamment //httpd//
 +  * cgi-bin
 +  * conf - la conf, notamment extra et original
 +  * error
 +  * htdocs - configuration,​ avec notamment une arbo contenant les fichiers d'​origine
 +  * icons - icones utilisé pour la vue arborescente
 +  * include - en-tête (pour la compilation de modules externes)
 +  * lib - biblio de fonctions partagées
 +  * logs - logs
 +  * manual - documentation
 +  * modules - modules
 +
 +=== Gestion du service ===
 +
 +=== Compte utilisateur ===
 +
 +Le service tourne sous le compte //​localsystem//​ qui ne convient pas si [[:​apache|apache]] a besoin d'un accès réseau
 +
 +
 +Activer le service
 +<​code>​
 +%INSTALLDIR%\bin\httpd.exe -k install
 +</​code>​
 +
 +**note** on peut spécifier un **nom de service** avec l'​option -n
 +
 +Lancer le service
 +<​code>​
 +net start [[:​apache|Apache]]24
 +</​code>​
 +
 +relancer le service:
 +<​code>​
 +httpd -k restart
 +</​code>​
 +
 +Vérifier la validité syntaxique de la configuration:​
 +<​code>​
 +httpd -t
 +</​code>​
 +
 +=== Logs ===
 +
 +Les logs d'​erreur [[:​windows|windows]] (//​eventvwr//​) peuvent contenir des infos sur le démarrage du servive (avant que le système de log propre à [[:​apache|apache]] n'ait le temps de prendre le relais)
 +
 +
 + ==== Performances ====
 +
 + === désactiver les modules inutiles ===
 +
 + === Choix du MPM ===
 +
 + * worker et prefork n'​apportent pas de gain de performance,​ mais worker sera plus économe en mémoire, mais aussi moins tolérant vis à vis de modules externes peu fiable ou non thread-safe
 + 
 + === DNS lookup ===
 +
 +//​HostnameLookups//​ à désactiver. Ne pas utiliser de nom de machine / domaine dans les directives de contrôles d'​accès. ​
 +
 +Si les noms de machines sont nécessaires pour les stats, utiliser [[logresolve]]
 +
 + === AllowOverride ===
 +
 +À n'​activer que pour les répertoires dans lesquels un htaccess est nécessaire.
 +
 + === FollowSymlink et FollowSymlinIfOwnerMatch ===
 +
 +À limiter.
 +
 + === MaxClients ===
 +
 +Trop faible : les ressources du système ne sont pas exploitées de manière optimale.
 +Trop haute : le système vas se mettre à swapper et tomber en carafe.
 +
 +Une formule : **MaxClients = Total RAM dedicated to the web server / Max child process size **
 +
 + === MinSpareServers ===
 +
 +Trop haut : gaspillage de ressource.
 +
 +Trop bas : échec lors d'un pic d'​activité. Un message d'​erreur est enregistré dans les log lorsque plus de 4 processus [[:​apache|apache]] sont créés par seconde.
 +
 + ​=== ​ MaxRequestPerChild ===
 +À positionner à quelques 1000 pour éviter les éventuelles fuites de mémoire.
 +
 + === KeepAlive and KeepAliveTimeout ===
 +
 +La 1ère est à activer et la 2ème à positionner assez bas pour:
 + * permettre d'​avoir plusieurs requêtes http par connexion
 + * éviter d'​avoir des processus en attente de fin de connexion **netstat**
 +
 + === Compression et cache ===
 +
 +voir [[apache.mod_cache|mod_cache]],​ [[apache.mod_expires|mod_expires]] et [[apache.mod_headers|mod_headers]]
 +
 + === Séparer contenu statique et dynamique ===
 +
 +Le code suivant permet de faire servir les images par un petit serveur et le reste par le "​gros"​ serveur:
 +<​code>​
 +ProxyPassReverse / http://​%{HTTP_HOST}:​8088/​
 + ​RewriteEngine on                                             ---- [9]
 + ​RewriteCond ​  ​%{REQUEST_URI} !.*.(gif|png|jpg)$
 + ​RewriteRule ^/(.*) http://​%{HTTP_HOST}:​8088/​$1 [P]
 +</​code>​
 +
 + === fastcgid ===
 +
 +Voir [[:​apache#​fastcgid | ici]]
 +
 +
 + ==== Cache ====
 +
 +depuis la v 2.2, les modules //​mod_cache//​ et //​mod_file_cache//​ ne sont plus considérés comme expérimentaux
 +
 + === mod_file_cache ===
 +
 +Permet la mise en cache de fichiers statiques, rarement mis à jour.
 +
 + === mod_cache ===
 +
 +Si l'url demandée est dans le cache et n'est pas arrivée à expiration, alors aucune des actions (mod_proxy, mod_rewrite) associées à cette requête ne sera exécutée.
 +
 +Directives importantes:​
 +  * UseCanonicalName - permet à un hôte virtuel avec plusieurs nom / alias d'​utiliser le même cache.
 +  * CacheDefaultExpire - 
 +
 +
 +
 + ==== benchmark ====
 + === ab ===
 +
 +livré en standard. Utilisation typique:
 +<​code>​
 +av -kc 10 -n 1000 http://​serveur/​url/​
 +</​code>​
 +
 +Attention de bien tester une adresse //valide// ( si le nombre de réponses par seconde est anormalement élevé et sil la valeur de //non-2xx responses// est différente de 0, méfiance ).
 +
 + === jmeter ===
 +
 +TODO
 +
 + === Quelques résultats de benchmark ===
 +
 +réalisé sur la même machine (vm baratine) avec la commande <​code>​ ab -c 100 -t 30 url</​code>​ :
 +
 +== page statique ==
 +^ serveur ^ Request per seconds ^time per request ^99% ^ remarque ^
 +| apache prefork | entre 600 et 780 | entre 1.3 et 1.6 | entre 408 et 587 | charge élevée, résultats irréguliers d'un test à l'​autre |
 +| apache worker | entre 1380 et 1630 | entre 0.6 et 0.6 | 1040 | |
 +| nginx | environ 2000 | 0.5 | 260 | conf par défaut, charge faible, résultats réguliers |
 +
 +== page dynamique phpinfo ==
 +^ serveur ^ Request per seconds ^time per request ^99% ^ remarque ^
 +| apache prefork | entre 53 et 75 | entre 13 et 18.6 | entre 2560 et 5300 | résultat irréguliers,​ forte charge|
 +| nginx + php-fpm | entre 124 et 156 | entre 6.4 et 8 | entre 3500 et 4000 | charge faible, conf par défaut |
 +| apache worker + php-fpm | 103 | 9 | 148 | charge faible, mais **des requètes en erreur** |
 +| apache + event + php-fpm | 130 | 7,5 | 3800 | requètes en erreur |
 +
 +
 +
 +# vim: set filetype=dokuwiki:​
  
apache.txt · Dernière modification: 2018/03/09 11:52 (modification externe)