Jak zezwolić użytkownikom na wykonanie skryptu bez ujawniania chronionych informacji

1

Biorąc pod uwagę, że użytkownik root ma pewne dane uwierzytelniające (powiedzmy klucz API) ustawiony w zmiennej środowiskowej, a mając nieuprzywilejowanego użytkownika Johna, jak mogę pozwolić Johnowi wykonać skrypt używa powiedział klucz API bez ryzyka wycieku wartości do Johna?

WTK
źródło
4
Wydaje mi się, że musiałbyś mieć jakiś program proxy działający pod użytkownikiem root, który wykonuje tę pracę dla John i przekazuje informacje, których chce John.
Mokubai
Hmm, @Mokubai wszelkie dalsze wskazówki i przykłady, na których mogę polegać? I jeszcze jedna uwaga - przeczytałem, że z jakimś mumbo-jumbo mogę sprawić, by skrypt był wykonywalny, ale nieczytelny, czy to działa w tym przypadku?
WTK
Naprawdę nie widzę żadnego sposobu na wykonanie skryptu wykonywalnego, ale nie do odczytania. Możesz uruchomić skrypt jako inny użytkownik, ale wtedy musisz podać użytkownikowi hasło lub sudo pozwolenie na uruchomienie, które uważam za trudne do uwierzenia, może być całkowicie bezpieczne, aby zapobiec prostemu czytaniu. Jeśli masz dowody przeciwne, to dobrze by było to pokazać. Nie mam żadnych przykładów, jak to zrobić, jest zbyt wiele sposobów i nie mamy pojęcia, jakie ograniczenia masz, poza tym, że nie wyciekłeś tego klucza.
Mokubai

Odpowiedzi:

2

Pytanie wydaje się być trochę nieostre.

  • Pytanie, jako taki, mówi o uzyskaniu wartości z „zmiennej środowiskowej superużytkownika” (tj. „główna zmienna środowiskowa”). Nie wiem nawet, co to znaczy. Mówisz, że John powinien uzyskać wartość ze środowiska użytkownika (nother), który jest zalogowany jako „root”, lub kto działa jako „root” su lub sudo? A może mówisz o środowisku a proces (prawdopodobnie proces w tle) działający jako „root”?

    Ale niezależnie od szczegółów, które masz na myśli, to brzmi jak klucz jest bardzo dynamiczny i ulotny. Ponieważ nie rozumiem, co to znaczy, Nie powiem, że to niemożliwe, ale brzmi to trudne.

  • Ale w komentarzu mówisz o tworzeniu skryptu wykonywalny, ale nieczytelny. Sugeruje to, że chcesz mieć klucz zakodowany w skrypcie, tak długo, jak użytkownicy inni niż root nie mogą go odczytać. Sugeruje to, że klucz jest bardzo statyczny, zmienia się tak rzadko, że jesteś skłonny zmodyfikować skrypt za każdym razem klucz się zmienia.

    U & amp; L ma długą wątek na ten temat: Czy skrypt może być wykonywalny, ale nie można go odczytać? Niestety większość odpowiedzi jest negatywnych, lub są to ugięcia, odchylenia lub obejścia, niektóre z nich działają lepiej niż inne. Na przykład, Santana sugeruje tworzenie wpisu w /etc/sudoers co pozwala Janowi na biegać skrypt z podwyższonymi uprawnieniami, nie będąc w stanie odczytać go jako siebie. Ale jeśli skrypt nie potrzebuje podwyższonych uprawnień (inne niż do uzyskania klucza), nie chcesz go uruchamiać z podwyższonymi uprawnieniami.

    Jednak dalej to powiązane pytanie (w Super User) , Przedstawiam zwariowany sposób na wykonanie skryptu, ale nie do odczytania owijając go w program C. Jak wyjaśniam w tej odpowiedzi, ta technika nie jest niezawodna; istnieją sposoby na wyciek informacji.

  • Najbardziej rozsądna / wiarygodna interpretacja, IMHO, jest to, że klucz jest przechowywany w pliku, którego John nie może odczytać. Tradycyjnym sposobem implementacji takich układów jest setUID i / lub setGID. ( sudo jest również przydatny.)

Oto przykład, jak to zrobić. Napisz taki program w C:

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

#define KEY_FILE         (odpowiednia nazwa ścieżki)  #define SCRIPT  (odpowiednia nazwa ścieżki)  Główny()
{
        PLIK * key_fp;
        klucz char [80];  (dostosuj odpowiednio)  gid_t gid;
        uid_t uid;
        char * args [10];  (dostosuj odpowiednio)  key_fp = fopen (KEY_FILE, "r");
        if (key_fp == NULL)
        {
                perror (KEY_FILE);
                exit (1);
        }  (Twój kod do czytania i sprawdzania poprawności  klawisz  )  fclose (key_fp);
        if (setenv („KEY”, key, 1)! = 0)
        {
                fprintf (stderr, "Problem z setenv (). n");
                exit (1);
        }
        gid = getgid ();
        uid = getuid ();
        // posługiwać się
        // if (setresgid (gid, gid, gid)! = 0 || setresuid (uid, uid, uid)! = 0)
        // jeśli są dostępne; Inaczej
        if (setregid (gid, gid)! = 0 || setreuid (uid, uid)! = 0)
        {
                fprintf (stderr, "Problem upuszczania uprawnień. n");
                exit (1);
        }
        args [0] = "nazwa skryptu";  (dostosuj odpowiednio)  args [1] = NULL;
        execv (SCRIPT, args);
        perror (SCRIPT);
        exit (1);
} 

Definiować KEY_FILE do pełnej ścieżki do pliku zawierającego klucz, i zdefiniuj SCRIPT do pełnej ścieżki do pliku zawierającego skrypt. Upewnij się, że John ma dostęp do odczytu skryptu, ale nie ma pliku klucza, i że nie ma dostępu do zapisu do żadnego z katalogów w żadnej ze ścieżek. Ułóż ten program, aby mógł odczytać plik klucza przez ustawienie go setUID i / lub setGID. Odczytuje klucz, wstawia go do środowiska, upuść uprawnienia i wykonaj skrypt. (Możesz zmodyfikować powyższy kod tak, że argumenty wiersza polecenia podane programowi przejść do skryptu.)

Jak wspomniano powyżej, skrypt zostanie uruchomiony z UID i GID Johna, ale z kluczem w środowisku. W niektórych systemach John może odczytać środowisko skryptu z /proc/ (pid_of_script) /otaczać lub z ps. Jeśli tak, warto mieć skrypt natychmiast skopiuj klucz do lokalnej (nieeksportowanej) zmiennej i odznacz KEY zmienna.

Skrypt prawdopodobnie będzie mógł przekazać klucz do programu

  • przez rurę (na przykład., printf "%s"  (kluczowa wartość) | (program) ),
  • poprzez dokument tutaj lub
  • przez sznurek tutaj.

Ryzyko związane z przekazaniem wartości przez środowisko jest wymienione powyżej. Unikaj przekazywania go jako parametru wiersza polecenia, jak to z pewnością można zobaczyć ps.

Jeśli chcesz sprawić, by program był uruchomiony sudo, być może będziesz musiał wprowadzić kod UID i GID Johna, bo sudo ustawia prawdziwe identyfikatory, a także efektywne.

G-Man
źródło