… oder: Krisenmanagement für arme Admins. Für ganz, ganz Arme.
Am Mittwoch geht es für mich auf zum diesjährigen Summer Breeze Metal Open Air in Dinkelsbühl. Das bedeutet leider nicht nur Genuss für meine Ohren, sondern auch Stress: Der Admin in mir macht sich Gedanken, ob denn auch alle Server ohne Störungen über die Festivalzeit kommen werden. Unterwegs habe ich nur mein Smartphone mit einer wackeligen Mobilfunkverbindung. Darauf ist ein SSH-Client installiert, der mir Zugriff auf meine Server erlaubt. Und weil mir alleine der Gedanke daran schon weh tut, root-Login darauf zu ermöglichen, kann sich das Smartphone nur als normaler Benutzer zum Server verbinden. Via Publickey-Auth, versteht sich.
Nun stehe ich allerdings vor dem Problem, dass ja ein normaler Benutzer keine Dienste neu starten kann, weil ihm die Rechte dazu fehlen. Möglicherweise werde ich beispielsweise meinen XMPP-Server einmal neu starten müssen, weil die zuletzt getroffenen Maßnahmen nicht gewirkt haben und er wieder einmal keine Logins mehr zulässt. Ein „systemctl restart prosody“ ist mit diesem Account nicht möglich. Nun könnte man mit sudo arbeiten und die Ausführung des Kommandos speziell für diesen User erlauben. Meine Debian-Server kommen allerdings ohne sudo und das soll auch so bleiben. Also kein sudo für mich.
Unter Linux gibt es allerdings noch eine andere Möglichkeit, Befehle mit höheren Rechten auszuführen: setuid. Ist dieses Bit für eine ausführbare Datei gesetzt, wird diese immer mit den Rechten des Dateibesitzers ausgeführt – egal, wer die Ausführung initiiert. Leider funktioniert das mit neueren Linux-Kerneln nicht mehr für Scripts, sodass ich mich kurz dazu entschlossen habe, ein einfaches C-Programm zu schreiben, das den Neustart diverser Dienste übernehmen kann:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> char *prosody = "prosody"; char *php = "php"; char *nginx = "nginx"; int main(int argc, char *argv[]) { setuid(0); // be root if(argc == 2){ // check content of second argument (first is program name) if( strcmp( argv[1], prosody ) == 0) { printf( "Restarting Prosody ..." ); system( "systemctl restart prosody" ); } else if( strcmp( argv[1], php ) == 0) { printf( "Restarting PHP ..." ); system( "systemctl restart php5-fpm" ); } else if( strcmp(argv[1], nginx) == 0) { printf( "Restarting Nginx ..." ); system( "systemctl restart nginx" ); } } return 0; }
Ich will Prosody, Nginx und PHP neu starten können. Das kleine Programm lässt sich natürlich für beliebig viele weitere Dienste erweitern. Programm kompilieren:
$ gcc -o emergency emergency.c
Die Binärdatei „emergency“ wird nun an passender Stelle auf dem Server abgelegt und bekommt vom root-User das SetUID-Bit (4) verpasst:
# chmod 4755 emergency
Nun kann ein einfacher Benutzer das Programm z.B. wie folgt aufrufen:
$ ./emergency prosody
Damit wird der Prosody-Dienst mit root-Rechten neu gestartet.
Sollte mein XMPP-Server bis Sonntag wieder zicken, habe ich zumindest die Möglichkeit, Prosody mal eben neu zu starten. Bei größeren Problemen hilft mir mein SSH-Zugang dann zwar nicht, aber schließlich will ich ja auch nicht stundenlang auf einem Laptop herumhacken, wenn ich schon einmal auf einem Festival unterwegs bin ;-) Dann lasst uns mal alle hoffen, dass Prosody keinen Ärger macht, während ich weg bin …
Oh, da fällt mir ein: Noch billiger wäre ein Cronjob gewesen, der die Dienste alle paar Stunden neu startet … :P Aber die Verbindungsabbrüche will ich meinen Usern dann doch lieber nicht antun.
https://www.layers-gedanken.de
Hab es mal getestet. Debian 8.3:
[15/08-09:33] root@test:~]# chmod 4755 /home/layer8/test
[15/08-09:33] root@test:~]# su layer8
layer8@test:/root$ cd
layer8@test:~$ ./test lighttpd
Failed to restart lighttpd.service: Access denied
Restarting lighttpd …
layer8@test:~
Der mag mich anscheinend nicht :-)
https://legacy.thomas-leister.de/ueber-mich-und-blog/
Merkwürdig, vielleicht habe ich vergessen, einen Schritt hier zu dokumentieren. Habe auch Debian 8.3 laufen.
LG Thomas
https://www.layers-gedanken.de
Problem gefunden: Ich hab es als layer8 und nicht als root erstellt. ein chown und anschließendes chmod 4755 brachte erfolg :-)
https://www.dannykorpan.de
Schon einmal mit Zabbix versucht zur Überwachung? Für einen Server sicherlich ein wenig überdimensioniert, aber du schreibst ja von mehreren Servern. Hier kann man auch bei nicht funktionieren z.B. automatisch Dienste neu starten lassen, Skripte ausführen etc.
https://www.layers-gedanken.de
Nach dem es nun bei mir läuft: Direkt ein kleiner Verbesserungsvorschlag:
Statt zB:
printf( „Restarting PHP …“ );
besser ein
printf( „Restarting PHP …\n“ );
Die Ausgabe wirkt dann schöner :)
https://misterunknown.de
Warum nicht „su -c ’systemctl xxx restart'“?
…und wie war’s auf’m Breeze? :D
https://legacy.thomas-leister.de/ueber-mich-und-blog/
Sehr, sehr geil :) War jetzt zum 3. Mal dort und wurde nicht enttäuscht.
Freut mich :)
Also ich geh nicht mehr hin. Das war bei mir mehr oder weniger ein Heimspiel. Wurde mir aber irgendwann zu groß und stressig. Weiß nicht ob die das mittlerweile besser im Griff haben..
Verwende persönlich immer shc (https://en.wikipedia.org/wiki/Shc_the_shell_script_compiler) um mir meine shell scripts zu compilieren um darauf dann das sticky bit zu setzen. Ist vielleicht für manche einfacher wenn sie kein C können :)