Dado que o usuário root tem algumas credenciais (digamos, uma chave de API) definidas em uma variável de ambiente, e dado um usuário sem privilégios John, como posso deixar John executar um script queusadisse a chave da API sem o risco de vazar seu valor para John?
Responder1
A questão parece um pouco fora de foco.
A questão,por si só, fala sobre como obter um valor de uma “variável de ambiente de superusuário” (ou seja, uma “variável de ambiente raiz”). Eu nem tenho certeza do que isso significa. Você está dizendo que John deveria obter o valor do ambiente de um (outro) usuário que está logado como “root” ou que está executando como “root” através de
su
ousudo
? Ou você está falando sobre o ambiente de umprocesso (provavelmente um processo em segundo plano) rodando como “root”?Mas, quaisquer que sejam os detalhes que você tenha em mente, parece que a chave é muito dinâmica e efêmera. Como não entendo o que isso significa, não direi que é impossível, mas parece difícil.
Mas então, em um comentário, você fala sobre tornar um script executável, mas não legível. Isso sugere que você deseja ter a chave codificada no script, desde que usuários não-root não possam lê-la. Isso sugere que a chave é muito estática, mudando tão raramente que você deseja modificar o script sempre que a chave for alterada.
U&Ltem um longo tópico sobre esse mesmo assunto: Um script pode ser executável, mas não legível? Infelizmente, a maioria das respostas é negativa ou são desvios, desvios ou soluções alternativas, algumas das quais funcionam melhor que outras. Por exemplo,Santana sugerecriando uma entrada
/etc/sudoers
que permite que Johncorrero script com permissões elevadas, embora não seja capaz de lê-lo como ele mesmo. Mas, se o script não precisar de permissões elevadas (exceto para obter a chave), você não deseja executá-lo com permissões elevadas.No entanto, emesta questão relacionada (no superusuário), apresento uma maneira desajeitada de tornar um script executável, mas não legível, envolvendo-o em um programa C. Como explico nessa resposta, esta técnica não é infalível; existem maneiras pelas quais as informações podem vazar.
A interpretação mais razoável/plausível, IMHO, é que a chave é mantida em um arquivo que John não consegue ler. A forma tradicional de implementar tais acordos é setUID e/ou setGID. (
sudo
também é útil.)
Aqui está um exemplo de como fazer isso. Escreva um programa em C como este:
#include <stdio.h> #include <stdlib.h> #define KEY_FILE (nome do caminho apropriado) #define SCRIPT (nome do caminho apropriado) principal() { ARQUIVO *key_fp; chave char[80]; (ajuste conforme apropriado) gid_t gid; uid_t uid; char *args[10]; (ajuste conforme apropriado) key_fp = fopen(KEY_FILE, "r"); se (key_fp == NULO) { erro(KEY_FILE); saída(1); } (seu código para ler e validarchave) fclose(key_fp); if (setenv("CHAVE", chave, 1) != 0) { fprintf(stderr, "Problema com setenv().\n"); saída(1); } gid = getgid(); uid = getuid(); // usar // if (setresgid(gid, gid, gid) != 0 || setresuid(uid, uid, uid) != 0) // se estiverem disponíveis; de outra forma if (setregid(gid, gid) != 0 || setreuid(uid, uid) != 0) { fprintf(stderr, "Problema ao eliminar privilégios.\n"); saída(1); } args[0] = "nomedoscript"; (ajuste conforme apropriado) args[1] = NULO; execv(SCRIPT, argumentos); erro(SCRIPT); saída(1); }
Defina KEY_FILE
o nome do caminho completo para o arquivo que contém a chave e defina SCRIPT
o nome do caminho completo para o arquivo que contém o script. Certifique-se de que John tenha acesso de leitura ao script, mas não ao arquivo-chave, e que ele não tenha acesso de gravação a nenhum dos diretórios em nenhum dos caminhos. Faça com que este programa seja capaz de ler o arquivo de chave tornando-o setUID e/ou setGID. Ele irá ler a chave, inseri-la no ambiente, eliminar privilégios e executar o script. (Você pode modificar o código acima para que os argumentos da linha de comando fornecidos ao programa sejam transmitidos ao script.)
Conforme dito acima, o script será executado com o UID e GID de John, mas com a chave no ambiente. Em alguns sistemas, pode ser possível que John leia o ambiente do script de ou com . Nesse caso, pode ser útil fazer com que o script copie imediatamente a chave para uma variável local (não exportada) e remova a configuração da variável./proc/(pid_of_script)/environ
ps
KEY
Provavelmente será seguro para o script passar a chave para um programa
- através de um tubo (por exemplo, ),
printf "%s" (key_value) | (program)
- através de um documento aqui, ou
- através de uma string aqui.
Os riscos de repassar o valor pelo meio ambiente são mencionados acima. Evite passá-lo como um parâmetro de linha de comando, pois isso definitivamente pode ser visto por ps
.
Se você quiser tornar o programa executável sudo
, pode ser necessário codificar o UID e o GID de John, porque sudo
define os IDs reais e também os efetivos.