# Least Privilege: Webserver-brugerens rettigheder

> Webserver-bruger med minimale rettigheder: ingen shell, ingen sudo, ingen cron, snævre databaserettigheder og systemd-beskyttelse til PHP-FPM. Med kontrolkommandoer.

Kilde: https://phpsos.de/da/blog/rechte-des-webserver-benutzers/  
Status: 25.10.2026  
Udbyder: PHP SOS, PHP-nødhjælp og serversikkerhed. Akut hjælp på WhatsApp: https://wa.me/491736494914?text=Hej%20PHP%20SOS%2C%20vi%20har%20brug%20for%20hj%C3%A6lp%20med%20vores%20PHP-server.%20Firma%3A%20%E2%80%A6%20Website%3A%20%E2%80%A6

**Kort sagt:** Webserver-brugeren, som PHP kører under, bør efter princippet om minimale rettigheder (Least Privilege) kun læse det, websitet har brug for, og kun skrive de steder, hvor det gemmer data. Brugeren har ingen login-shell, ingen sudo-rettigheder, ingen egne cronjobs og ingen SSH-nøgler, og dens databasekonto må kun læse og ændre data. systemd-indstillinger som `ProtectSystem` og `PrivateTmp` afgrænser desuden PHP-FPM.

## Spørgsmålet efter indbruddet: Hvad må denne proces?

Ved PHP2Shell handler det om udførelse af skadelig kode på afstand uden login. Lykkes det, kører koden ikke i et tomrum, men som en helt bestemt bruger: PHP-processens bruger. Alt, hvad denne bruger må, må angriberen fra det øjeblik også.

På mange servere er det overraskende meget. Brugeren ejer hele programkoden, har en shell, kan oprette egne cronjobs, og applikationens databasekonto har alle rettigheder til alle databaser. For en angriber er det det ideelle udgangspunkt for at etablere sig varigt.

Hvordan I tildeler filer og mapper de rigtige rettigheder, beskriver vejledningen [Filrettigheder på webserveren](https://phpsos.de/da/ratgeber/dateirechte-webserver/). Dette indlæg ser på selve kontoen: login, særrettigheder, planlagte opgaver, database og de grænser, systemd trækker.

## Opgørelse: Hvem er webserver-brugeren?

Først afklarer I, hvilke brugere der overhovedet er involveret. Ved PHP-FPM fastlægger hver pool med `user` og `group`, under hvem dens workers kører. Ved mod_php kører PHP som Apache-bruger. Hvordan master og workers spiller sammen i PHP-FPM, forklarer [PHP-FPM forklaret: Procesmanager, pools og workers](https://phpsos.de/da/php/php-fpm-erklaert/). Følgende kommandoer læser kun:

```bash
# Under hvilke brugere kører webserver og PHP?
ps -eo user,group,cmd | grep -E "[p]hp-fpm|[n]ginx|[a]pache2|[h]ttpd" | sort | uniq -c
# Kontooplysninger: hjemmemappe og shell (tilpas brugeren)
getent passwd www-data
# Har brugeren sudo-rettigheder?
sudo -l -U www-data
# Egne cronjobs?
sudo crontab -l -u www-data
# SSH-nøgler i hjemmemappen (under Debian/Ubuntu er det /var/www)
sudo ls -la /var/www/.ssh 2>/dev/null
```

Notér resultaterne for hver pool-bruger. Kører alle websites under den samme bruger, er det det første punkt på listen; hvordan I adskiller dem, beskriver [Isolér PHP-FPM-pools pr. website](https://phpsos.de/da/blog/php-fpm-pools-isolieren/).

## Webserver-brugerens rettigheder: Hvad kontoen ikke har brug for

Oversigten nedenfor viser, hvad en webserver-bruger typisk ikke har brug for, og hvordan I fratager den det.

| Rettighed | Hvorfor farlig | Anbefaling |
|---|---|---|
| Login-shell | Login og interaktiv brug mulig | Shell `/usr/sbin/nologin` |
| sudo-poster | Vej til root-rettigheder | ingen poster, heller ikke til enkeltkommandoer |
| egen crontab | varig bagdør, der overlever hver genstart | ingen, begræns via `/etc/cron.allow` |
| SSH-nøgler | login udefra | ingen `authorized_keys` |
| Ejerskab af programkoden | koden kan ændres | ejeren er en deploy-bruger |
| Skriverettigheder uden for datamapper | placering af skadelig kode | kun uploads, cache, temp |
| fulde databaserettigheder | andre applikationers databaser, filadgang via databasen | kun egen database, kun datarettigheder |

Shellen sætter I med `usermod -s /usr/sbin/nologin www-data`. For cron gælder: Findes `/etc/cron.allow`, må kun de dér nævnte brugere oprette egne cronjobs. Nyoprettede cronjobs eller ukendte SSH-nøgler er et typisk tegn på, at nogen har fæstnet sig. Et særligt tydeligt advarselstegn beskriver indlægget [Advarselstegn: Webserveren starter en shell](https://phpsos.de/da/blog/webserver-startet-shell/).

## Databasen: Begræns rettighederne til det nødvendige

Et websites databasekonto er reelt en anden webserver-bruger. Dets adgangsdata ligger i applikationens konfigurationsfil og kan læses af indsmuglet kode. Derfor bør det kun have lov til det, applikationen har brug for i drift.

```sql
-- Eksempel MySQL/MariaDB: egen konto pr. website, kun datarettigheder
CREATE USER 'seite1'@'localhost' IDENTIFIED BY 'hier-ein-langes-Zufallspasswort';
GRANT SELECT, INSERT, UPDATE, DELETE ON seite1.* TO 'seite1'@'localhost';
-- Kontrollér rettigheder
SHOW GRANTS FOR 'seite1'@'localhost';
```

Rettigheder som `FILE`, `SUPER` eller `GRANT OPTION` og adgang til `*.*` har en applikationskonto ikke brug for. Mange CMS'er kræver desuden `CREATE`, `ALTER`, `INDEX` og `DROP` til opdateringer. Renere er en separat konto til opdateringer og migreringer, som kun bruges under vedligeholdelse. Kontrollér kravene i producentens dokumentation.

## Afgræns PHP-FPM yderligere med systemd

systemd kan begrænse en tjenestes udsyn over systemet. Til PHP-FPM egner nogle indstillinger fra systemd-dokumentationen sig særligt godt. De virker også på masterprocessen, som starter som root.

```ini
# sudo systemctl edit php8.3-fpm
[Service]
# /usr, /boot og /etc skrivebeskyttet
ProtectSystem=full
# /home, /root og /run/user usynlige
ProtectHome=true
# eget /tmp og /var/tmp kun til denne tjeneste
PrivateTmp=true
# ingen rettighedsudvidelse via setuid eller fil-capabilities
NoNewPrivileges=true
```

Test disse indstillinger, før I tager dem i produktiv brug. Ligger websites under `/home`, forhindrer `ProtectHome=true` adgangen. `NoNewPrivileges=true` kan forstyrre programmer, som PHP kalder, og som skifter gruppetilhørsforhold ved start, f.eks. nogle lokale mailprogrammer til PHP-funktionen `mail()`. Gå derfor frem i trin:

1. Tilføj én indstilling, genstart tjenesten, kontrollér `systemctl status php8.3-fpm`.
2. Test websitets kernefunktioner: login, formularer, mailafsendelse, uploads, applikationens cronjobs.
3. Gennemgå fejlloggen for PHP-FPM og applikationen.
4. Tilføj først derefter den næste indstilling.

Til sidst socketten: Ifølge PHP-manualen får den som standard rettighederne `0660` for poolens bruger og gruppe. Sæt `listen.owner` og `listen.group` så, at kun webserveren kan forbinde, ikke enhver lokal bruger.

> **Tip:**
> Minimale rettigheder er en grundholdning, ikke et engangsprojekt. Gentag opgørelsen fra dette indlæg efter hver ombygning og hvert nyt website, for nye tjenester medbringer ofte generøse standardrettigheder.

## Konklusion: Angriberen arver det, I tillader

Least Privilege lyder som teori, men er et meget praktisk spørgsmål: Hvad kan nogen, der udfører kode som webserver-bruger? På en server med shell, sudo-post, egen crontab og en databasekonto med alle rettigheder er svaret: næsten alt. På en afgrænset server bliver det snarere ved en hændelse i et enkelt website, som kan opdages og ryddes op.

Omlægningen kræver ingen ny software, kun en omhyggelig opgørelse og trinvise tests. Begynd med de punkter, der næppe kan ødelægge noget, altså shell, sudo og SSH-nøgler, og arbejd jer derefter frem til databaserettigheder og systemd-indstillinger.

## Hvordan hjælper PHP SOS konkret?

- **Kontrollere konti:** Vi registrerer for hver pool og webserver bruger, shell, sudo-poster, cronjobs, SSH-nøgler og databaserettigheder.
- **Reducere rettigheder:** Vi fratager det, der ikke er brug for, og adskiller deploy-, drifts- og vedligeholdelseskonti.
- **Afgrænse tjenester:** Vi sætter systemd-beskyttelsesindstillinger trinvist og tester websitet efter hvert trin.
- **Fastholde varigt:** Som en del af [serverhærdningen](https://phpsos.de/da/leistungen/server-haertung/) dokumenterer vi rettighedskonceptet til fremtidige ændringer.


## Ofte stillede spørgsmål

**Under hvilken bruger kører PHP på min server?**  
Det afhænger af driftsformen. Ved mod_php kører PHP som Apache-bruger, f.eks. www-data eller apache. Ved PHP-FPM fastlægger hver pool sin bruger med user og group; masterprocessen kører som regel som root, workerne som poolens bruger. Kommandoen ps viser det hurtigt.

**Har webserver-brugeren brug for en login-shell?**  
Nej. Hverken Nginx, Apache eller PHP-FPM har brug for et interaktivt login for denne bruger. En shell som /usr/sbin/nologin forhindrer, at nogen logger ind med denne konto. Deployments kører via en separat bruger.

**Hvorfor ingen sudo-rettigheder til www-data, heller ikke til en enkelt kommando?**  
Fordi indsmuglet kode arver netop disse rettigheder. Selv en tilsyneladende harmløs kommando kan, hvis den er frigivet forkert, føre til root-rettigheder. Opgaver, der kræver forhøjede rettigheder, hører hjemme i adskilte tjenester eller forløb uden for webserveren.

**Hjælper det mod PHP2Shell?**  
Det lukker ikke sårbarheden; til det skal der bruges PHP-opdateringen og en genstart af alle workers. Minimale rettigheder begrænser dog, hvad en angriber kan gøre efter en vellykket udnyttelse: ændre filer, fæstne sig, nå andre websites.

## Kilder

- [PHP-manual: FPM-konfiguration (user, listen.mode)](https://www.php.net/manual/en/install.fpm.configuration.php)
- [systemd.exec (ProtectSystem, PrivateTmp, NoNewPrivileges)](https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html)
- [BSI IT-Grundschutz](https://www.bsi.bund.de/DE/Themen/Unternehmen-und-Organisationen/Standards-und-Zertifizierung/IT-Grundschutz/it-grundschutz_node.html)
- [OWASP Cheat Sheets](https://cheatsheetseries.owasp.org/)
