« Security/Services/Apache » : différence entre les versions

De TartareFR
Aller à la navigation Aller à la recherche
(Annulation des modifications 2702 de Didier (discussion))
 
(3 versions intermédiaires par le même utilisateur non affichées)
Ligne 1 : Ligne 1 :
= Sécuriser son serveur Apache =
<big>'''Sécuriser son serveur Apache'''</big>
{{Admon/logo|TuxCRS.png}}
{{Admon/logo|TuxCRS.png}}
C'est ballot de mettre une serrure aux fenêtres si la porte reste grande ouverte.
C'est ballot de mettre une serrure aux fenêtres si la porte reste grande ouverte.
Ligne 162 : Ligne 162 :
=== Activer le module mod_security ===
=== Activer le module mod_security ===


mod_security module Apache écrit par Ivan Ristic, l'auteur du livre ''Apache Security'' des éditions O'Reilly.
[[Webserver/Apache/Modules/Security|mod_security]] est un module Apache écrit par Ivan Ristic, l'auteur du livre ''Apache Security'' des éditions O'Reilly.
 
mod_security peut:


[[Webserver/Apache/Modules/Security|mod_security]] peut:
*Filtrage simple
*Filtrage simple
*Filtre basé sur des expressions régulières
*Filtre basé sur des expressions régulières
Ligne 307 : Ligne 306 :
SecChrootDir /chroot/apache
SecChrootDir /chroot/apache
</syntaxhighlight>
</syntaxhighlight>
== mod_ssl ==
How to solve particular security constraints for an SSL-aware webserver is not always obvious because of the coherences between SSL, HTTP and Apache's way of processing requests. This chapter gives instructions on how to solve such typical situations. Treat is as a first step to find out the final solution, but always try to understand the stuff before you use it. Nothing is worse than using a security solution without knowing it's restrictions and coherences.
=== Cipher Suites and Enforced Strong Security ===
{{Admon/faq|How can I create a real SSLv2-only server?    [L]|The following creates an SSL server which speaks only the SSLv2 protocol and its ciphers.<br>
Fichier httpd.conf
<syntaxhighlight lang="apache">
SSLProtocol -all +SSLv2
SSLCipherSuite SSLv2:+HIGH:+MEDIUM:+LOW:+EXP
</syntaxhighlight>}}
{{Admon/faq|How can I create an SSL server which accepts strong encryption only?    [L]|The following enables only the seven strongest ciphers:
Fichier httpd.conf
<syntaxhighlight lang="apache">
SSLProtocol all
SSLCipherSuite HIGH:MEDIUM
</syntaxhighlight>}}
{{Admon/faq|How can I create an SSL server which accepts strong encryption only, but allows export browsers to upgrade to stronger encryption?    [L]|This facility is called Server Gated Cryptography (SGC) and details you can find in the README.GlobalID document in the mod_ssl distribution. In short: The server has a Global ID server certificate, signed by a special CA certificate from Verisign which enables strong encryption in export browsers. This works as following: The browser connects with an export cipher, the server sends it's Global ID certificate, the browser verifies it and subsequently upgrades the cipher suite before any HTTP communication takes place. The question now is: How can we allow this upgrade, but enforce strong encryption. Or in other words: Browser either have to initially connect with strong encryption or have to upgrade to strong encryption, but are not allowed to keep the export ciphers. The following does the trick:
Fichier httpd.conf
<syntaxhighlight lang="apache">
#  allow all ciphers for the inital handshake,
#  so export browsers can upgrade via SGC facility
SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
<Directory /usr/local/apache/htdocs>
#  but finally deny all browsers which haven't upgraded
SSLRequire %{SSL_CIPHER_USEKEYSIZE} >= 128
</Directory>
</syntaxhighlight>}}
{{Admon/faq|How can I create an SSL server which accepts all types of ciphers in general, but requires a strong ciphers for access to a particular URL?    [L]|Obviously you cannot just use a server-wide SSLCipherSuite which restricts the ciphers to the strong variants. But mod_ssl allows you to reconfigure the cipher suite in per-directory context and automatically forces a renegotiation of the SSL parameters to meet the new configuration. So, the solution is:
Fichier httpd.conf
<syntaxhighlight lang="apache">
#  be liberal in general
SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
<Location /strong/area>
#  but https://hostname/strong/area/ and below requires strong ciphers
SSLCipherSuite HIGH:MEDIUM
</Location>
</syntaxhighlight>}}
=== Client Authentication and Access Control ===
{{Admon/faq|How can I authenticate clients based on certificates when I know all my clients? [L]|When you know your user community (i.e. a closed user group situation), as it's the case for instance in an Intranet, you can use plain certificate authentication. All you have to do is to create client certificates signed by your own CA certificate ca.crt and then verifiy the clients against this certificate.<br>
Fichier httpd.conf
<syntaxhighlight lang="apache">
#  require a client certificate which has to be directly
#  signed by our CA certificate in ca.crt
SSLVerifyClient require
SSLVerifyDepth 1
SSLCACertificateFile conf/ssl.crt/ca.crt
</syntaxhighlight>}}
{{Admon/faq|How can I authenticate my clients for a particular URL based on certificates but still allow arbitrary clients to access the remaining parts of the server? [L]|For this we again use the per-directory reconfiguration feature of mod_ssl:<br>
Fichier httpd.conf
<syntaxhighlight lang="apache">
SSLVerifyClient none
SSLCACertificateFile conf/ssl.crt/ca.crt
<Location /secure/area>
SSLVerifyClient require
SSLVerifyDepth 1
</Location>
</syntaxhighlight>}}
{{Admon/faq|How can I authenticate only particular clients for a some URLs based on certificates but still allow arbitrary clients to access the remaining parts of the server? [L]|The key is to check for various ingredients of the client certficate. Usually this means to check the whole or part of the Distinguished Name (DN) of the Subject. For this two methods exists: The mod_auth based variant and the SSLRequire variant. The first method is good when the clients are of totally different type, i.e. when their DNs have no common fields (usually the organisation, etc.). In this case you've to establish a password database containing all clients. The second method is better when your clients are all part of a common hierarchy which is encoded into the DN. Then you can match them more easily.
'''The first method'''<br>
Fichier httpd.conf<syntaxhighlight lang="apache">
SSLVerifyClient      none
<Directory /usr/local/apache/htdocs/secure/area>
SSLVerifyClient      require
SSLVerifyDepth      5
SSLCACertificateFile conf/ssl.crt/ca.crt
SSLCACertificatePath conf/ssl.crt
SSLOptions          +FakeBasicAuth
SSLRequireSSL
AuthName            "Snake Oil Authentication"
AuthType            Basic
AuthUserFile        /usr/local/apache/conf/httpd.passwd
require              valid-user
</Directory>
</syntaxhighlight>
Fichier httpd.htaccess
<syntaxhighlight lang="apache">
/C=DE/L=Munich/O=Snake Oil, Ltd./OU=Staff/CN=Foo:xxj31ZMTZzkVA
/C=US/L=S.F./O=Snake Oil, Ltd./OU=CA/CN=Bar:xxj31ZMTZzkVA
/C=US/L=L.A./O=Snake Oil, Ltd./OU=Dev/CN=Quux:xxj31ZMTZzkVA
</syntaxhighlight>
'''The second method'''<br>
Fichier httpd.conf<syntaxhighlight lang="apache">
<syntaxhighlight lang="apache">
SSLVerifyClient      none
<Directory "/var/www/html/area">
SSLVerifyClient      require
SSLVerifyDepth      5
SSLCACertificateFile conf/ssl.crt/ca.crt
SSLCACertificatePath conf/ssl.crt
SSLOptions          +FakeBasicAuth
SSLRequireSSL
SSLRequire          %{SSL_CLIENT_S_DN_O}  eq "Snake Oil, Ltd." and \
                    %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"}
</Directory>
</syntaxhighlight>}}
{{Admon/faq|How can I require HTTPS with strong ciphers and either basic authentication or client certificates for access to a subarea on the Intranet website for clients coming from the Internet but still allow plain HTTP access for clients on the Intranet? [L]|Let us assume the Intranet can be distinguished through the IP network 192.160.1.0/24 and the subarea on the Intranet website has the URL /subarea. Then configure the following outside your HTTPS virtual host (so it applies to both HTTPS and HTTP):<br>
Fichier httpd.conf
<syntaxhighlight lang="apache">
SSLCACertificateFile conf/ssl.crt/company-ca.crt
<Directory /usr/local/apache/htdocs>
#  Outside the subarea only Intranet access is granted
Order                deny,allow
Deny                from all
Allow                from 192.168.1.0/24
</Directory>
<Directory /var/www/html/subarea>
#  Inside the subarea any Intranet access is allowed
#  but from the Internet only HTTPS + Strong-Cipher + Password
#  or the alternative HTTPS + Strong-Cipher + Client-Certificate
#  If HTTPS is used, make sure a strong cipher is used.
#  Additionally allow client certs as alternative to basic auth.
SSLVerifyClient      optional
SSLVerifyDepth      1
SSLOptions          +FakeBasicAuth +StrictRequire
SSLRequire          %{SSL_CIPHER_USEKEYSIZE} >= 128
#  Force clients from the Internet to use HTTPS
RewriteEngine        on
RewriteCond          %{REMOTE_ADDR} !^192\.168\.1\.[0-9]+$
RewriteCond          %{HTTPS} !=on
RewriteRule          .* - [F]
#  Allow Network Access and/or Basic Auth
Satisfy              any
#  Network Access Control
Order                deny,allow
Deny                from all
Allow                192.168.1.0/24
#  HTTP Basic Authentication
AuthType            basic
AuthName            "Protected Intranet Area"
AuthUserFile        conf/protected.passwd
Require              valid-user
</Directory>
</syntaxhighlight>}}


== PHP ==
== PHP ==

Dernière version du 13 mai 2014 à 07:51

Sécuriser son serveur Apache

TuxCRS.png

C'est ballot de mettre une serrure aux fenêtres si la porte reste grande ouverte.

C'est pourquoi, avant même de penser à sécuriser Apache, quelques sécurités de base doivent préalablement être mise en place:

  • Firewall: C'est le premier rempart de la sécurité
  • Protection basique contre le flood. Cela peut être fait avec une règle firewall du type iptables -A FORWARD -p tcp --syn -m limit --limit 1/second -j ACCEPT
  • Avoir au moins un service de détection d'intrusion: <package>ossec</package>, <package>snort</package> et/ou autres...
  • Vérifier régulièrement la présence de rootkits avec les outils <package>chkrootkit</package>, <package>rkhunter</package>, etc...
  • Surveiller les logs.
  • Mettre son système à jour régulièrement. En effet si les logiciels ne sont pas à jour ou que les patchs de sécurités ne sont pas appliqués, la sécurisation n'aurait pas de sens et ne serait qu'un arbre qui cache la forêt.

Apache

Cacher le numéro de version et autres informations sensibles

Par défaut, Apache rapporte les informations suivantes:

  • numéro de version d'Apache
  • Liste des modules installés
  • Système d'exploitation et numéro de version de celui-ci

Ajout/modification des directives dans le fichier <path>/etc/httpd/conf/httpd.conf</path>

ServerSignature Off
ServerTokens Prod

La clé ServerSignature provoque l'affichage d'informations sensibles dans les pages d'erreur (403, 404 notamment), ainsi que dans les pages auto-générées listant les fichiers du répertoire.

La clé ServerTokens est utilisée pour déterminer si des informations doivent apparaître dans l'en-tête de réponse. Si la valeur de cette clé est Prod, la seule information sera:

Server: Apache
Note.png
Pour les paranoïaques
Pour qu'Apache rapporte autre chose que apache , il faut soit éditer les sources, soit utilisé le module mod_security

S'assurer qu'apache tourne avec son propre user et group

Beaucoup de serveurs web tourne avec le user nobody ou daemon. Dans le cas où Apache serait compromis, tous les processus utilisant le même user le serait aussi rapidement, et inversement.

User apache
Group apache

S'assurer que les fichiers en dehors du répertoire de travail d'apache ne soient pas servis

Pour cela on bloque la racine du serveur, et on accepte de servir uniquement les fichiers se trouvant le répertoire de travail d'Apache.

<Directory />
  Order Deny,Allow
  Deny from all
  Options None
  AllowOverride None
</Directory>
<Directory /web>
  Order Allow,Deny
  Allow from all
</Directory>
Note.png
Cas des fichiers qui devraient être normalement servis et se trouvant en dehors du répertoire de travail d'Apache
Il faut explicitement déclarer chaque répertoire parent dans la configuration d'Apache et y définir les droits, comme pour le répertoire de travail.

Exemple: Apache hébergant un wiki.

Les fichiers se trouvent dans <path>/var/www/wiki</path> et dans <path>/usr/share/mediawiki/skins</path>.

La déclaration sera donc

Alias /wiki/skins /usr/share/mediawiki/skins
Alias /wiki /var/www/wiki

<Directory "/var/www/wiki">
    Options Includes FollowSymLinks
    AllowOverride None
    Order Allow,Deny
    Allow from all
</Directory>

<Directory "/usr/share/mediawiki/skins">
    Options Includes
    AllowOverride None
    Order Allow,Deny
    Allow from all
</Directory>

Désactiver l'indexation des répertoires

Il faut spécifier dans les options que l'indexation n'est pas autorisée en mettant -Indexes ou None aux Options dans la balise Directory.

Options -Indexes

Désactiver l'inclusion de fichiers

Il faut spécifier dans les options que l'inclusion n'est pas autorisée en mettant -Includes ou None aux Options dans la balise Directory.

Options -Includes

Désactiver l'exécution des scripts CGI

Il faut spécifier dans les options que l'exécution des scripts CGI n'est pas autorisée en mettant -ExecCGI ou None aux Options dans la balise Directory.

Options -ExecCGI
Note.png
Nagios
Le service de supervision Nagios a besoin de pouvoir exécuter des scripts CGI. Il faudra donc ajouter la directive +ExecCGI dans la balise du répertoire de nagios.

Désactiver le suivi des liens symboliques

Il faut spécifier dans les options que le suivi des liens symboliques n'est pas autorisée en mettant -FollowSymLinks ou None aux Options dans la balise Directory.

Options -FollowSymLinks

Désactiver plusieurs options

Il faut spécifier dans les options que rien n'est autorisé en mettant None aux Options dans la balise Directory.

Options None

On peut aussi spécifier les options interdites

Options -ExecCGI -FollowSymLinks -Indexes

Désactiver le support des fichiers .htaccess

Il faut spécifier dans la directive AllowOverride que rien n'est autorisé.

AllowOverride None

Pour les répertoires nécessitant un fichier .htaccess, il convient de modifier le nom et de spécifier le nouveau nom à Apache. De plus ces fichiers doivent être interprétés mais ne doivent pas être téléchargés.

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

Désactiver le debug des connexions HTTP : TRACE et TRACK

Il faut spécifier la directive suivante. Elle est supportée sur tous les Apaches 2.2 et supérieur.

TraceEnable Off


Idea.png
Apache < 2.0.55 ou 1.3.34
Il faut activer le module rewrite et ajouter les lignes suivantes au fichier <path>/etc/httpd/conf/httpd.conf</path>
RewriteEngine On 
RewriteCond %{REQUEST_METHOD} ^TRACE 
RewriteRule .* - [F]

Activer le module mod_security

mod_security est un module Apache écrit par Ivan Ristic, l'auteur du livre Apache Security des éditions O'Reilly.

mod_security peut:

  • Filtrage simple
  • Filtre basé sur des expressions régulières
  • Validation de l'encodage d'URL
  • Validation de l'encodage Unicode
  • Audit
  • Prévention des attaques Null byte
  • Respect d'un quota pour la mémoire
  • Masquage de l'identité du serveur Web
  • Support du chroot
  • Et bien d'autres choses encore...

Désactivation des modules non-utilisés

Apache est fournit avec un nombre conséquent de modules. Après analyse de la documentation de chaque module, il faut déterminer si le module est nécessaire pour l'installation.

On peut désactiver le chargement des modules non-utilisés en commentant la ligne commençant par LoadModule pour le module en question (Ajout d'un # en début de ligne).

Pour lister les modules d'Apache

grep LoadModule httpd.conf

Les modules suivants sont généralement activés par défaut mais ne sont utiles que dans des cas bien précis:

  • mod_imap
  • mod_include
  • mod_info
  • mod_userdir
  • mod_status
  • mod_cgi
  • mod_autoindex
Main module summary
Module's name Description
core The core Apache features, required in every Apache installation.
http_core The core http support, required in every Apache 2.0 installation.
prefork Multi-Processing Module (MPM) that implements a non-threaded, pre-forking web server. Can be replaced by other multiprocessing module, e.g. worker , threadpool etc. The MPM module is required in every Apache 2.0 installation.
mod_access Provides access control based on client hostname, IP address, or other characteristics of the client request. Because this module is needed to use "order", "allow" and "deny" directives, it should remain enabled.
mod_auth Required in order to implement user authentication using text files (HTTP Basic Authentication), which was specified in functionality assumptions.
mod_dir Required to search and serve directory index files: "index.html", "default.htm", etc.
mod_log_config Required to implement logging of the requests made to the server.
mod_mime Required to set the character set, content- encoding, handler, content-language, and MIME types of documents.

S'assurer que seul root puisse accéder à la configuration d'Apache

chown -R root:root /etc/httpd
chmod -R o-rwx /etc/httpd

Baisser la valeur du timeout

Par défaut, le timeout est fixé à 300 secondes. On peut baisser cette valeur afin de limiter les effets des attaques par déni de service.

Timeout 45

Limiter la taille des requêtes

Apache possède quelques directives pour limiter la taille des requêtes, Cela peut aussi être utile pour limiter les attaques par déni de service.

On limite tout d'abord la taille des requêtes avec la directive LimitRequestBody. La valeur par défaut est Illimité. Si la taille maximum des fichiers uploadés est plus petit que 1MB, on peut fixer la valeur à 1048576.

LimitRequestBody 1048576

Cette valeur peut encore être plus faible si l'upload n'est pas autorisé.

Quelques autres directives comme LimitRequestFields, LimitRequestFieldSize et LimitRequestLine sont déjà mise à des valeurs raisonnables pour la plupart des serveurs mais rien n'empêche de faire un ajustage plus fin.

Limiter la taille des requêtes XML

Si le module mod_dav est activé ( pour subversion notamment ), on peut limiter la taille des requêtes XML avec la directive LimitXMLRequestBody. Cette directive est uniquement disponible depuis apache 2 et est fixée par défaut à approximativement 1 million bytes (un peu plus qu'1Mo). Cette valeur est souvent mise à 0 pour ne pas limiter la taille des fichiers uploadés avec WebDAV, mais pour un simple dépôt de fichier source, on peut le fixer à approximativement 10Mo.

LimitXMLRequestBody 10485760

Limiter les accès concurrents

Apache has several configuration settings that can be used to adjust handling of concurrent requests.

La directive MaxClients est le nombre maximum de processus enfant créés pour satisfaire les requêtes. Il ne doit pas être trop élevé si le serveur n'a pas assez de mémoire pour gérer l'accès à de nombreux fichiers simultanément.

Les autres directives telles que MaxSpareServers, MaxRequestsPerChild, ThreadsPerChild, ServerLimit, et MaxSpareThreads doivent être ajustées en fonction du système d'exploitation et des paramètres du serveur physique ( RAM, CPU, etc...).

Restriction d'accès par adresse IP

Si certaines ressources ne doivent être servies que pour certaines adresses ou plages d'adresses IP, il convient de restreindre l'accès de celle-ci dans la configuration d'Apache. Restriction à la plage d'adresse 192.168.0.0/24.

Order Deny,Allow
Deny from all
Allow from 192.168.0.0/24

Restriction sur une adresse IP.

Order Deny,Allow
Deny from all
Allow from 127.0.0.1

Ajustage des connexions persistantes

D'après la documentation d'Apache, les connexions persistantes augmentent les performances de 50%, donc ces paramètres doivent être modifiés avec précaution.

Les connexions persistantes sont activés par défaut et doivent le rester. Toutefois un ajustage du nombre de connections persistantes, ainsi que du timeout peut être entrepris après une analyse très poussée des journaux d'Apache afin de déterminer les meilleures valeurs. par défaut le nombre de connections persistantes est fixé à 100 et le timeout à 15.

Méthode d'authentification

Il préférable d'utiliser la méthode Digest en lieu et place de la méthode Basic, surtout si le protocole est http. En effet le login et le mot de passe passe en clair sur le réseau avec la méthode Basic.

Méthodes d'authentification avec Apache

Exécuter Apache dans un environnement Chroot

Un Chroot permet d'exécuter un programme dans une prison isolée. Cela permet de limiter l'intrusion à ce seul service.

Ce n'est pas vraiment facile d'exécuter Apache dans un chroot, notamment à cause des dépendances des librairies. Toutefois le module mod_security le permet très facilement en ajoutant la directive suivante à la configuration d'Apache.

SecChrootDir /chroot/apache

PHP

Cacher le numéro de version

PHP expose son numéro de version ( par défaut ? ). En effet il suffit de lancer la commande suivante pour s'en rendre compte. Bien entendu le fichier index.php doit exister, sinon Apache rapporte une erreur 404.

nc localhost 80 << EOF
HEAD http://localhost/index.php http/1.1
host: localhost

EOF

Apache répond en spécifiant le numéro de version de php

HTTP/1.1 200 OK
Date: Thu, 06 Sep 2012 10:03:22 GMT
Server: Apache
X-Powered-By: PHP/5.4.6
Connection: close
Content-Type: text/html; charset=UTF-8


Ajout de la ligne suivante au fichier <path>/etc/php.ini</path>

expose_php = Off

Après la modification et un restart d'Apache plus tard

nc localhost 80 << EOF
HEAD http://localhost/index.php http/1.1
host: localhost

EOF

Cette fois le numéro de version de php est caché

HTTP/1.1 200 OK
Date: Thu, 06 Sep 2012 10:03:22 GMT
Server: Apache
Connection: close
Content-Type: text/html; charset=UTF-8