Não há nada no ambiente de processo convencional para tornar uma variável somente leitura, apenas os shells têm esse conceito para seu próprio ambiente / variáveis (os dois se sobrepõem de formas, mas devem ser entendidos como distintos) . O mesmo se aplica para as propriedades type como integer, array, function etc.
Você já pensou em usar um shell restrito, como rbash
?
Você pode definir rbash
para executar readonly TEST_ENV
) em seu script de inicialização. rbash
pode ser muito restritivo, mas aborda em grande parte as questões levantadas nos comentários.
O ambiente é uma parte de leitura / gravação de cada processo (veja aqui e aqui para detalhes), não apenas um processo pode gravar diretamente na parte de dados (via environ[]
), pode mudar os ponteiros para ele. Você pode fazer algo com isso (ou seja, mudar para uma página somente leitura) se for proficiente em montagem e puder encontrar o caminho em torno do código de inicialização crt
, mas não o recomendo; -)
Se houver comandos específicos que os usuários executam que devem ter um determinado ambiente, você poderá definir somente a execução de grupo e usar sudo
para definir as variáveis corretas (por exemplo, via /etc/environment
ou env_file
diretiva) e execute o comando como o grupo específico (preservando o uid). As versões recentes suportam noexec
na maioria das plataformas, o que pode ser usado para evitar a execução de um novo shell (embora possa quebrar programas que legitimamente fork()
e exec()
).
Como última opção, você pode usar LD_PRELOAD
e sua própria biblioteca para definir um ambiente controlado para alguns / todos os processos do usuário, agrupando as funções libc relevantes ( getenv() putenv()
etc.). O libfaketime faz exatamente isso para funções libc relacionadas ao tempo. Existe uma ferramenta menos conhecida chamada timetravel que faz semelhante, mas também ganchos setenv()
e getenv()
para manter o controle de LD_PRELOAD
em face da adversidade.
A abordagem mais robusta é filtrar as chamadas setenv() unsetenv() putenv()
(e possivelmente clearnv()
) para impedir a modificação e filtrar getenv()
para que sempre retorne o valor necessário (possivelmente de um arquivo). Essa abordagem não impedirá a manipulação direta da memória do ambiente via environ[]
, mas contanto que você esteja no controle de getenv()
, qualquer processo que dependa da API libc deve ver seu valor. bash
usa environ[]
diretamente quando inicializa, mas também chama getenv()
.