LAMP: Utiliser un utilisateur spécifique pour un vhost
Description
Il peut être utile dans de nombreux cas d'utiliser un utilisateur particulier pour faire tourner un VirtualHost Apache.
J'entends par là qu'aussi bien Apache que PHP-FPM utilisent cet utilisateur dans le cadre de ce vhost.
Et pour ce faire il va falloir un peu de travail, il faut changer le mode de fonctionnement d'Apache afin qu'il puisse utiliser les paramètres nécessaires.
L'environnement sera composé comme suit:
- Utilisateur: myweb
- Home de l'utilisateur dans
/srv/web/myweb
- Site internet dans
/srv/web/myweb/www
- Dossiers nécessaires à PHP dans
/srv/web/myweb/php
Les configurations de PHP-FPM et Apache dépendent de votre système, par défaut sous Fedora elles sont respectivement dans /etc/php-fpm.d/
et /etc/httpd/conf.d/
Configuration d'Apache
Pour Apache, on va devoir passer son mode de fonctionnement en MPM prefork et ajouter le module ITK.
Sous Fedora on installera ce module avec la commande suivante:
[root@linux] # | dnf -y install httpd-itk | dblclick to copy |
Une fois le module installé, il ne reste qu'à l'activer.
On va d'abord modifier le mode de fonctionnement d'Apache en éditant le fichier /etc/httpd/conf.modules.d/00-mpm.conf
afin de commenter le mode actuel et dé-commenter le mode prefork.
Après modification votre fichier devrait ressembler à ça:
# Select the MPM module which should be used by uncommenting exactly
# one of the following LoadModule lines. See the httpd.conf(5) man
# page for more information on changing the MPM.
# prefork MPM: Implements a non-threaded, pre-forking web server
# See: http://httpd.apache.org/docs/2.4/mod/prefork.html
#
# NOTE: If enabling prefork, the httpd_graceful_shutdown SELinux
# boolean should be enabled, to allow graceful stop/shutdown.
#
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
# worker MPM: Multi-Processing Module implementing a hybrid
# multi-threaded multi-process web server
# See: http://httpd.apache.org/docs/2.4/mod/worker.html
#
#LoadModule mpm_worker_module modules/mod_mpm_worker.so
# event MPM: A variant of the worker MPM with the goal of consuming
# threads only for connections with active processing
# See: http://httpd.apache.org/docs/2.4/mod/event.html
#
#LoadModule mpm_event_module modules/mod_mpm_event.so
On peut ensuite activer le module ITK, il suffit de dé-commenter la ligne LoadModule du fichier /etc/httpd/conf.modules.d/00-mpm-itk.conf
# ITK MPM (Multi-Processing Module). Mpm-itk allows you to run each of your
# vhost under a separate uid and gid - in short, the scripts and configuration
# files for one vhost no longer have to be readable for all the other vhosts.
LoadModule mpm_itk_module modules/mod_mpm_itk.so
On en a finit avec la configuration générale d'Apache, il ne restera que la configuration du vhost que nous verrons un peu plus tard.
Création de l'utilisateur
Notre utilisateur aura une configuration permettant de réduire la surface d'attaque:
- Il ne pourra pas se connecter avec un shell
- Son HomeDirectory sera le parent direct du dossier contenant le site afin de pouvoir établir un chroot si on le souhaite
- On lui donne le groupe nobody qui n'a pas le moindre droits (normalement)
[root@linux] # | useradd -g nobody -s /sbin/nologin -M -d /srv/web/myweb myweb | dblclick to copy |
Configuration de PHP-FPM
Pour PHP-FPM, nous allons devoir créer un ensemble de répertoires dédiés comme l'utilisateur qui exécutera les scripts PHP n'est pas celui par défaut; il n'a donc pas les droits pour écrire dans les répertoires standards.
Création des répertoires
Les dossiers créés par la première commande sont ceux qui composent l'environnement nécessaire de PHP.
La seconde commande crée le répertoire du site web
[root@linux] # | mkdir -p /srv/web/myweb/php/{logs,wsdlcache,opcache,session,tmp} | dblclick to copy |
[root@linux] # | mkdir -p /srv/web/myweb/www |
Ne pas oublier de modifier les droits pour que notre utilisateur puisse exploiter ces répertoires.
On passera aussi en 700 la racine afin que seul notre utilisateur n'accède à ce répertoire.
[root@linux] # | chown -R myweb /srv/web/myweb | dblclick to copy |
[root@linux] # | chmod 700 /srv/web/myweb |
Fichier de configuration du pool
Fichier de configuration de php-fpm |
---|
; Start a new pool named 'myweb'.
; the variable $pool can we used in any directive and will be replaced by the
; pool name ('myweb' here)
[myweb]
; Per pool prefix
; It only applies on the following directives:
; - 'access.log'
; - 'slowlog'
; - 'listen' (unixsocket)
; - 'chroot'
; - 'chdir'
; - 'php_values'
; - 'php_admin_values'
; When not set, the global prefix (or @php_fpm_prefix@) applies instead.
; Note: This directive can also be relative to the global prefix.
; Default Value: none
prefix = /srv/web/$pool
; Unix user/group of processes
user = myweb
group = nobody
; The address on which to accept FastCGI requests.
; Note: This value is mandatory.
listen = $pool.sock
; Set listen(2) backlog.
; Default Value: 511
;listen.backlog = 511
; When POSIX Access Control Lists are supported you can set them using
; these options, value is a comma separated list of user/group names.
; When set, listen.owner and listen.group are ignored
listen.acl_users = myweb
listen.acl_groups =
; Specify the nice(2) priority to apply to the pool processes (only if set)
; The value can vary from -19 (highest priority) to 20 (lower priority)
; Note: - It will only work if the FPM master process is launched as root
; - The pool processes will inherit the master process priority
; unless it specified otherwise
; Default Value: no set
; process.priority = -19
; Choose how the process manager will control the number of child processes.
pm = dynamic
; The number of child processes to be created when pm is set to 'static' and the
; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'.
; This value sets the limit on the number of simultaneous requests that will be
; served. Equivalent to the ApacheMaxClients directive with mpm_prefork.
; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP
; CGI. The below defaults are based on a server without much resources. Don't
; forget to tweak pm.* to fit your needs.
pm.max_children = 40
; The number of child processes created on startup.
pm.start_servers = 1
; The desired minimum number of idle server processes.
pm.min_spare_servers = 1
; The desired maximum number of idle server processes.
pm.max_spare_servers = 2
; The number of requests each child process should execute before respawning.
pm.max_requests = 500
; The access log file
; Default: not set
;access.log = logs/$pool.access.log
;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
; Note: path INI options can be relative and will be expanded with the prefix
; (pool, global or @prefix@)
; Default Value: nothing is defined by default except the values in php.ini and
; specified at startup with the -d argument
;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com
;php_flag[display_errors] = off
php_admin_value[error_log] = /srv/web/myweb/logs/php-error.log
php_admin_flag[log_errors] = On
;php_admin_value[memory_limit] = 128M
; Set the following data paths to directories owned by the FPM process user.
;
; Do not change the ownership of existing system directories, if the process
; user does not have write permission, create dedicated directories for this
; purpose.
;
; See warning about choosing the location of these directories on your system
; at http://php.net/session.save-path
php_value[session.save_handler] = files
php_value[session.save_path] = /srv/web/myweb/session
php_value[soap.wsdl_cache_dir] = /srv/web/myweb/wsdlcache
php_value[opcache.file_cache] = /srv/web/myweb/opcache
php_admin_value[open_basedir] = /srv/web/myweb/www:/srv/web/myweb/tmp:/dev/urandom
|
Configuration du VirtualHost Apache
Dans la configuration Apache il faut noter 2 éléments pour que tout fonctionne:
- Le SetHandler pour les fichiers PHP qui doit pointer sur le socket ouvert par PHP-FPM
- Le AssignUserId qui définira les droits qu'Apache doit utiliser pour accéder aux fichiers
Fichier de configuration du vhost |
---|
<VirtualHost *:80>
ServerName myweb.com
ServerAlias www.myweb.com
DocumentRoot /srv/web/myweb
<FilesMatch \.php$>
SetHandler "proxy:unix:/srv/web/myweb/myweb.sock|fcgi://localhost"
</FilesMatch>
<IfModule mpm_itk_module>
AssignUserId myweb nobody
</IfModule>
#Redirect "/" "https://myweb.com/"
</VirtualHost>
#<VirtualHost *:443>
# ServerName myweb.com
# ServerAlias www.myweb.com
#
# SSLEngine on
# SSLProtocol all -SSLv2 -SSLv3
# SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
# SSLCertificateFile /etc/letsencrypt/live/myweb/fullchain.pem
# SSLCertificateKeyFile /etc/letsencrypt/live/myweb/privkey.pem
#
# DocumentRoot /srv/web/myweb
#
# <FilesMatch \.php$>
# SetHandler "proxy:unix:/srv/web/myweb/myweb.sock|fcgi://localhost"
# </FilesMatch>
#
# <IfModule mpm_itk_module>
# AssignUserId myweb nobody
# </IfModule>
#
#</VirtualHost>
|