A questão parece ser um pouco desfocada.
-
A questão, per se, fala sobre como obter um valor de uma "variável de ambiente super usuário" (isto é, uma "variável de ambiente raiz"). Eu nem tenho certeza do que isso significa. Você está dizendo que João deveria pegar o valor do ambiente de um usuário (nother) que está logado como “root”, ou quem está executando como "root" por meio de
su
ousudo
? Ou você está falando sobre o ambiente de um processo (provavelmente um processo em segundo plano) rodando como "root"?Mas, quaisquer detalhes que você tenha em mente, Isso soa como a chave é muito dinâmica e efêmera. Desde que eu não entendo o que isso significa, Não vou dizer que é impossível, mas parece difícil.
-
Mas, em um comentário, você fala sobre criar um script executável mas não legível. Isso sugere que você está disposto a ter a chave codificada no script, contanto que usuários não-root não possam lê-lo. Isso sugere que a chave é muito estática, mudando tão raramente que você está disposto a modificar o script toda vez que a chave muda.
U & L tem um longo tópico sobre este mesmo tópico: Um script pode ser executável, mas não legível? Infelizmente, a maioria das respostas está no negativo, ou são desvios, desvios ou soluções alternativas alguns dos quais funcionam melhor que outros. Por exemplo, Santana sugere a criação de uma entrada em
/etc/sudoers
que permite que o John execute o script com permissões elevadas, apesar de não ser capaz de lê-lo como ele mesmo. Mas, se o script não precisar de permissões elevadas (diferente de obter a chave), você não quer executá-lo com permissões elevadas.No entanto, em esta pergunta relacionada (em Superusuário) , Eu apresento uma maneira desajeitada de tornar um script executável, mas não legível envolvendo-o em um programa em C. Como explico nessa resposta, essa técnica não é infalível; existem maneiras de vazar informações.
-
A interpretação mais razoável / plausível, IMHO, é que a chave é mantida em um arquivo que John não consegue ler. A maneira tradicional de implementar tais arranjos é setUID e / ou setGID. (
sudo
também é útil.)
Veja um exemplo de como fazer isso. Escreva um programa em C como este:
#include <stdio.h> #include <stdlib.h> #define KEY_FILE (appropriate pathname) #define SCRIPT (appropriate pathname) main() { FILE *key_fp; char key[80]; (adjust as appropriate) gid_t gid; uid_t uid; char *args[10]; (adjust as appropriate) key_fp = fopen(KEY_FILE, "r"); if (key_fp == NULL) { perror(KEY_FILE); exit(1); } (your code to read and validate key) fclose(key_fp); if (setenv("KEY", key, 1) != 0) { fprintf(stderr, "Problem with setenv().\n"); exit(1); } gid = getgid(); uid = getuid(); // use // if (setresgid(gid, gid, gid) != 0 || setresuid(uid, uid, uid) != 0) // if they’re available; otherwise if (setregid(gid, gid) != 0 || setreuid(uid, uid) != 0) { fprintf(stderr, "Problem dropping privileges.\n"); exit(1); } args[0] = "scriptname"; (adjust as appropriate) args[1] = NULL; execv(SCRIPT, args); perror(SCRIPT); exit(1); }
Defina KEY_FILE
como o nome completo do caminho para o arquivo que contém a chave.
e defina SCRIPT
para o nome completo do caminho para o arquivo que contém o script.
Certifique-se de que John tenha acesso de leitura ao script, mas não ao arquivo de chave,
e que ele não tem acesso de gravação a nenhum dos diretórios em nenhum dos dois caminhos.
Organize para este programa poder ler o arquivo de chaves
fazendo-o setUID e / ou setGID.
Ele vai ler a chave, inseri-lo no ambiente,
abandone os privilégios e execute o script.
(Você pode querer modificar o código acima
de modo que os argumentos da linha de comando dados ao programa
passar para o script.)
Conforme mencionado acima, o script será executado com o UID e o GID de John,
mas com a chave no ambiente.
Em alguns sistemas, é possível que John leia o ambiente do roteiro
de /proc/(pid_of_script)/environ
ou com ps
.
Se assim for, pode ser útil ter o script
copie imediatamente a chave para uma variável local (não exportada)
e desmarque a variável KEY
.
Provavelmente, será seguro que o script passe a chave para um programa
- através de um cano
(por exemplo,
printf "%s" (key_value) | (program)
), - através de um documento aqui ou
- através de uma string aqui.
Os riscos de passar o valor pelo ambiente são mencionados acima.
Evite passá-lo como um parâmetro de linha de comando,
como isso pode definitivamente ser visto por ps
.
Se você quiser que o programa seja executado por meio de sudo
,
pode ser necessário codificar o UID e o GID de John,
porque sudo
define os IDs reais e os efetivos.