This page looks best with JavaScript enabled

Apache Centos8/PHP7 multi-user

 ·  ☕ 3 min read

Depuis la version 7 de php, suphp ne fonctionne plus.
Pour info, suphp permettait de faire tourner php avec l’uid et le gid du propriétaire du fichier php: Idéal pour sécuriser un hébergement mutualisé avec plusieurs sites et propriétaires différents.

Voici une méthode pour faire de même avec php7 en php-fpm et les paquets rémi sous Centos 8 ou/et dérivé de Redhat 8.

Chaque site est associé à un utilisateur qui publie ses fichiers php avec son uid et gid via un serveur sftp.

Pour chaque site, un groupe de process php-fpm est lancé avec l’uid et gid correspondant à l’utilisateur.

Ainsi un process php d’un site A ne peut pas accéder au process et répertoire disque d’un site B. Il en est de même avec la publication sftp chrooté.

Installation Centos 8

  • Selinux disabled
  • Dépots tiers
dnf install epel-release -y
dnf install https://rpms.remirepo.net/enterprise/remi-release-8.rpm
dnf config-manager --set-enabled PowerTools
dnf config-manager --set-enabled remi
  • Paquets php installés:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
php-common-e7.4.3-1.el8.remi.x86_64
php-fpm-7.4.3-1.el8.remi.x86_64
php-process-7.4.3-1.el8.remi.x86_64
php-pecl-zip-1.17.1-1.el8.remi.7.4.x86_64
php-json-7.4.3-1.el8.remi.x86_64
php-pdo-7.4.3-1.el8.remi.x86_64
php-cli-7.4.3-1.el8.remi.x86_64
php-gd-7.4.3-1.el8.remi.x86_64
php-mbstring-7.4.3-1.el8.remi.x86_64
php-soap-7.4.3-1.el8.remi.x86_64
php-xml-7.4.3-1.el8.remi.x86_64
php-pecl-mysql-1.0.0-0.23.20190415.d7643af.el8.remi.7.4.x86_64
php-mysqlnd-7.4.3-1.el8.remi.x86_64
php-intl-7.4.3-1.el8.remi.x86_64
php-tidy-7.4.3-1.el8.remi.x86_64
Paquets apache installés:
httpd-2.4.37-16.module_el8.1.0+256+ae790463.x86_64
httpd-filesystem-2.4.37-16.module_el8.1.0+256+ae790463.noarch
centos-logos-httpd-80.5-2.el8.noarch
httpd-tools-2.4.37-16.module_el8.1.0+256+ae790463.x86_64

Conf sftp only et chroot

Les utilisateurs dans le groupe groupchroot ne peuvent faire que du sftp dans leur répertoire (pas de shell, pas de ssh!)

  • Modification du fichier /etc/ssh/sshd_config
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
SyslogFacility AUTHPRIV
PermitRootLogin yes
AuthorizedKeysFile	.ssh/authorized_keys
PasswordAuthentication yes
ChallengeResponseAuthentication no
GSSAPIAuthentication yes
GSSAPICleanupCredentials no
UsePAM yes
X11Forwarding yes
UsePrivilegeSeparation sandbox	
PrintMotd no

AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS

Subsystem sftp internal-sftp

# -----------------------------
Match Group groupchroot
ChrootDirectory %h
AllowTCPForwarding no
X11Forwarding no
#-------------------------------

HostbasedAuthentication yes

Match Group groupchroot 
X11Forwarding no
AllowTcpForwarding no
ChrootDirectory /home

Création d’un site monsite.fr associé à l’user moi

  • Création de l’user et ajout dans le groupe groupchroot pour le ssh
adduser moi
usermod -G groupchroot moi
passwd moi
  • Modification des droits et création lien symbolique
chown root:root -R /home/moi
mkdir /home/moi/public_html
chown moi:root -R /home/moi/public_html
chmod 755 -R /home/moi/public_html
ln -s /home/moi/public_html /var/www/html/monsite.fr
  • Création du daemon php cloisonné pour cet user (un fichier par site web)

vi /etc/php-fpm.d/monsite.fr.conf

Exemple:


[monsite.fr]
user = moi
group = moi

## La socket
listen = /var/run/php-fpm/monsite.fr.sock

listen.acl_users = apache,nginx
listen.allowed_clients = 127.0.0.1
pm = ondemand
pm.max_children = 50
pm.start_servers = 3
pm.min_spare_servers = 3
pm.max_spare_servers = 35

## TUNER le log pour le site
slowlog = /var/log/php-fpm/www-slow-monsite.fr.log
php_admin_value[error_log] = /var/log/php-fpm/monsite.fr-error-too.log
php_admin_flag[log_errors] = on
php_value[session.save_handler] = files
php_value[session.save_path]= /var/lib/php/session
php_value[soap.wsdl_cache_dir] = /var/lib/php/wsdlcache
  • Reload du daemon php

systemctl reload php-fpm

  • Creation du VHOST Dans apache

vi /etc/httpd/conf.d/monsite.fr.conf

SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1
<VirtualHost *:80>

ServerName monsite.fr
DocumentRoot /var/www/html/monsite.fr
ErrorLog logs/monsite.fr-error_log
CustomLog logs/monsite.fr-access_log common


#### METTRE ICI LA SOCKET ######
<FilesMatch \.php$>
SetHandler "proxy:unix:/var/run/php-fpm/monsite.fr.sock|fcgi://localhost"
</FilesMatch>

#### METTRE ICI LE REPERTOIRE ####

<Directory /var/www/html/monsite.fr>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</directory>

</VirtualHost>
  • Reload du daemon apache

systemctl reload httpd

Donc l’idée de base était de cloisonner la publication sftp et l’exécution du daemon php.
Les conf sont des exemples, cela doit être adapté au niveau de sécurisation souhaité, notamment pour Apache (Droit .htaccess, Allow …) et php (disable de commande, max_size …), mais la base est là.

TCHAO


Ghis
WRITTEN BY
Ghis
AdminSys