Resources beperken met Ulimit
- August 27, 2022
- 0
Op een multi-user systeem moet je als admin ervoor zorgen dat elke gebruiker voldoende resources ter beschikking heeft. Dat geldt zowel voor echte gebruikers als voor service accounts die een daemon draaien. Cruciaal daarbij is dat niemand met alle resources aan de haal kan gaan. Daarvoor beschikt Linux sinds jaar en dag over een eenvoudig, maar efficiënt systeem om beperkingen per gebruiker in te stellen. We bekijken kort hoe dat in zijn werk gaat.
Ulimit
De huidige beperkingen voor jouw gebruiker vraag je op met het ulimit-commando:
$ ulimit -a
Technisch gezien is dat geen extern commando, maar een builtin van bash. De help-functie open je dus met “help ulimit” en niet met “man ulimit”, maar dat terzijde. Er zijn maar liefst 16 verschillende limits om in te stellen. Ongeveer de helft daarvan heeft standaard een bepaalde waarde, de rest staat op unlimited. Voor elke limit zijn er steeds twee waarden ingesteld:
1. de actuele waarde, ofwel de soft limit
2. de maximale waarde, ofwel de hard limit
Soft versus hard
Een gewone gebruiker kan de soft limits aanpassen tot aan de waarde van de hard limits, maar enkel root kan de hard limits wijzigen. Het systeem van soft en hard limits geeft de gebruikers dus enige vrijheid om de limits te verhogen. Het bovenstaande commando gaf alle ingestelde soft limits weer, voor de hard limits gebruik je:
$ ulimit -Ha
De uitvoer van ulimit -a geeft meteen voor elke limit aan met welke optie je die kan aanpassen. In de praktijk stoot je van alle limieten vaak het eerst op max user processes (-u) of open files (-n). Die laatste staat standaard ingesteld op 1024:
$ ulimit -n
1024
Maar je mag die maar liefst 1024 maal hoger instellen:
$ ulimit -Hn
1048576
Bijvoorbeeld:
$ ulimit -n 8192
$ ulimit -n
8192
Configuratie
Die wijziging is enkel actief in je huidige shell-sessie. Om de limit permanent te wijzigen, neem je het ulimit-commando op in ~/.bashrc of voeg je een entry toe aan het bestand /etc/security/limits.conf (meer uitleg over de precieze syntax vind je in het bestand zelf). Dat laatste bestand is hoe dan ook de enige manier om een hard limit aan te passen voor een gewone gebruiker.
Processen
Met ulimit controleer je in de huidige shell de ingestelde limieten, maar wat met processen die op de achtergrond draaien? Je mag er niet zomaar van uitgaan dat die de standaardlimieten hebben van de gebruiker die het proces gestart heeft. Het is immers goed mogelijk dat het opstartscript voor die processen bepaalde limieten verhoogd of net verlaagd heeft. Gelukkig is het erg eenvoudig om de limits van een proces op te vragen. Zoek eerst het proces id op via ps of top en vul dat in onderstaand commando in:
$ cat /proc/<proces id>/limits
Re
Fork bomb
Als uitsmijter geven we een kort voorbeeld waarom het belangrijk is om pakweg het maximaal aantal processen van een gewone gebruiker te beperken. Een klassiek voorbeeld is de zogenaamde formk bomb in bash. Deze ietwat cryptische code maakt binnen de seconde zoveel processen aan dat het systeem gewoon crasht:
:(){ :|:& };:
De “:(){ }” omvat de definitie van een functie genaamd “:”. Die functie doet niets meer dan in de achtergrond zichzelf starten en vervolgens pipen naar zichzelf: “:|:&”, waardoor er almaar meer processen starten. Tot slot roepen we de functie aan om de bom als het ware af te laten gaan. Voer je dat bijvoorbeeld uit op een Raspberry Pi met de standaard limit van 1024 processen, dan krijg je weliswaar een aantal foutmeldingen, maar geeft het systeem verder geen kik. Verhoog je de limit echter naar het maximaal toegestane voor gewone gebruikers (28559), dan crasht het systeem binnen enkele seconden. Je bent gewaarschuwd!