Table des matières

Apache

Cette page est juste un mémo

Docs ⇒ http://devdocs.io/apache_http_server/

Commandes utiles

Tester les configs avant de faire un reload ou un restart

apache2ctl -t

reloader, restarter etc..

service apache2 restart
/etc/init.d/apache2 restart
apache2ctl restart

Afficher les modules chargés

apache2ctl -t -D DUMP_MODULES

ou

apache2ctl -M

D’autre commande

apache2ctl -h

Afficher le status

apache2ctl status

Encore plus détaillé

apache2ctl fullstatus

Configuration de base

La doc ⇒ http://httpd.apache.org/docs/2.2/fr/

Le minimum pour un accès avec un nom de domaine

# Apache doit écouter sur le port 80
Listen 80
 
# Toutes les adresses IP doivent répondre aux requêtes sur les 
# serveurs virtuels
NameVirtualHost *:80
 
<VirtualHost *:80>
DocumentRoot /www/example.com
ServerName www.example1.com
 
# Autres directives ici
 
</VirtualHost>
 
<VirtualHost *:80>
DocumentRoot /www/example.org
ServerName www.example2.org
 
# Autres directives ici
 
</VirtualHost>

Les directives

<Directory /usr/local/httpd/htdocs>
  AllowOverride None
  Options Indexes FollowSymLinks
</Directory>

Les options

Accès par mot de passe

#accès au fichier de mot de passe généré par la commande htpasswd
AuthUserFile .htpasswd
AuthGroupFile /dev/null
AuthName "Ce message s'affichera dans la boite de dialogue demandant l'identification"
AuthType Basic
<Limit GET POST>
  require valid-user
</Limit>

Installation de Apache2-mpm-worker

http://www.skyminds.net/serveur-dedie-installation-dapache-php-mysql-et-webmin/

Voici les paquets standards à installer

ii  apache2                                      2.2.16-6+squeeze4                            Apache HTTP Server metapackage
ii  apache2-mpm-worker                           2.2.16-6+squeeze4                            Apache HTTP Server - high speed threaded model
ii  apache2-utils                                2.2.16-6+squeeze4                            utility programs for webservers
ii  apache2.2-bin                                2.2.16-6+squeeze4                            Apache HTTP Server common binary files
ii  apache2.2-common                             2.2.16-6+squeeze4                            Apache HTTP Server common files

ii  mysql-client-5.1                             5.1.49-3                                     MySQL database client binaries
ii  mysql-common                                 5.1.49-3                                     MySQL database common files, e.g. /etc/mysql/my.cnf
ii  mysql-server                                 5.1.49-3                                     MySQL database server (metapackage depending on the latest version)
ii  mysql-server-5.1                             5.1.49-3                                     MySQL database server binaries and system database setup
ii  mysql-server-core-5.1                        5.1.49-3                                     MySQL database server binaries

ii  php5                                         5.3.3-7+squeeze3                             server-side, HTML-embedded scripting language (metapackage)
ii  php5-cgi                                     5.3.3-7+squeeze3                             server-side, HTML-embedded scripting language (CGI binary)
ii  php5-cli                                     5.3.3-7+squeeze3                             command-line interpreter for the php5 scripting language
ii  php5-common                                  5.3.3-7+squeeze3                             Common files for packages built from the php5 source
ii  php5-curl                                    5.3.3-7+squeeze3                             CURL module for php5
ii  php5-gd                                      5.3.3-7+squeeze3                             GD module for php5
ii  php5-mcrypt                                  5.3.3-7+squeeze3                             MCrypt module for php5
ii  php5-mysql                                   5.3.3-7+squeeze3                             MySQL module for php5
ii  php5-suhosin                                 0.9.32.1-1                                   advanced protection module for php5

ii  postfix                                      2.7.1-1+squeeze1                             High-performance mail transport agent

Pour que php5 marche avec la version worker, il est indispensable d’installer le paquet

libapache2-mod-fcgid

Il faut ajouter les lignes suivantes dans le fichier /etc/apache2/httpd.conf

# pour faire marcher php5 avec apache2-mpm-worker
AddHandler fcgid-script .php
FCGIWrapper /usr/lib/cgi-bin/php5 .php
Options ExecCGI

il faut aussi activer les modes suivant :

a2enmod cache
a2enmod fcgid
a2enmod headers
a2enmod rewrite

Très important aussi, pour le php5, il faut configurer le fichier /etc/php5/cgi/php.ini mais il ne faut surtout pas négliger /etc/apache2/mods-available/fcgid.conf

Toutes les options ici http://httpd.apache.org/mod_fcgid/mod/mod_fcgid.html#fcgidmaxrequestlen

Problème

Problème rencontré et solution.

apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName

Il suffit de modifier le fichier /etc/hosts et de rajouter un localhost.localdomain avant le localhost

Avant

127.0.0.1       localhost       swp.localhost     rdlaptop.rdomain

Après

127.0.0.1       localhost.localdomain        localhost       swp.localhost     rdlaptop.rdomain

Votre fichier peut aussi ressembler à ca

127.0.0.1       localhost.localdomain   localhost
77.77.77.77     p2pfr

Remplacez par ca

127.0.0.1       localhost.localdomain   localhost
77.77.77.77     p2pfr.localdomain       p2pfr

Surtout ne faite pas l’erreur de mettre

127.0.0.1       localhost.localdomain   localhost
77.77.77.77     p2pfr.com               p2pfr

Sinon apache ne prendra pas en compte la config de votre site avec comme nom de domaine p2pfr.com, il passera directement par la config default

Log d'apache

Tous les logs d’apache se trouvent dans /var/log/apache2.

Dans mon cas, j’ai décidé de créer un répertoire par site web afin d’y stocker les logs access.log et error.log. Et c’est dans ce cas précis qu’il faut faire attention à logrotate !!

En effet, la config de logrotate pour apache est la suivante :

/var/log/apache2/*.log {
        weekly
        missingok
        rotate 52
        compress
        delaycompress
        notifempty
        create 640 root adm
        sharedscripts
        postrotate
                /etc/init.d/apache2 reload > /dev/null
        endscript
}

Logrotate ne gère donc que le répertoire /var/log/apache2 mais pas ces sous répertoire !
Modifiez alors ce fichier en ajoutant le répertoire de destination /var/log/apache2/*/*.log.

/var/log/apache2/*.log /var/log/apache2/*/*.log {
        weekly
        missingok
        rotate 52
        compress
        delaycompress
        notifempty
        create 640 root adm
        sharedscripts
        postrotate
                /etc/init.d/apache2 reload > /dev/null
        endscript
}

Si vous avez des sous-sous répertoire, ajoutez /var/log/apache2/*/*/*.log etc…

Pour ceux qui utilise awstats ou tout autre script qui doit lire les fichiers de log, pensez à modifier la ligne

create 640 root adm

par

create 644 root adm

internal dummy connection

— source: https://blog.nicolargo.com/2011/03/supprimer-les-logs-apache-internal-dummy-connection.html

Si vous avez plein de log apache avec des lignes internal dummy connection, créez un fichier de conf avec

# Filters
SetEnvIf Remote_Addr "127\.0\.0\.1" local
SetEnvIf Remote_Addr "\:\:1" local

Ensuite, on doit activer ce filtre le fichier de définition de votre site (sous le répertoire /etc/apache2/site-enabled). Il faut modifier la ligne suivante:

CustomLog /var/log/apache2/www-access.log combined env=!local

Un restart d’apache pour appliquer

Lorsque Apache est installé dans un NAT à travers d'un reverse proxy

J’ai constaté que lorsque apache est installé dans un LAN et que les connexions HTTP passent par un reverse proxy (ici pound) la variable PHP $_SERVER[REMOTE_ADDR] renvoie l’adresse ip du serveur proxy.

La 1ère solution aurait été de recoder le code de vos script php en remplacant $_SERVER[REMOTE-ADDR] par $_SERVER[X_FORWARDED_FOR] mais ce n’est pas pratique et pas très recommandable.

Il existe donc un module apache nommé rpaf ( voir http://stderr.net/apache/rpaf/ ) dispo dans les dépots debian.

Installé le via la commande

aptitude install libapache2-mod-rpaf

Ajoutez un petit de code dans votre config apache /etc/apache2/httpd.conf

<IfModule mod_rpaf.c>
RPAFenable On
RPAFsethostname On
RPAFproxy_ips 127.0.0.1, xx.xx.xx.xx
</IfModule>

Remplacez les xx.xx.xx.xx par l’ip public de votre serveur proxy.

Activez le module et rechargez apache

a2enmod rpaf
service apache2 reload

et voila ;)

PHP

Les log de php sont par défaut un truc de ouf… Si vous regardé les log error.log d’apache vous trouverez des milliers de ligne de mod_fcgid: stderr: PHP Notice: et il convient de modifier php.ini pour éviter toutes ses lignes qui ne servent à rien et qui remplit/fait ramer votre serveur pour rien.

/etc/php5/cgi/php.ini
Remplacez ca

error_reporting = E_ALL & ~E_DEPRECATED

par ca

error_reporting = E_ALL & ~E_DEPRECATED & ~E_NOTICE

Ensuite on recharge apache2

service apache2 reload

Quelques préconisations de configuration et sécurité ⇒ http://wiki.goldzoneweb.info/configuration_securisation_et_optimisations_de_php

ALERT - script tried to increase memory_limit

Quand on a Wordpress d’installé, on peut remarqué dans le syslog de nombreuses lignes d’alerte de suhosin

suhosin[20206]: ALERT - script tried to increase memory_limit  to 268435456 bytes which is above the allowed value (attacker '82.xxx.xxx.xxx', file '/var/www/xxxxx', line 12)

On édite le fichier de config php qui ici tourne comme un cgi /etc/php5/cgi/php.ini on cherche la variable memory_limit et on la fixe à 256M

; Maximum amount of memory a script may consume (128MB)
; http://php.net/memory-limit
memory_limit = 256M

Les mods d'apache

expires

doc : http://httpd.apache.org/docs/current/fr/mod/mod_expires.html

Il est important de mettre en cache certains fichiers qui ne bougent jamais comme les images, scripts js et fichiers css. Le cache en question est situé côté client et économisera de la bande passante sur le serveur.

<IfModule mod_expires.c>
      ExpiresActive On
      ExpiresByType image/gif "access plus 30 days"
      ExpiresByType image/jpg "access plus 30 days"
      ExpiresByType image/jpeg "access plus 30 days"
      ExpiresByType image/png "access plus 30 days"
      ExpiresByType image/x-icon "access plus 30 days"
      ExpiresByType text/css "access plus 1 days"
      ExpiresByType application/x-javascript "access plus 3 days"
</IfModule>

mod_fcgid: read data timeout in 40 seconds

Si vous voyez ça dans vos log, il vous faut rajouter ça dans /etc/apache2/mods-available/fcgid.conf

IPCCommTimeout 240

Tester les performances

Avec httperf voir très bon tuto ⇒ http://www.synbioz.com/blog/benchmark_avec_httperf

Un outils intégré avec apache, ab pour apache benchmark

Pour tester une url avec 2000 requêtes dont 10 en simultanées

ab -c 10 -n 2000 'https://mon_serveur/url_a_bourriner'

Pour envoyer en POST, créer un fichier post.txt avec les paramètres urlencodé

email=toto%40toto.fr&variable=1

Utilisez la commande suivante

ab -p post.txt -T 'application/x-www-form-urlencoded' -c 10 -n 2000 'https://mon_server/api/test'

Sécurité

Pour cacher la version de apache et autre

vi /etc/apache2/conf.d/security
ServerTokens Prod
ServerSignature Off
TraceEnable Off

Pour cacher la version de php, modifiez php.ini et configurer la variable suivante

expose_php = Off

apache2-mpm-itk

Après quelques années d’expériences avec apache2, nous avons abandonné la version worker au profit de la version prefork. Aujourd’hui nous passons de prefork à itk.

La migration se fait sans douleurs avec un

apt-get install apache2-mpm-itk

Ceci remplace apache2-mpm-prefork et toute la config reste compatible sans problème.

Le mpm itk permet de choisir un uid:gid différent pour chaque virtual-host et ce sans avoir recours aux cgi ou aux modules suexec ou suphp, ce qui est extrêmement pratique dans le cadre d’un hébergement mutualisé ainsi que dans certains cas pratiques.

Coté sécurité, le mpm itk permet d’isoler la configuration de chaque vhost directement dans son fichier de configuration.

Il n’y a plus qu’a créer un utilisateur et de rajouter ces lignes dans vos config

<IfModule mpm_itk_module>
  AssignUserId username groupname
</IfModule>

Plus d’info :

En cas de piratage

Restaurer une sauvegarde et comparer les répertoires avec diff

diff -qr repOK repHACKED

Recopier que les fichiers qui ont changé avec rsync

rsync -avP repOK repHACKED

Refaite un diff pour des nouveaux fichiers ne serait pas resté tout seul

Comparer les logs

Debian 10 Apache 2.4 php7.3

Sur la dernière debian, apache est par défaut apache mpm event. Plus question ici d’installer le module apache php. Pour activer php, suivez les commandes

apt install php7.3-fpm
a2enmod proxy_fcgi
a2enconf php7.3-fpm
systemctl restart apache

le module itk n’est plus nécessaire, maintenant on peut gérer les users directement dans la config des pools php

⇒ doc: https://villalard.net/utiliser-apache-avec-php-fpm

# cd /etc/php/7.3/fpm/pool.d
# ls
www.conf

cp www.conf dev.conf
vi dev.conf

On modifie au minimum

; Start a new pool named 'www'.
; the variable $pool can be used in any directive and will be replaced by the
; pool name ('www' here)
[dev]

; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
;       will be used.
user = edmc
group = edmc

; The address on which to accept FastCGI requests.
; Valid syntaxes are:
;   'ip.add.re.ss:port'    - to listen on a TCP socket to a specific IPv4 address on
;                            a specific port;
;   '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
;                            a specific port;
;   'port'                 - to listen on a TCP socket to all addresses
;                            (IPv6 and IPv4-mapped) on a specific port;
;   '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
listen = /run/php/dev.sock

ensuite on adapte notre config apache

        <FilesMatch \.php$>
                SetHandler "proxy:unix:/run/php/dev.sock|fcgi://localhost/"
        </FilesMatch>

on restart php et apache

systemctl restart php7.3-fpm.service apache2.service

et voila :)

htcacheclean

Activez les modules

a2enmod mod_cache mod_cache_disk

Dans la config du site, pour un cache de 60 secondes

    <IfModule mod_cache.c>
      <IfModule mod_cache_disk.c>
        #LogLevel debug
        CacheRoot /var/cache/apache2/mod_cache_disk
        CacheDefaultExpire 60
        CacheMinExpire 60
        CacheMaxExpire 60
        CacheEnable disk /
        #CacheDetailHeader On
        CacheHeader On
        CacheIgnoreCacheControl On
        CacheIgnoreNoLastMod On
        CacheStoreNoStore On
        CacheStoreExpired On
        #CacheIgnoreHeaders None
        #CacheDisable "/index.php"
        #UnsetEnv no-cache
      </IfModule>
    </IfModule>

Voir les fichiers en cache

htcacheclean -A -p/var/cache/apache2/mod_cache_disk

Si vous avez configuré un autre répertoire que celui par défaut, la purge ne se fera pas, mettez un cron

0 */2 * * * /usr/bin/htcacheclean -n -t -p/home/user/apache2_mod_cache_disk -l100M

Cette exemple purge toutes les 2 heures en vérifiant que la taille globale ne dépasse pas 100Mo, -t supprimer les répertoires vide (important car il peut vite y’en avoir un paquet), -n met une priorité basse au processus afin de ne pas bloquer le serveur.