Não é possível definir o UID nos scripts do shell

14

Alguém pode me ajudar a descobrir o que está acontecendo aqui? Eu tenho algumas regras configuradas para controlar a contagem de pacotes. Quando executo o seguinte script como root:

#!/bin/bash
iptables -t mangle -xnvL

Recebo a saída que espero:

//snip
233203 199929802 MARK  //blah blah blah
//snip

No entanto, quero executar isso como parte dos cactos, que funcionam como apache. Agora o apache não pode executar o iptables, e é por isso que tenho o script. Eu o configurei como raiz SUID :

-rwsr-sr-x 1 root root   37 May 14 23:06 iptables_packet_report.sh

Mas então eu recebo esta saída:

server # sudo -u apache ./iptables_packet_report.sh
iptables v1.4.2: can't initialize iptables table `mangle': Table does not exist (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.

Obviamente meu kernel está bem, e o fato de eu estar rodando como não-root está atrapalhando algo, mas não entendo o porquê. Eu verifiquei o SUID com [a demonstração] ( http://en.wikipedia.org/wiki/Setuid#Demonstration) e confirmei que estava funcionando.

server # sudo -u apache ./printid
Real UID  = 81
Effective UID = 0
Real GID  = 81
Effective GID = 0

Meu objetivo final é obter a saída do iptables -t mangle -xnvL enquanto estiver rodando como apache, para que eu possa usar cactos para representar graficamente tudo isso.

Tom Ritter
fonte

Respostas:

16

Você não pode usar a raiz SUID para scripts de shell. Somente programas reais podem ser raiz SUID, os scripts de shell começam com "#!" e o intérprete teria que executar o SUID e isso não funciona por algum motivo que eu não sabia

Dê uma olhada no sudo e instale-o! Edite / etc / sudoerrs, adicione uma linha como esta:

www-data        ALL=NOPASSWD: /usr/local/sbin/iptables_packet_report.sh

Então apenas corra

sudo /usr/local/sbin/iptables_packet_report.sh

do seu código.

Não deve solicitar a senha, mas avaliar o processo automaticamente.

Tenho certeza de que suas mensagens de erro também aconteceriam se você su manualmente em www-data e execute manualmente

cristão
fonte
13

Como Christian indicou, meu problema era que eu estava tentando SUID em um script de shell. Como explicado aqui, configurar SUID em um script de shell é uma péssima idéia:

executar um script de shell no UNIX envolve um processo de duas etapas: quando o kernel determina que um script de shell está prestes a ser executado, ele primeiro inicia uma cópia SUID do interpretador de shell e, em seguida, o interpretador de shell começa a executar o script de shell. Como essas duas operações são executadas em duas etapas distintas, você pode interromper o kernel após a primeira etapa e alternar o arquivo que o interpretador de shell está prestes a executar. Dessa maneira, um invasor pode fazer com que o computador execute qualquer shell script de sua escolha

Por causa disso, muitas distribuições linux modernas ignoram os scripts do shell SUID, incluindo o gentoo que eu estava usando. Eu era capaz de editar o arquivo sudoers e fazê-lo funcionar.

Tom Ritter
fonte
Resposta fantástica!
Dave Cheney
Alguém sabe se isso é verdade para o Solaris 10?
Eric Johnson
2

Eu acho que a solução do christian é a melhor, mas se você realmente quiser, pode compilar o script usando shc e, em seguida, setuid root no programa compilado.

Kyle Brandt
fonte