---
title:  "De mysteries achter SELinux"
excerpt: 'Voor velen is SELinux nog een groot mystery. Jammer want het biedt veel voordelen en maakt je systeem ineens een pak veiliger'
coverImage: '/SELinux/SELinux_cover.png'
date:   '2023-07-31T20:00:00.000Z'
author: Eli Winderickx
hero_image: /SELinux_cover.png
category: SELinux,Wish I knew sooner,Configuratie,Expert Tip
---
## De basis
Zoals altijd beginnen we bij het begin. SELinux of Security Enhanced Linux is een extra laag bovenop de `Discretionary Access Control`, genaamd `Mandatory Access Control`. Voordat `SELinux` dus "vervelend" kan doen, moeten dus onder andere de rechten al goed staan. eigenaar en groep op de map, gebruiker lid van de groep, bestand- en mappenrechten,... Pas daarna, als die hordes overbrugt zijn, zal SELinux een additionele controle doen. Daarnaast is het ook handig om te weten is dat `SELinux` `Access Vector Cache` gebruikt. Dat wil zeggen dat:
- Je gaat meldingen van blokkades kunnen terugvinden in:  
  - `/var/log/audit/audit.log`,
  - alsook in de `Systemd Journal` (`journalctl -xe`)
- Het maakt gebruik van cache dus het kan zijn dat wijzigingen niet altijd meteen actief worden.

## Hoe kan ik zien waar `SELinux` actief is?
Zowel bestanden als processen vallen altijd onder een SELinux beleid als deze actief is. Maar eerst even SELinux zelf. Je kan het proces opvragen via `sestatus`. Deze geeft je dan de `Type` alsook de `Mode` mee. Standaard gaat dat staan op `Targeted` en `Enforcing`. maar er zijn nog andere types en modi.  
Type:
- `Targeted`: Default: Controleert welke processen aan welke bestanden mogen.
- `mls`: Multi-level security. Naast `Targeted` mode, zal het ook nagaan of de gebruiker effectief naar die bestanden mag gaan. Root mag bijvoorbeeld een bestand bewerken maar als je als `sudoer` het bestand opent, zou dat niet mogen lukken. Daar zorgt deze policy voor.
- `minimun`: Hierbij gaan slechts bepaalde processen gecontroleerd worden.

Mode:
- `Enforcing`: SELinux controleert en houdt alles tegen wat niet mag
- `Permissive`: SELinux controleert maar houdt niets tegen. Alles wordt standaard wel gedocumenteerd.
- `Disabled`: Deze mode gaan we niet gebruiken want dit schakelt SELinux uit.

### De bestanden en processen
Om de configuratie van bestanden te controleren, kan je het list commando uitvoeren met de `-Z` flag. Datzelfde kunnen we doen voor processen.
```bash
ls -alZ /root
# ... unconfined_u:object_r:admin_home:s0:...
ps auZ
# ...unconfined_u:unconfined_u:unconfined_u:s0-s0:
```

![Security context in processen](/SELinuxProcess.png)

De `SELinux` context kan opgedeeld worden door middel van het `:` teken. Het eerste deel slaagt op de `user mapping`, vervolgens `role`, dan `type` en het laatste gedeelte is het level. Dit level is relevant in de `multi-level security` policy.


## Hoe verander ik dat nu?
De configuratie van `SELinux` is terug te vinden in `/etc/selinux/config`. Dit is steeds de permanentere config waar we willen zijn. Dit bestand gaan we niet te vaak aanpassen. Veel eerder kunnen we met `setenforce` de mode aanpassen naar een tijdelijk gewenste mode.

```bash
sudo setenforce permissive
# Daarna kunnen we controleren
sudo getenforce
```

Ook tijdens de boot van een machine kunnen we in GRUB extra opties toevoegen door op `e` te drukken nadat we een gewenste kernel hebben geselecteerd. Achteraan de `Linux` lijn, kunnen we dan ofwel `selinux=0` zetten om `SELinux` voor 1 boot volledig uit te schakelen of `enforcing=0` om SELinux tijdelijk op permissive te zetten.

> Dit kan je ook permanenter doorvoeren. Best doe je dat in de SELinux config maar via `grubby` gaat dat zo: `grubby --update-kernel$(grubby --default-kernel) --args enforcing=0`

Je begrijpt misschien al dat je best `SELinux` op `Permissive` zet. Hiermee wordt er niets geblokkeerd maar als de `Policy` op `Targeted` of `mls` staat, kunnen we gemakkelijk achterhalen of `SELinux` effectief in de weg stond.

### Security context veranderen
#### Bestanden en mappen
Als je een bestaand bestand verplaatst van ene map naar de andere gaat de security context onveranderd blijven in tegenstelling tot nieuwe bestanden die meteen de correcte context van de parent map krijgen. In geval van onder andere een webserver kan dit vervelende scenario's veroorzaken. Gelukkig is dit snel recht te zetten;
```bash
# -v voor verbose en -R voor Recursief
restorecon -vR /pad/naar/parent/folder
```

Als dit niet klopt, kan je in analogie van `chmod` of `chown` ook `chcon` gebruiken om de security context aan te passen.
```bash
# Neem security context over van een ander bestand
chcon --reference <referentiebestand> bestand
# Of stel het manueel in
chcon -t httpd_sys_content_t bestand
```

In verschillende gevallen staat in `/var/log/audit/audit.log` ook duidelijke informatie over welk bestand of map verkeerd staat en wat er ingesteld moet worden. Als je dat graag wat leesbaarder wilt, kan de inhoud doorsturen naar `audit2why` om een leesbaarder formaat terug te krijgen.
```
cat /var/log/audit/audit.log | audit2why
```

#### Booleans
Soms staat hier een boolean in die je meteen kan uitvoeren zoals hieronder. Die zorgen er dan voor dat je eenvoudig een policy kan activeren of deactiveren zonder grote wijzigingen in SELinux of zonder dat je je eigen modules moet schrijven.
```
semanage -P zabbix_can_network 1
```

#### Modules
In andere gevallen moet je soms zelf een module maken. Ook hier moet je zelf het warm water niet opnieuw uitvinden. Je kan die module laten genereren, controleren en vervolgens toepassen.
```bash
# Maakt een .te en .pp bestand aan in huidige map.
ausearch -C '<soft>' --raw | audit2allow -M <NaamNieuweModule>
# Daarna kan je die module installeren
semodule -i <NaamNieuweModule>.pp
```

## Een praktisch voorbeeld
Ik heb `Nginx` geïnstalleerd met `dnf install nginx` en heb in de configuratie gekozen om een andere document root te gebruiken, namelijk `/srv/www/public_html`. Minder populair dan `/var/www/` maar nog steeds een map waar een website hoort te staan.

```conf
# /etc/nginx/nginx.conf
# ...
server {
  root  /srv/www/public_html;
# ...
```

Als we nu de website proberen te benaderen krijgen we nu een error in het audit log. Ik heb zelf die map aangemaakt en deze heeft nog niet de juiste security context. Dat kunnen we aanpassen!

![Audit log met error over onze public_html map](/SELinux_AuditLog.png)

```bash
# We kennen de juiste security context toe aan de map
chcon -R -t httpd_sys_content_t /srv/
```

Omdat we heel Agile werken, heb ik nieuwe bestanden geüpload naar mijn persoonlijke map voor deze website en van daaruit verplaats ik die met `mv`. Opnieuw krijgen we nu een probleem met SELinux. Geen probleem voor ons want we weten hoe we dat moeten aanpakken! Alhoewel het audit log ons zal voorstellen om een module te maken die `Nginx` toegang zal geven aan mijn publieke map, zijn wij slimmer en gebruiken wij `restorecon` om de security context in de map te herstellen.

```
mv ~/myNewIndex.html /srv/www/public_html/index.html
```
![Foute security context](/SELinux_FoutieveSecurityContext.png)

```
restorecon -R /srv/www/public_html/
```

De website gaat nu goed werken!

## Enkele aandachtspunten
### Voer niet gewoon alles uit in het `audit.log`
Stel je werkt als root op een server (wat sowieso af te raden is) en je verplaatst een bestand naar de document root van een webserver, dan gaat die security context mogelijk staan als `admin_home`. Het `audit.log` kan dan voorstellen om `httpd` toegang te geven tot `admin_home`. Dat is helemaal niet wenselijk. Zo kunnen we de webserver toegang verschaffen naar de `/root` map.

### Maak je aanpassingen wanneer SELinux uitgeschakeld staat
Dat kan je! Vooral in noodgevallen wanneer je naar een emergency target opstart, ga je aanpassingen doen aan jouw systeem terwijl SELinux volledig uitstaat. Let wel op als je achteraf het toestel herstart. Als je dat niet goed aanpakt, kan je mogelijk ongewenste blokkades tegenkomen. De oplossing is simpel. je moet gewoon een bestand aanmaken en SELinux controleert en herstelt alles.
```bash
touch /.autorelabel
```