# Créer un groupe d'utilisateurs pour un site web Apache
## Pourquoi un groupe par site ?
Quand on héberge un site web, deux populations doivent pouvoir lire ses fichiers : **Apache** (le serveur web, qui les sert aux visiteurs) et les **personnes qui maintiennent le site** (développeurs, intégrateurs, administrateurs de contenu). Si on ne réfléchit pas à la question des droits, on tombe rapidement dans un des deux travers classiques :
- **Tout ouvrir** (`chmod 777` partout) : c'est la porte ouverte aux compromissions. Si une faille permet à Apache d'écrire un fichier, l'attaquant peut alors écraser n'importe quel script PHP du site.
- **Tout faire en root** : c'est pratique au début, mais cela impose à chaque mainteneur de connaître le mot de passe administrateur, et il devient impossible de tracer qui a modifié quoi.
La bonne pratique est donc de créer **un groupe dédié par site**, qui rassemble les personnes habilitées à intervenir dessus. Plusieurs avantages :
- **Évolutif** : ajouter ou retirer un mainteneur revient à ajouter ou retirer un utilisateur du groupe, sans rien changer aux permissions des fichiers.
- **Étanche** : les mainteneurs d'un site n'ont aucun droit sur les autres sites de la machine.
- **Traçable** : chaque modification est faite par un compte nommé, pas par `root`.
Cette approche reste valable même pour un site géré par une seule personne : le jour où vous voudrez déléguer la maintenance ou simplement créer un compte de déploiement, le travail aura déjà été fait.
Dans cet article, on prend comme exemple un site fictif **perdu.com**, dont les fichiers seront placés dans `/var/www/perdu.com`. Adaptez les noms à votre cas.
## Étape 1 — Créer le groupe dédié
```
sudo groupadd www-perdu.com
```
Le nom du groupe est arbitraire ; le préfixe `www-` est une convention qui rappelle qu'il s'agit d'un groupe lié à un site web. Vous pouvez vérifier sa création :
```
getent group www-perdu.com
```
## Étape 2 — Ajouter les mainteneurs au groupe
Ajoutez chaque utilisateur qui devra travailler sur le site :
```
sudo usermod -aG www-perdu.com chloe
```
L'option **`-a` (append) est obligatoire** : sans elle, `-G` **remplace** la liste complète des groupes secondaires de l'utilisateur au lieu d'y ajouter. C'est l'erreur classique qui fait perdre à quelqu'un l'accès à `sudo`, `docker` ou `libvirt` parce qu'on a écrasé ses autres appartenances.
Pour ajouter plusieurs personnes :
```
sudo usermod -aG www-perdu.com chloe
sudo usermod -aG www-perdu.com mathieu
```
**Important** : l'appartenance à un nouveau groupe n'est prise en compte qu'à la **prochaine ouverture de session**. Si chloe est déjà connectée, elle doit se déconnecter puis se reconnecter (ou ouvrir un nouveau terminal SSH). Pour vérifier ses groupes effectifs :
```
groups chloe
```
## Étape 3 — Créer l'arborescence du site
On place le site dans `/var/www`, l'emplacement standard sur Debian/Ubuntu et un choix courant sur Fedora/RHEL :
```
sudo mkdir -p /var/www/perdu.com/www
sudo mkdir -p /var/www/perdu.com/logs
```
L'option `-p` crée les dossiers parents au besoin et ne renvoie pas d'erreur s'ils existent déjà. La structure proposée sépare les fichiers servis publiquement (`www/`) de ce qui ne doit jamais être exposé (logs applicatifs, sauvegardes, données privées).
À ce stade, les dossiers appartiennent à `root:root` avec des droits `755`. Personne d'autre que root ne peut y écrire.
## Étape 4 — Attribuer la propriété au groupe
On veut que :
- **Le groupe `www-perdu.com`** puisse lire **et écrire** dans les dossiers (les mainteneurs déploient et modifient les fichiers).
- **Apache** puisse lire les fichiers pour les servir.
- **Personne d'autre** ne puisse y accéder.
On commence par attribuer le groupe :
```
sudo chgrp -R www-perdu.com /var/www/perdu.com
```
L'option `-R` (récursif) applique le changement à tout le contenu déjà présent.
Puis on applique des permissions adaptées :
```
sudo find /var/www/perdu.com -type d -exec chmod 2775 {} \;
sudo find /var/www/perdu.com -type f -exec chmod 664 {} \;
```
Décortiquons ce qui se passe ici. On utilise `find` plutôt qu'un `chmod -R` unique parce que **les permissions des dossiers et des fichiers ne doivent pas être les mêmes** : un fichier de configuration n'a pas à être exécutable, alors qu'un dossier a besoin du bit `x` pour être parcouru.
- **Dossiers : `2775`** soit `rwxrwsr-x`. Le propriétaire (root) et les membres du groupe `www-perdu.com` peuvent lire, écrire et entrer dans le dossier. Les autres (dont `www-data`/`apache`) peuvent lire et entrer, mais pas modifier.
- **Fichiers : `664`** soit `rw-rw-r--`. Le propriétaire et le groupe peuvent lire et écrire, les autres uniquement lire.
### Le bit SGID : pourquoi le `2` en tête ?
Le chiffre `2` devant `775` active le **bit SGID** sur les dossiers. Ce bit a un effet décisif : **tout nouveau fichier ou sous-dossier créé hérite automatiquement du groupe du dossier parent**, au lieu d'hériter du groupe principal de la personne qui le crée.
Sans SGID, si chloe (dont le groupe principal est `chloe`) crée un fichier, ce fichier appartient au groupe `chloe`, ce qui le rend invisible en écriture pour les autres mainteneurs du site. Avec SGID, le fichier appartient automatiquement à `www-perdu.com`, et toute l'équipe peut continuer à travailler dessus sans intervention.
Si vous préférez utiliser `chmod` directement plutôt que `find`, voici la version équivalente — un peu plus permissive sur les exécutables existants, mais plus simple à retenir :
```
sudo chmod -R g+rwX,o+rX,o-w /var/www/perdu.com
sudo find /var/www/perdu.com -type d -exec chmod g+s {} \;
```
L'astuce du `X` majuscule (au lieu de `x` minuscule) est utile : elle n'ajoute le droit d'exécution qu'aux dossiers et aux fichiers déjà exécutables, sans rendre exécutables tous les fichiers texte par mégarde.
## Étape 5 — Garantir les bons droits sur les nouveaux fichiers
Le SGID s'occupe du groupe, mais pas des permissions elles-mêmes. Pour que les fichiers créés par un mainteneur soient en `664` (et non en `644` qui interdirait l'écriture aux autres membres du groupe), il faut un **umask permissif** côté utilisateur.
Demandez à chaque mainteneur d'ajouter cette ligne à son `~/.bashrc` :
```
umask 0002
```
Cet umask conserve les droits d'écriture pour le groupe. Avec un umask `0022` (le défaut habituel), chloe créerait des fichiers en `644` que mathieu ne pourrait pas modifier.
### Solution plus robuste : les ACL
Si vous voulez une garantie absolue sans dépendre du umask de chacun, les **ACL** (*Access Control Lists*) sont l'outil de référence :
```
sudo setfacl -R -m g:www-perdu.com:rwX /var/www/perdu.com
sudo setfacl -R -d -m g:www-perdu.com:rwX /var/www/perdu.com
```
La première ligne applique le droit, la seconde le rend **par défaut** : tout nouveau fichier ou dossier créé dedans héritera automatiquement de ces droits, peu importe l'umask. Sur Debian/Ubuntu, les ACL sont déjà activées par défaut sur les systèmes de fichiers modernes ; sur d'autres distributions, vous pourriez devoir installer le paquet `acl`.
Vérifier les ACL en place :
```
getfacl /var/www/perdu.com
```
## Étape 6 — Le cas particulier d'Apache
Sur Debian/Ubuntu, Apache fonctionne sous l'utilisateur **`www-data`** ; sur Fedora/RHEL et openSUSE, il s'agit de **`apache`**. Vérifiez le bon nom sur votre système :
```
ps aux | grep -E 'apache|httpd' | grep -v grep
```
Avec les permissions définies plus haut, Apache peut **lire** tous les fichiers du site (le droit `r-x` accordé aux *autres* suffit). C'est ce qu'on veut dans 90 % des cas : Apache sert le contenu sans pouvoir le modifier, ce qui limite considérablement les dégâts d'une éventuelle faille.
### Quand Apache a besoin d'écrire
Certaines applications web ont besoin qu'Apache puisse écrire dans des dossiers précis : envoi de fichiers via un formulaire, cache, sessions, génération de miniatures… Le piège, c'est de répondre à ce besoin en ouvrant l'écriture **partout**, ce qui rend possible le téléversement d'un script malveillant qui sera ensuite exécuté.
**Ne donnez l'écriture à Apache que sur les dossiers strictement nécessaires.** Exemple pour un dossier `uploads` :
```
sudo mkdir -p /var/www/perdu.com/www/uploads
sudo chown www-data:www-perdu.com /var/www/perdu.com/www/uploads
sudo chmod 2775 /var/www/perdu.com/www/uploads
```
Sur Fedora/RHEL, remplacez `www-data` par `apache`.
**Variante avec ACL**, sans changer le propriétaire :
```
sudo setfacl -R -m u:www-data:rwX /var/www/perdu.com/www/uploads
sudo setfacl -R -d -m u:www-data:rwX /var/www/perdu.com/www/uploads
```
C'est souvent plus propre : le propriétaire principal reste `root`, et on ajoute juste un droit ciblé pour Apache. Pas d'ambiguïté sur « à qui appartient ce dossier ».
### Empêcher l'exécution dans les dossiers d'upload
Un dossier où Apache peut écrire et où il peut exécuter du PHP est une cible classique. Désactivez explicitement l'exécution de scripts dans `uploads/` via la configuration Apache du site :
```