selbst programmieren
selbst programmieren
moin moin ich möchte mal gerne wissen, was so die grundlagen sind die man braucht um sich selbst ein web interface zu schreiben. Also ist das insgesamt sehr schwer oder ist es noch relativ einfach zb einen cs server mittels webinterface zu restarten? atm kann ich nur php, aber was wäre sinnvoll noch zukönnen? oder reicht es komplett aus php zu können? Oder wie mache ich es das ich per php sämtliche befehle aufm server ausführen kann?
MfG
Nascar
MfG
Nascar
Re: selbst programmieren
Das machst Du so: http://www.php-faq.de/q/q-php-externes-programm.html Aber das Problem ist nicht, welche Befehle, sondern als welcher User.Nascar wrote:Oder wie mache ich es das ich per php sämtliche befehle aufm server ausführen kann?
Re: selbst programmieren
d.h für mich alle scripte die ich per system oä ausführe laufen dann als wwwrun oder halt der apache user
kann man evtl den user wechseln?
kann man evtl den user wechseln?
Re: selbst programmieren
man sudo
PayPal.Me/JoeUser ● FreeBSD Remote Installation
Wings for Life ● Wings for Life World Run
„If there’s more than one possible outcome of a job or task, and one
of those outcomes will result in disaster or an undesirable consequence,
then somebody will do it that way.“ -- Edward Aloysius Murphy Jr.
Wings for Life ● Wings for Life World Run
„If there’s more than one possible outcome of a job or task, and one
of those outcomes will result in disaster or an undesirable consequence,
then somebody will do it that way.“ -- Edward Aloysius Murphy Jr.
Re: selbst programmieren
Das ist korrekt.Nascar wrote:d.h für mich alle scripte die ich per system oä ausführe laufen dann als wwwrun oder halt der apache user
Naja, nicht einfach. Das würde ja den Sicherheitsüberlegungen für das System grundsätzlich zuwider laufen. Du kannst natürlich suexec hacken, sodaß es niedere User-ID Nummern akzeptiert (tut es normal grundsätzlich nicht) und dann einen vhost mit UID 0 aufsetzen. Das wäre jedoch ziemlich dumm.kann man evtl den user wechseln?
Oder du kannst einen suexec Account aufmachen für wwwrun. Das wäre auch dumm, aber weniger dumm. Insbesondere, wenn Du Filterregeln für die Argumente definierst.
Du kannst auch eine Queue aufmachen, etwa in einer MySQL Tabelle. Da schreibt dann Dein Webserver Requests rein, und ein Cronjob fischt die raus, und hinterlegt Resultate. Das wäre - je nach Implementation - wenig dumm bis sehr schlau. Wenn Du direkt Kommandos in der Tabelle hinterlegst, wäre das dumm. Wenn Du Befehle hinterlegst, die dann fest vordefinierte Kommandos auslösen ohne den Parametern in der MySQL Tabelle zu trauen, dann wäre das eher schlau.
So in etwa sehe ich das.
Re: selbst programmieren
isotopp das mit der mysql lösung hört sich interessant an ;) und das cronjob script könnte ich ja dann auch in php schreiben und im crontab des jeweiligen users starten
also:
Interface schreibt in die DB: server|teamspeak|restart|now
Crontab wird vom user teamspeak aufgerufen und führt php .... aus
in dieser php datei steht dann das er die zeile da oben auflöst und die commands mit system oä ausführt und den datenbank eintrag später löscht.
evtl kann man in die db noch schreiben das der server richtig restartet wurde
nur wie oft lässt man sonen cron aufrufen...
soweit richtig?
also:
Interface schreibt in die DB: server|teamspeak|restart|now
Crontab wird vom user teamspeak aufgerufen und führt php .... aus
in dieser php datei steht dann das er die zeile da oben auflöst und die commands mit system oä ausführt und den datenbank eintrag später löscht.
evtl kann man in die db noch schreiben das der server richtig restartet wurde
nur wie oft lässt man sonen cron aufrufen...
soweit richtig?
Re: selbst programmieren
Ganz genau!Nascar wrote:Interface schreibt in die DB: server|teamspeak|restart|now
Crontab wird vom user teamspeak aufgerufen und führt php .... aus
in dieser php datei steht dann das er die zeile da oben auflöst und die commands mit system oä ausführt und den datenbank eintrag später löscht.
evtl kann man in die db noch schreiben das der server richtig restartet wurde
Cron kann nur einmal pro Minute. Wenn Du öfter brauchst, mußt Du einen eigenen Dauerläufer schreiben, der dann bei Bedarf nachguckt. Bedarf kann man auch verschiedene Weisen signalisieren, die aber mit PHP alle nicht einfach sind (Signal, Message, select auf fd und so weiter).nur wie oft lässt man sonen cron aufrufen...
-
Roger Wilco
- Posts: 5923
- Joined: 2004-05-23 12:53
Re: selbst programmieren
Ich finde das polling durch einen Cronjob, der jede Minute läuft nicht sonderlich elegant. Wieso sollte die Aktion nicht direkt durch die Benutzereingabe (natürlich erst nach einer Plausibilitätsprüfung) getriggert werden? Ob ich jetzt die Kommandos erst in eine Queue schreibe und durch ein Skript, das jede Minute läuft, wieder auslesen und umsetzen lasse, oder ob ich die Kommandos direkt nach der Aktion im richtigen Kontext ausführe (z. B. durch einen Systemaufruf im PHP-Skript und sudo), macht im Endeffekt keinen Unterschied. Die Eingabe muß in jedem Fall geprüft werden. Wieso sollte ich dann noch den "Umweg" über die externe Queue und ein zusätzliches Skript nehmen?
-
rootmaster
- Posts: 483
- Joined: 2002-04-28 13:30
- Location: Hannover
Re: selbst programmieren
ich denke, dass eingaben, die direkt durch priviligierte prozesse ausgeführt werden, immer - im webkontext - dumm sind (weil hochgefährlich).. unabhängig ob über queues oder queries. aber genau so war es ja imho nicht angedacht ;)Roger Wilco wrote:Ob ich jetzt die Kommandos erst in eine Queue schreibe und durch ein Skript, das jede Minute läuft, wieder auslesen und umsetzen lasse, oder ob ich die Kommandos direkt nach der Aktion im richtigen Kontext ausführe (z. B. durch einen Systemaufruf im PHP-Skript und sudo), macht im Endeffekt keinen Unterschied.
generell braucht man einen "kontextswitch" von einem unpriviligierten prozess zu einem priviligierten.
die angeführte lösung mit einem durch cron getriggerten root-skript ist eigentlich eine lösung, wie sie zum beispiel confixx macht. es werden flags und daten in tabellen geschrieben, die das skript zu definierten aktionen im root kontext veranlassen. elegant ist das sicher nicht, aber eine einfache lösung ;)
eleganter fände ich es zum beispiel, einen daemon laufen zu lassen, dem die daten (nicht kommandos) über einen unix socket übergeben werden. der startet dann definierte aktionen mit definiertem user kontext und ressourcen über einen wrapper mit CAP_SETUID.
"back to the roots"
Re: selbst programmieren
moin moin,
@ rootmater
wenn ich könnte würde ich einen solchen prozess selbst schreiben, aber ich denke ich hab da nicht die nötigen programmier kenntnisse in anderen sprachen als php.
oder kann man einen solchen prozess als shell script schreiben und dieses dann über den inetd anssprechen? also auf einem bestimmten port?
Wenn ja gibt es da evtl beispiele für?
MfG
Nascar
@ rootmater
wenn ich könnte würde ich einen solchen prozess selbst schreiben, aber ich denke ich hab da nicht die nötigen programmier kenntnisse in anderen sprachen als php.
oder kann man einen solchen prozess als shell script schreiben und dieses dann über den inetd anssprechen? also auf einem bestimmten port?
Wenn ja gibt es da evtl beispiele für?
MfG
Nascar
Re: selbst programmieren
Polling ist auch nicht elegant. Es ist hier aber auch nicht der Punkt. Es geht hier um zwei Dinge.Roger Wilco wrote:Ich finde das polling durch einen Cronjob, der jede Minute läuft nicht sonderlich elegant. Wieso sollte die Aktion nicht direkt durch die Benutzereingabe (natürlich erst nach einer Plausibilitätsprüfung) getriggert werden?
Das Erste ist Rechteminimierung - wir wollen so viel als möglich ohne Privilegien tun, und wir wollen insbesondere die Prüfung aller Parameter und alle UI-Sachen ohne Rechte tun.
Das Zweite ist ist, den privilegierten Bereich sauber zu halten, also dort nix zu verarbeiten, was eine direkte Benutzereingabe ist. Das gezeigte Beispiel war schon ganz gut. Dort wurde der Name einer Tätigkeit ("Teamspeak restarten") transportiert und nicht ein Pfadname, der so direkt in eine system()-Anweisung einfliessen kann. Auf der privilegierten Seite existiert dann eine statische Zuordnung von Namen und Kommandos
Code: Select all
$jobs = array("Teamspeak restarten" => "/usr/local/bin/restart-teamspeak");Die MySQL-Queue hat den Vorteil, daß man so auch gleich einen Paßwortprüfungsmechanismus hat. Man speichert in der unprivilegierten Seite einfach gar keine Paßworte, sondern recht die Benutzer-Usernamen und Paßworte einfach direkt ins mysql_connect() weiter. Die Rechte im MySQL setzt man nun so auf, daß diese User gar nichts machen können, außer vielleicht eine Stored Procedure enqueue() aufzurufen, die mit SQL SECURITY DEFINER läuft (also mit den Rechten des Autors von enqueue(), nicht mit den Rechten des Aufrufers von enqueue()). In enqueue() schreibt man das übergebene Kommando in die Queue-Tabelle und hinterlegt dabei zwangsweise auch session_user() (das ist der Username, mit dem man sich angemeldet hat, current_user() ist in einer SQL SECURITY DEFINER Prozedur der User, der die Prozedur geschrieben hat).
Auf dem privilegierten Ende der Queue kann man so den Request und wer ihn aufgegeben hat entnehmen, in ein Kommando umwandeln und das Kommando mit Privilegien ausführen, das alles in einer zweiten Result-Tabelle loggen und an die GUI zurückgeben.
Die Tabellen haben dabei eine ganze Reihe von Vorteilen - Datenbanken lösen einem hier das Locking-Problem, man kann atomar einen Job als "eingereiht, wartend", "in Bearbeitung", "gelöscht", "abgearbeitet" und "manuell pausiert" markieren ohne sich den Wolf zu programmieren. Man hat außerdem den ganzen Kram sofort asynchron (die GUI hakt nie!) und persistent (die Resultate und das Log stehen für einen Audit bequem zur Verfügung). Und es skaliert halt schön...
Das einzig Unschöne ist, da hast Du Recht, das Polling. Das kann man vermeiden, indem man in irgendeiner Weise vom unprivilegierten Teil in den privilegierten Teil signalisiert, und dafür gibt es eine Reihe von Mechanismen - leider sind die meisten rein mit PHP ein wenig hakelig zu bedienen.
Synchron, kein Locking, kein Logging und eine Shell auf dem Transportweg, also möglicherweise EscapeShellCmd()-Probleme. Und die Frage, wie Du den Aufrufer authentisierst - die Möglichkeit mit den MySQL-Usern macht es extrem leicht, komplett ohne Paßworte in den Scripten auszukommen.Ob ich jetzt die Kommandos erst in eine Queue schreibe und durch ein Skript, das jede Minute läuft, wieder auslesen und umsetzen lasse, oder ob ich die Kommandos direkt nach der Aktion im richtigen Kontext ausführe (z. B. durch einen Systemaufruf im PHP-Skript und sudo), macht im Endeffekt keinen Unterschied.
-
Roger Wilco
- Posts: 5923
- Joined: 2004-05-23 12:53
Re: selbst programmieren
Das ist durchaus eine Ã?berlegung wert, wobei du mit dem Daemon wieder eine Komponente mehr hast, die Fehler enthalten kann.rootmaster wrote:eleganter fände ich es zum beispiel, einen daemon laufen zu lassen, dem die daten (nicht kommandos) über einen unix socket übergeben werden. der startet dann definierte aktionen mit definiertem user kontext und ressourcen über einen wrapper mit CAP_SETUID.
Ja. Die Ein-/Ausgabe läuft aus Sicht des Skripts über stdin und stdout, wenn du es über (x)inetd einbindest. In xinetd.conf(5) stehen am Ende einige Beispiele dazu.Nascar wrote:oder kann man einen solchen prozess als shell script schreiben und dieses dann über den inetd anssprechen? also auf einem bestimmten port?
Ich wollte auch keineswegs darauf hinaus, dass man die Benutzereingaben direkt an einen Systemaufruf durchreicht.isotopp wrote:Dort wurde der Name einer Tätigkeit ("Teamspeak restarten") transportiert und nicht ein Pfadname, der so direkt in eine system()-Anweisung einfliessen kann. Auf der privilegierten Seite existiert dann eine statische Zuordnung von Namen und Kommandos
Mein Verständnisproblem(?) ist folgendes: Wieso sollte es einen gravierenden Unterschied ausmachen, ob ich ein Pseudokommando "Starte teamspeak" mit einem zusätzlichen Skript aus einer Queue (z. B. die von dir genannte MySQL-DB) auslese oder dies direkt aus einem Formular übernehme? Die statische Zuordnung von Pseudobefehl <-> tatsächlicher Befehl kann ich in beiden Varianten nutzen.
Synchronizität und Locking sind ein Problem, wenn kein (wie von rootmaster vorgeschlagen) Daemon läuft, der beides übernimmt. Aber Logging ist sicherlich problemlos machbar (wie detailliert hättens denn gerne?) und wie schon geschrieben, würde man sicherlich die Benutzereingaben nicht ungeprüft übernehmen (Pseudokommandos, siehe oben).isotopp wrote:Synchron, kein Locking, kein Logging und eine Shell auf dem Transportweg, also möglicherweise EscapeShellCmd()-Probleme.
Naja, das kann auch schon im Backend der GUI passieren. Ein unberechtigter Nutzer darf erst gar keinen Job anlegen.isotopp wrote:Und die Frage, wie Du den Aufrufer authentisierst - die Möglichkeit mit den MySQL-Usern macht es extrem leicht, komplett ohne Paßworte in den Scripten auszukommen.
