ich verzweifle hier etwas.. seit Tagen lese ich im Netz darüber nach, wie ich meinen Usern Limits aufzwingen kann, in Bezug auf Speichernutzung, CPU-Last und Anzahl der Prozesse.
Halt, stop
Ich weiß, es gibt die /etc/security/limits.conf (von PAM), die /etc/limits (von Shadow), es gibt im Apache die RLimit-Optionen, es gibt grsecurity und RSBAC - und all das Zeug kriegt es nicht auf die Reihe einfach nur zu sagen:
Alle Prozesse (!) die dem User kd5000 gehören, unterliegen folgenden Beschränkungen:
- gesamter maximaler RAM-Verbrauch des Users ist XYZ MByte,
- der User darf maximal 100 Prozesse starten,
- keins seiner Programme darf mehr als 30 Sekunden CPU-Zeit verbrauchen
Ich krieg noch die Krise.. Unix und Linux werden doch schon seit Ewigkeiten im multi-user Betrieb eingesetzt, da kann es doch nicht sein, dass man heute noch jeden Server mit einer Fork-Bombe platt machen kann :twisted:
So, aber nun genug geschimpft (liegt vermutlich eh daran, dass ich die Lösung einfach nicht sehe). Meine Config sieht wie folgt aus (und darf auch gern kritisch kommentiert werden):
Ubuntu Feisty,
jeder User soll bald SSH-Zugang haben,
Apache 2.2 mit PHP 5.2.3, Python 2.5.1 und Ruby 1.8.5,
SuEXEC für jeden Virtualhost auf den jeweiligen User, die Wrapper-Skripte sind allerdings für den jeweiligen User zugänglich und editierbar (meiner Meinung nach bringt es nichts, das zu beschränken, weil der User sonst das Programm einfach in seiner Shell startet, wenn er unbedingt will..)
PHP und Ruby werden über mod_fcgid als FastCGI eingebunden,
Python über mod_wsgi im Daemon-Mode
Das heißt, alle Sachen, die ein User über den Apache oder die Shell starten kann, laufen auch unter seiner User-ID. Der Trick ist aber eben, dass er sie über den Apache per FastCGI *oder* per Shell starten kann - und dann je nach dem die Limits nicht greifen.
Die Shell zu limitieren, ist einfach - da reicht /etc/security/limits.conf, das funktioniert wunderbar. Wenn ein User also über die Shell die CPU zum Glühen bringen will, sollte ihm das dank Limits recht schnell wieder abgewöhnt werden.
Aber das funktioniert nicht mehr, sobald die Programme überhaupt nicht erst durch die Shell gehen - wenn ich als User ein PHP-/Python-/Ruby-Programm erstelle, was 500 MB RAM verbrät, unendlich oft forkt und irgendein großes Programm von der Platte startet, kommen die limits.conf Einträge nie zur Wirkung.
RLimitCPU / RLimitNPROC etc. zeigen überhaupt keine Wirkung (dabei scheint mir das die Lösung zumindest für den Apache-Teil zu sein..). Ich habe sie mal testweise in eine VirtualHost-Section eingebaut und Apache mit "apache2ctl graceful" neugestartet, mein PHP-Skript lief ohne Probleme 30 Sekunden bei 100% CPU, bis das max_execution_time Limit von PHP selbst gegriffen hat..
Irgendwie steh ich gerade im Wald und seh die Bäume nicht - ich will jetzt auf meinem fertigen Produktivserver nicht nachträglich grsecurity oder RSBAC installieren, auch weil ich von diesen Zusätzen noch überhaupt keine Ahnung habe und erstmal in einer VMware experimentieren will..
Gibt es denn dann keine Möglichkeit, diese Resource Limits *global per User* zu setzen? Es kann doch nicht sein, dass ich in jedem Programm was auf der Kiste existiert und zugänglich für den User ist, einzeln Beschränkungen (falls überhaupt möglich) setzen muss - für PHP in der ini, für Python und Ruby weiß ich noch überhaupt nicht wie, ...
Hat irgendjemand eine Idee? Wie macht ihr das denn oder wie machen das die "großen Provider"?
In meiner Verzweiflung überlege ich mir schon, ein Cronjob-Skript zu verwenden, was einfach die Prozessliste durchgeht und alles killt, was ihm nicht passt - aber das hilft natürlich auch nichts.. dann hat der böse User im worst-case 60 Sekunden Zeit um das System abzuschießen. Eine Fork-Bomb hat das in meiner VMware in 3 Sekunden geschafft. ;)
Viele Grüße und vielen Dank im voraus,
Philipp