<divclass="col-main cell cell--auto"><!-- start custom main top snippet --><divid="results-container"class="search-result js-search-result"></div><!-- end custom main top snippet -->
</details><h1id="comment-accueillir-plusieurs-sites-web-en-toute-sécurité-avec-nginx-et-php-fpm">Comment accueillir plusieurs sites Web en toute sécurité avec Nginx Et Php-fpm</h1>
<p>Article original : <ahref="https://www.digitalocean.com/community/tutorials/how-to-host-multiple-websites-securely-with-nginx-and-php-fpm-on-ubuntu-14-04">How To Host Multiple Websites Securely With Nginx And Php-fpm On Ubuntu 14.04</a></p>
<h2id="introduction">introduction</h2>
<p>Il est bien connu que la pile LEMP (Linux, nginx, MySQL, PHP) offre une vitesse et une fiabilité inégalées pour l’exécution des sites PHP. Autres avantages tels que la sécurité et l’isolement sont moins populaires, cependant.</p>
<p>Dans cet article, nous allons vous montrer les avantages de la sécurité et de l’isolement de sites sur LEMP avec différents utilisateurs de Linux en cours d’exécution. Cela se fera par la création de différents pools de php-fpm pour chaque bloc de serveur nginx (site ou hôte virtuel).</p>
<p><em>Ce guide a été testé sur Ubuntu 14.04. L’installation et la configuration décrite seraient similaires sur d’autres versions du système d’exploitation ou OS, mais les commandes et l’emplacement des fichiers de configuration peuvent varier.</em></p>
</blockquote>
<p>Il suppose également que vous avez déjà nginx et php-fpm mis en place. Si non, s’il vous plaît suivre la première étape et la troisième étape de l’article <ahref="https://www.digitalocean.com/community/tutorials/how-to-install-linux-nginx-mysql-php-lemp-stack-on-ubuntu-14-04">Comment faire pour installer Linux, nginx, MySQL, PHP (LEMP) pile sur Ubuntu 14.04</a>.</p>
<p>Toutes les commandes de ce tutoriel doit être exécuté en tant qu’utilisateur non root.<br/>
Si l’accès root est nécessaire pour la commande, il sera précédé par sudo.<br/>
Si vous ne possédez pas sz serveur mis en place, suivez ce tutoriel: <ahref="https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-14-04">Configuration initiale du serveur avec Ubuntu 14.04</a>.</p>
<p>Vous aurez également besoin d’un nom de domaine complet (fqdn) qui pointe vers le Droplet pour les tests en plus de la localhost par défaut. Si vous ne l’avez pas à portée de main, vous pouvez utiliser <codeclass="language-plaintext highlighter-rouge">site1.example.org</code>.<br/>
Modifier le fichier <codeclass="language-plaintext highlighter-rouge">/etc/hosts</code> avec votre éditeur préféré comme ceci <codeclass="language-plaintext highlighter-rouge">sudo nano /etc/hosts</code> et ajoutez cette ligne (remplacez site1.example.org avec votre fqdn si vous l’utilisez):
/ etc / hosts</p>
<p>…
127.0.0.1 site1.example.org
…</p>
<h2id="raisons-pour-plus-sécuriser-lemp">Raisons pour plus sécuriser LEMP</h2>
<p>Dans le cadre d’une configuration commune LEMP il n’y a qu’un seul **php-fpm pool ** qui exécute tous les scripts PHP pour tous les sites sous le même utilisateur. Cela pose deux problèmes majeurs:</p>
<ul>
<li>Si une application sur le bloc de serveur d’nginx, à savoir sous-domaine ou site distinct web, est compromis, tous les sites sur ce Droplet seront touchés aussi. L’attaquant est capable de lire les fichiers de configuration, y compris les détails de base de données, des autres sites ou même modifier leurs fichiers.</li>
<li>Si vous voulez donner un accès utilisateur à un site sur votre Droplet, vous lui donnaerez accès à tous les sites. Par exemple, votre développeur a besoin de travailler sur l’environnement de la mise en scène. Cependant, même avec les permissions de fichiers très strictes, vous serez toujours obligé de lui donner accès à tous les sites, y compris votre site principal, sur le même Droplet.</li>
</ul>
<p>Les problèmes ci-dessus sont résolus en php-fpm en créant un pool différent qui fonctionne sous un utilisateur différent pour chaque site.</p>
<h3id="étape-1---configuration-de-php-fpm">Étape 1 - Configuration de php-fpm</h3>
<p>Si vous avez couvert les conditions préalables, alors vous devriez déjà avoir un site web fonctionnel sur le Droplet. Sauf si vous avez spécifié un fqdn pour cela, vous devriez être en mesure d’y accéder sous localhost ou par l’adresse IP.</p>
<p>Maintenant nous allons créer un deuxième site (site1.example.org) avec son propre php-fpm pool et l’utilisateur Linux.</p>
<p>Commençons par la création de l’utilisateur nécessaire. Pour une meilleure isolation, le nouvel utilisateur doit avoir son propre groupe. Donc, d’abord créer le groupe d’utilisateurs site1 :<br/>
<p>Le nouvel utilisateur site1 n’a pas de mot de passe et ne peut pas ouvrir une session dans le Droplet. Si vous avez besoin de fournir une personne avec un accès direct aux fichiers de ce site, vous devez créer un mot de passe pour cet utilisateur avec la commande <codeclass="language-plaintext highlighter-rouge">sudo passwd site1</code>. Avec la nouvelle combinaison <strong>utilisateur/mot de passe</strong> ,un utilisateur peut se connecter à distance par ssh ou sftp. Pour plus d’information et de sécurité ,vérifier la configuration de l’article <ahref="https://www.digitalocean.com/community/questions/setup-a-secondary-ssh-sftp-user-with-limited-directory-access">Setup a secondary SSH/SFTP user with limited directory access.</a><br/>
Ensuite, créez un nouveau pool php-fpm pour site1.<br/>
Un pool de php-fpm dans son essence même est juste un processus Linux ordinaire, qui fonctionne sous certains utilisateur/groupe et écoute sur un socket Linux. Il pourrait également écouter sur une adresse IP: combinaison de port aussi, mais cela nécessiterait plus de ressources , et ce n’est pas la méthode préférée.</p>
<p>Par défaut, dans Ubuntu 14.04 chaque pool de php-fpm doit être configuré dans un fichier situé dans le répertoire <codeclass="language-plaintext highlighter-rouge">/etc/php5/fpm/pool.d</code>. Dans ce répertoire ,chaque fichier avec les extensions .conf est automatiquement chargé dans la configuration globale php-fpm.</p>
<p>Donc, pour notre nouveau site, nous allons créer un nouveau fichier <codeclass="language-plaintext highlighter-rouge">/etc/php5/fpm/pool.d/site1.conf</code> . Vous pouvez le faire avec votre éditeur préféré comme ceci:<br/>
<p>Dans la configuration ci-dessus noter ces options spécifiques:</p>
<ul>
<li>[Site1] est le nom du pool. Pour chaque pool, vous devez spécifier un nom unique.</li>
<li>user et group utilisés pour le nouveau pool qui sera exécuté</li>
<li>listen devra pointer vers un emplacement unique pour chaque pool.</li>
<li>listen.owner et listen.group définissent la propriété de l’auditeur, à savoir le socket du nouveau pool de php-fpm. Nginx doit être capable de lire ce socket. Voilà pourquoi le socket est créé avec l’utilisateur et groupe sous lequel nginx fonctionne - www-data.
* php_admin_value vous permet de définir les valeurs de configuration personnalisée PHP. Nous l’avons utilisé pour désactiver les fonctions qui peuvent exécuter des commandes Linux - exec, passthru, shell_exec, système.
* php_admin_flag est similaire à php_admin_value, mais il est juste un commutateur pour les valeurs booléennes, à savoir sur et en dehors. Nous allons désactiver la fonction PHP allow_url_fopen qui permet à un script PHP d’ouvrir des fichiers à distance et pourrait être utilisé par l’attaquant.</li>
</ul>
<blockquote>
<p><em>Remarque: Les valeurs de php_admin_value et php_admin_flag ci-dessus pourraient également être appliquées à l’échelle mondiale. Cependant, un site peut avoir besoin, et voilà pourquoi par défaut, ils ne sont pas configurés. La beauté des pools de php-fpm est qu’il vous permet d’affiner les paramètres de sécurité de chaque site. De plus, ces options peuvent être utilisées pour tous les autres paramètres de php, en dehors du périmètre de sécurité, afin de personnaliser l’environnement d’un site.</em></p>
</blockquote>
<p>Les options <strong>pm</strong> sont en dehors du thème de la sécurité en cours, mais vous devez savoir qu’ils vous permettent de configurer les performances du pool.</p>
<p>L’option <strong>chdir</strong> devrait être <strong>/</strong> qui est la racine du système de fichiers. Cela ne devrait pas être modifié sauf si vous utilisez une autre option importante de <strong>chroot</strong>.</p>
<p>L’option <strong>chroot</strong> n’est pas incluse dans la configuration ci-dessus à dessein. Elle permettrait d’exécuter un pool dans un environnement emprisonné (jailed environment), à savoir enfermé dans un répertoire. Il est parfait pour la sécurité parce que vous pouvez verrouiller le pool à l’intérieur de la racine web du site. Cependant, cette sécurité ultime causera de graves problèmes pour toute application PHP qui se fonde sur les binaires du système et des applications telles que Imagemagick ne seront pas disponibles. Si vous êtes plus intéressés par ce sujet s’il vous plaît lire l’article <ahref="https://www.digitalocean.com/community/tutorials/how-to-use-firejail-to-set-up-a-wordpress-installation-in-a-jailed-environment">How To Use Firejail to Set Up a WordPress Installation in a Jailed Environment</a>.</p>
<p>Une fois que vous avez terminé avec la configuration ,redémarrer php-fpm pour que les nouveaux paramètres entrent en vigueur:<br/>
<codeclass="language-plaintext highlighter-rouge">sudo service php5-fpm restart</code><br/>
Vérifiez que le nouveau pool est bien en cours d’exécution par la recherche de ses processus:<br/>
<codeclass="language-plaintext highlighter-rouge">ps aux | grep site1</code><br/>
Si vous avez suivi les instructions , vous devriez voir une sortie similaire à:</p>
<divclass="language-plaintext highlighter-rouge"><divclass="highlight"><preclass="highlight"><code>site1 14042 0.0 0.8 133620 4208 ? S 14:45 0:00 php-fpm: pool site1
site1 14043 0.0 1.1 133760 5892 ? S 14:45 0:00 php-fpm: pool site1
</code></pre></div></div>
<p>En début de ligne l’utilisateur sous lequel le processus ou le pool de php-fpm fonctionne - site1.</p>
<p>En outre, nous désactivons la mise en cache de php par défaut fourni par opcache. Cette extension de la mise en cache particulière pourrait être grande pour la performance, mais pas pour la sécurité comme nous le verrons plus tard. <br/>
Pour le désactiver modifier le fichier <codeclass="language-plaintext highlighter-rouge">/etc/php5/fpm/conf.d/05-opcache.ini</code> avec les privilèges de super-utilisateur et ajoutez la ligne:<br/>
<codeclass="language-plaintext highlighter-rouge">sudo service php5-fpm restart</code></p>
<h3id="étape-2---configuration-de-nginx">Étape 2 - Configuration de nginx</h3>
<p>Une fois que nous avons configuré le pool de php-fpm pour notre site, nous allons configurer le bloc de serveur nginx. Créer un nouveau fichier <codeclass="language-plaintext highlighter-rouge">/etc/nginx/sites-available/site1</code> avec votre éditeur préféré comme ceci:<br/>
<codeclass="language-plaintext highlighter-rouge">sudo vim /etc/nginx/sites-available/site1</code><br/>
<p>Le code ci-dessus montre une configuration commune pour un bloc de serveur nginx. Notez les pièces intéressantes mises en évidence:</p>
<ul>
<li>Web racine est /usr/share/nginx/sites/site1.</li>
<li>Le nom du serveur utilise le site1.example.org fqdn qui est celui mentionné dans les conditions du présent article.</li>
<li>fastcgi_pass spécifie le gestionnaire pour les fichiers php. Pour chaque site, vous devez utiliser un socket unix différent tel que /var/run/php5-fpm-site1.sock.</li>
<p>Pour activer le site ci-dessus, vous devez créer un lien symbolique vers le dans le répertoire /etc/nginx/sites-enabled/. Cela peut être fait avec la commande:<br/>
Enfin, redémarrez nginx pour la modification prenne effet comme ceci:<br/>
<codeclass="language-plaintext highlighter-rouge">sudo service nginx restart</code></p>
<h3id="étape-3---essais">Étape 3 - Essais</h3>
<p>Pour l’exécution des tests, nous allons utiliser la fonction <strong>phpinfo</strong> bien connue qui fournit des informations détaillées sur l’environnement php. Créer un nouveau fichier sous le nom <codeclass="language-plaintext highlighter-rouge">info.php</code> qui ne contient que la ligne <strong><?php phpinfo(); ?></strong>. Créer ce fichier à la racine <strong>/usr/share/nginx/html/</strong>. A cet effet, vous pouvez utiliser un éditeur comme ceci:<br/>
Maintenant, vous êtes prêt à exécuter le test le plus élémentaire pour vérifier l’utilisateur du serveur. Vous pouvez effectuer le test avec un navigateur ou un terminal et <strong>lynx</strong>, le navigateur de ligne de commande. Si vous ne disposez pas de lynx sur votre Droplet encore, installez-le avec la commande:<br/>
<p>Dans la commande ci-dessus nous filtrons la sortie avec grep seulement pour la variable <strong>SERVER[“USER”]</strong> qui représente l’utilisateur du serveur. Pour le site par défaut la sortie doit montrer l’utilisateur par défaut www-data comme ceci:<br/>
Si vous avez effectué des réglages PHP personnalisé sur une base par pool de php-fpm, alors vous pouvez également vérifier les valeurs correspondantes de la manière ci-dessus en filtrant la sortie qui vous intéresse.</p>
<p>Jusqu’à présent, nous savons que nos deux sites fonctionnent sous différents utilisateurs, mais maintenant nous allons voir comment sécuriser une connexion. Pour illustrer le problème de la sécurité que nous résolvons dans cet article, nous allons créer un fichier avec des informations sensibles. Habituellement, un tel fichier contient la chaîne de connexion à la base de données inclus utilisateur et mot de passe. Si quelqu’un découvre l’information, on imagine la suite!!!.</p>
<p>Avec votre éditeur préféré créer un nouveau fichier dans votre site principal <strong>/usr/share/nginx/html/config.php</strong>.<br/>
<p>Dans le fichier ci-dessus, nous définissons une variable appelée <strong>pass</strong> qui cpntient la valeur <strong>secret</strong>. Naturellement, nous voulons restreindre l’accès à ce fichier, donc nous allons définir ses autorisations à 400, qui donnent accès en lecture seule au propriétaire du fichier.</p>
<p>Pour modifier les autorisations à 400 exécutez la commande:<br/>
<p>En outre, notre site principal fonctionne sous l’utilisateur <strong>www-data</strong> qui doit être en mesure de lire ce fichier. Ainsi, changer la propriété du fichier à cet utilisateur comme ceci:
<p>Dans notre exemple, nous allons utiliser un autre fichier appelé <strong>/usr/share/nginx/html/readfile.php</strong> pour lire l’information secrète et l’afficher. Ce fichier doit contenir le code suivant:<br/>
<p>Pour confirmer toutes les autorisations et les propriétaires sont corrects dans la racine web exécutez la commande <codeclass="language-plaintext highlighter-rouge">ls -l /usr/share/nginx/html/</code>. Vous devriez voir une sortie similaire à:</p>
<divclass="language-shell highlighter-rouge"><divclass="highlight"><preclass="highlight"><code><spanclass="nt">-r--------</span> 1 www-data www-data 27 Jun 19 05:35 config.php
<spanclass="nt">-rw-r--r--</span> 1 www-data www-data 68 Jun 21 16:31 readfile.php
</code></pre></div></div>
<p>Maintenant accéder au dernier fichier sur votre site par défaut avec la commande :<br/>
Vous devriez être en mesure de voir s’afficher <strong>secret</strong> en sortie qui indique que le fichier avec des informations sensibles est accessible dans le même site, ce qui est le comportement correct attendu.</p>
<p>Maintenant, copiez le fichier <strong>/usr/share/nginx/html/readfile.php</strong> sur votre second site, <strong>site1.example.org</strong> comme ceci:<br/>
<p>Pour maintenir les relations site/utilisateur, assurez-vous que dans chaque site, les fichiers appartiennent à l’utilisateur du site respectif. Pour ce faire, changer groupe et utilisateur du fichier nouvellement copié :<br/>
<p>Pour confirmer que vous avez défini les autorisations et la propriété du fichier correct, s’il vous plaît lister le contenu du web racine site1 avec la commande:<br/>
Vous ne verrez que l’espace vide retourné. De plus, si vous recherchez des erreurs dans le journal des erreurs de nginx avec la commande <codeclass="language-plaintext highlighter-rouge">sudo grep error /var/log/nginx/error.log</code> vous verrez:</p>
<divclass="language-plaintext highlighter-rouge"><divclass="highlight"><preclass="highlight"><code>2015/06/30 15:15:13 [error] 894#0: *242 FastCGI sent in stderr: "PHP message: PHP Warning: include(/usr/share/nginx/html/config.php): failed to open stream: Permission denied in /usr/share/nginx/sites/site1/readfile.php on line 2
</code></pre></div></div>
<blockquote>
<p>Remarque: Vous verriez aussi une erreur semblable dans la sortie de lynx si vous avez <strong>display_errors</strong> set to <strong>On</strong> dans la configuration <strong>/etc/php5/fpm/php.ini</strong></p>
</blockquote>
<p>L’avertissement indique qu’un script à partir du site <strong>site1.example.org</strong> ne peut pas lire le fichier <strong>config.php</strong> sensible à partir du site principal. Ainsi, les sites fonctionnant sous différents utilisateurs ne peuvent pas compromettre la sécurité de l’autre.</p>
<p>Nous avons désactivé la mise en cache par défaut fourni par <strong>opcache</strong>. Si vous êtes curieux de savoir pourquoi, essayez d’activer à nouveau opcache en définissant avec les privilèges de super-utilisateur opcache.enable = 1 dans le fichier php5-fpm /etc/php5/fpm/conf.d/05-opcache.ini et redémarrer avec la commande sudo Service php5-fpm redémarrage.</p>
<p>Étonnamment, si vous exécutez à nouveau les étapes de test dans exactement le même ordre, vous serez en mesure de lire le fichier sensible indépendamment de sa propriété et de l’autorisation. Ce problème dans <strong>opcache</strong> a été rapporté depuis longtemps, mais le temps de cet article, il n’a pas encore été résolu.</p>
<h2id="conclusion">Conclusion</h2>
<p>D’un point de vue de la sécurité, il est essentiel d’utiliser des pools de php-fpm avec un utilisateur différent pour chaque site sur le même serveur web Nginx. Même s’il est livré avec une petite pénalité de performance, le bénéfice d’un tel isolement pourrait prévenir les violations graves de sécurité.</p>
<p>L’idée décrite dans cet article est unique, et il est présent dans d’autres technologies d’isolement de PHP similaires tels que SuPHP. Cependant, la performance de toutes les autres solutions de rechange est bien pire que celle de php-fpm.</p>
<divclass="article__section-navigator clearfix"><divclass="previous"><span>PRÉCÉDENT</span><ahref="/2019/12/25/Commandes-Linux.html">Commandes-Linux</a></div><divclass="next"><span>SUIVANT</span><ahref="/2019/12/25/Comment_cr%C3%A9er_un_live-USB_contenant_FreeDOS.html">Flash BIOS avec un live-USB FreeDOS</a></div></div></div>
</div>
<script>(function(){
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
$(function() {
var $this ,$scroll;
var $articleContent = $('.js-article-content');
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
var scroll = hasSidebar ? '.js-page-main' : 'html, body';