Skip to content

AppArmor and PHP-FPM

Creating the main PHP-FPM profile

First we create the php-fpm.d directory and an empty local file:

sudo -s
nano /etc/apparmor.d/php-fpm7.4
touch /etc/apparmor.d/local/php-fpm7.4

Create a new file and enter the following:

profile php-fpm7.4 /usr/sbin/php-fpm7.4 flags=(attach_disconnected, complain) {
  #include <abstractions/base>
  #include <abstractions/nameservice>
  #include <abstractions/openssl>
  #include <abstractions/php>
  #include <abstractions/ssl_certs>
  #include <local/php-fpm7.4>
  #include <php-fpm.d>

  capability chown,
  capability dac_override,
  capability kill,
  capability net_admin,
  capability setgid,
  capability setuid,

  signal send peer=php-fpm7.4//*,

  deny / rw,

  /etc/php{,5,7}/** r,
  /usr/sbin/php-fpm* rix,
  /var/log/php*-fpm.log rw,
  @{PROC}/@{pid}/attr/{apparmor/,}current rw,
  @{run}/php{,-fpm}/php*-fpm-*.sock w,
  @{run}/php{,-fpm}/php* rw,
  @{run}/php{,-fpm}/php*-fpm.sock rwlk,
  owner /etc/ImageMagick-6/log.xml r,
  owner /etc/ImageMagick-6/policy.xml r,
  owner /run/systemd/notify w,

  change_profile -> php-fpm7.4//*,


Using Changehat to protect a PHP-FMP pool

Changehat can be used to create specific rules for each pool. Here we create a changehat profile specifically for PHPMyAdmin:

mkdir /etc/apparmor.d/php-fpm.d
nano /etc/apparmor.d/php-fpm.d/phpmyadmin
  ^phpmyadmin flags=(complain) {
    #include <abstractions/base>
    #include <abstractions/dovecot-common>
    #include <abstractions/nameservice>
    #include <abstractions/openssl>
    #include <abstractions/php>
    #include <abstractions/ssl_certs>
    #include <abstractions/mysql>

    signal (receive) peer=php-fpm7.4,

    deny /var/www/** r,
    deny /usr/share/postfixadmin/** r,

    @{run}/php/php7.4-fpm-www-phpmyadmin.sock rwlk,
    /usr/share/icu/*/*.dat r,
    owner /etc/ImageMagick-6/log.xml r,
    owner /etc/ImageMagick-6/policy.xml r,
    owner /usr/share/phpmyadmin/* r,
    owner /usr/share/phpmyadmin/ rwlk,
    owner /usr/share/phpmyadmin/js/* r,
    owner /usr/share/phpmyadmin/libraries/** r,
    owner /usr/share/phpmyadmin/templates/** r,
    owner /usr/share/phpmyadmin/themes/ r,
    owner /usr/share/phpmyadmin/themes/** r,
    owner /usr/share/phpmyadmin/tmp/ r,
    owner /usr/share/phpmyadmin/tmp/** rwlk,
    owner /usr/share/phpmyadmin/vendor/** r,

Reload apparmor

service apparmor reload

Add the changehat to the pool config:

nano /etc/php/7.4/fpm/pool.d/www-phpmyadmin.conf

Add the changehat line beneath the listen section as below:

listen.owner = www-data = www-data
listen.mode = 0660

apparmor_hat = phpmyadmin

Restart the service:

sudo service php7.4-fpm restart

Use PHPMyAdmin and monitor for issues with:

tail -f /var/log/syslog | grep 'apparmor' --line-buffered

Run aa-logprof to update the profiles.

Once you are happy, enforce the profile with:

aa-enforce php-fpm7.4