So ermöglichen Sie Benutzern die Ausführung eines Skripts, ohne geschützte Informationen preiszugeben

So ermöglichen Sie Benutzern die Ausführung eines Skripts, ohne geschützte Informationen preiszugeben

Wenn der Root-Benutzer einige Anmeldeinformationen (z. B. einen API-Schlüssel) in einer Umgebungsvariable festgelegt hat und der nicht privilegierte Benutzer John ist, wie kann ich John ein Skript ausführen lassen, dasVerwendetbesagten API-Schlüssel, ohne das Risiko, dass sein Wert an John weitergegeben wird?

Antwort1

Die Frage scheint etwas unkonzentriert zu sein.

  • Die Frage,an sich, spricht davon, einen Wert aus einer „Superuser-Umgebungsvariable“ (also einer „Root-Umgebungsvariable“) abzurufen. Ich bin mir nicht einmal sicher, was das bedeutet. Meinen Sie, dass John den Wert aus der Umgebung eines (anderen) Benutzers abrufen soll, der als „Root“ angemeldet ist oder der als „Root“ über suoder läuft sudo? Oder sprechen Sie von der Umgebung einesVerfahren (wahrscheinlich ein Hintergrundprozess), der als „Root“ ausgeführt wird?

    Aber egal, welche Details Sie im Sinn haben, es klingt, als wäre der Schlüssel sehr dynamisch und flüchtig. Da ich nicht verstehe, was das bedeutet, werde ich nicht sagen, dass es unmöglich ist, aber es klingt schwierig.

  • Aber dann sprechen Sie in einem Kommentar davon, ein Skript ausführbar, aber nicht lesbar zu machen. Das lässt darauf schließen, dass Sie bereit sind, den Schlüssel fest in das Skript zu codieren, solange Nicht-Root-Benutzer ihn nicht lesen können. Das lässt darauf schließen, dass der Schlüssel sehr statisch ist und sich so selten ändert, dass Sie bereit sind, das Skript jedes Mal zu ändern, wenn sich der Schlüssel ändert.

    U&Lhat einen langen Thread zu genau diesem Thema: Kann ein Skript ausführbar, aber nicht lesbar sein?  Leider sind die meisten Antworten negativ oder es handelt sich um Ablenkungen, Umleitungen oder Umgehungen, von denen einige besser funktionieren als andere. Zum Beispiel:Santana empfiehlteinen Eintrag zu erstellen, /etc/sudoers der es John ermöglicht,laufendas Skript mit erhöhten Berechtigungen ausführen, ohne es als er selbst lesen zu können. Wenn das Skript jedoch keine erhöhten Berechtigungen benötigt (außer zum Abrufen des Schlüssels), möchten Sie es nicht mit erhöhten Berechtigungen ausführen.

    Dochdiese verwandte Frage (auf Super User)stelle ich eine umständliche Methode vor, ein Skript ausführbar, aber nicht lesbar zu machen, indem man es in ein C-Programm einbindet. Wie ich in dieser Antwort erkläre, ist diese Technik nicht narrensicher; es gibt Möglichkeiten, wie Informationen nach außen dringen können.

  • Die vernünftigste/plausibelste Interpretation ist meiner Meinung nach, dass der Schlüssel in einer Datei gespeichert ist, die John nicht lesen kann. Die traditionelle Art, solche Vereinbarungen zu implementieren, ist setUID und/oder setGID. ( sudoist auch nützlich.)

Hier ist ein Beispiel dafür. Schreiben Sie ein C-Programm wie dieses:

#include <stdio.h>
#include <stdlib.h>

#Schlüsseldatei definieren        (entsprechender Pfadname)
#define-SKRIPT          (entsprechender Pfadname)

hauptsächlich()
{
        DATEI *key_fp;
        Zeichentaste[80];        (ggf. anpassen)
        gid_t gid;
        uid_t Benutzerkennung;
        char *args[10];      (ggf. anpassen)

        key_fp = fopen(SCHLÜSSELDATEI, "r");
        wenn (key_fp == NULL)
        {
                perror(SCHLÜSSELDATEI);
                Ausgang (1);
        }
        (Ihr Code zum Lesen und ValidierenSchlüssel)
        fclose(Schlüssel_fp);
        wenn (setenv("SCHLÜSSEL", Schlüssel, 1) != 0)
        {
                fprintf(stderr, "Problem mit setenv().\n");
                Ausgang (1);
        }
        gid = getgid();
        uid = getuid();
        // verwenden
        // wenn (setresgid(gid, gid, gid) != 0 || setresuid(uid, uid, uid) != 0)
        // wenn sie verfügbar sind, andernfalls
        wenn (setregid(gid, gid) != 0 || setreuid(uid, uid) != 0)
        {
                fprintf(stderr, "Problem beim Löschen von Berechtigungen.\n");
                Ausgang (1);
        }
        args[0] = "Skriptname";     (ggf. anpassen)
        args[1] = NULL;
        execv(SCRIPT, Argumente);
        perror(SKRIPT);
        Ausgang (1);
}

Definieren Sie KEY_FILEden vollständigen Pfadnamen der Datei, die den Schlüssel enthält, und SCRIPTden vollständigen Pfadnamen der Datei, die das Skript enthält. Stellen Sie sicher, dass John Lesezugriff auf das Skript, aber nicht auf die Schlüsseldatei hat, und dass er keinen Schreibzugriff auf die Verzeichnisse in den Pfaden hat. Sorgen Sie dafür, dass dieses Programm die Schlüsseldatei lesen kann, indem Sie es auf setUID und/oder setGID setzen. Es wird den Schlüssel lesen, ihn in die Umgebung einfügen, die Berechtigungen löschen und das Skript ausführen. (Möglicherweise möchten Sie den obigen Code so ändern, dass Befehlszeilenargumente, die dem Programm übergeben werden, an das Skript weitergegeben werden.)

Wie oben angegeben wird das Skript mit Johns UID und GID ausgeführt, aber mit dem Schlüssel in der Umgebung. Auf einigen Systemen kann John die Umgebung des Skripts möglicherweise von oder mit lesen . In diesem Fall kann es hilfreich sein, wenn das Skript den Schlüssel sofort in eine lokale (nicht exportierte) Variable kopiert und die Variable aufhebt./proc/(pid_of_script)/environpsKEY

Es ist wahrscheinlich sicher, wenn das Skript den Schlüssel an ein Programm übergibt

  • durch ein Rohr (zB ),printf "%s" (key_value) | (program)
  • über ein Here-Dokument oder
  • durch einen Here-String.

Die Risiken der Wertübergabe über die Umgebung sind oben erwähnt. Vermeiden Sie die Übergabe als Befehlszeilenparameter, da dies definitiv von erkannt werden kann ps.

Wenn Sie das Programm über ausführen möchten sudo, müssen Sie möglicherweise Johns UID und GID fest codieren, da sudosowohl die tatsächlichen als auch die effektiven IDs festgelegt werden.

verwandte Informationen