como executar a tarefa setuid corretamente?

2

Supondo que haja um site php e eu quero bloquear um ip no nível do firewall baseado na execução do código do site. O site é executado sob um usuário não raiz.

Eu ia passar o IP do código do site para um script (gravável apenas para o root) como

#!/bin/bash
function validate_ip()
{ ... code here ...}
if validate_ip $1; then 
    /usr/sbin/iptables -I INPUT -s $1 -j DROP
    echo 'blocked'; 
else 
    echo 'bad IP $1'; 
fi

usando bit suid. Eu quero adicionar validação adicional de IP para evitar XSS e outras coisas ruins (considere paranóia se você quiser), então não queira permitir que o site chame o iptables diretamente.

O script não funciona can't initialize iptables table 'filter': Permission denied (you must be root) porque o bash descarta o bit suid

Existe uma solução alternativa: allow iptables no sudo mas não acho seguro. Não tenho tempo / possibilidade de desenvolver / comprar um binário que faça a tarefa. Um invólucro binário sugerido em torno do script, mas eu hesito, talvez haja uma maneira melhor?

Então, a pergunta é: como posso permitir que o aplicativo não-raiz bloqueie o ip no firewall do iptables de maneira segura?

    
por Putnik 21.09.2017 / 23:00

1 resposta

4

Em vez de fazer o seu script bash suid root, execute o seu script bash através do sudo. Como um benefício colateral, isso também permite que você bloqueie facilmente quem pode executar seu script como root e também os argumentos passados. Você poderia, por exemplo, permitir apenas:

phpuser ALL=(root) NOPASSWD: /usr/local/sbin/your-script [0-9][0-9][0-9].[0-9][0-9][0-9].[0-9][0-9][0-9].[0-9][0-9][0-9]

certifique-se de que seu script PHP sempre formata cada octeto de endereço IP como três dígitos.

Se for muito difícil ter o sudo chamada PHP (o que não deveria ser!), você pode fazer o script fazê-lo sozinho, com algo como:

#!/bin/sh

[ "$(id -u)" -eq 0 ] || exec sudo -- "$0" "$@"
# rest of script here

(Eu não estou inteiramente certo de que o iptables ficará satisfeito com os 0s iniciais, se não você pode despir-se).

PS: Por favor, cite suas variáveis em seu script de shell:

if validate_ip "$1"; then 
    /usr/sbin/iptables -I INPUT -s "$1" -j DROP
    # ⋮
    
por 21.09.2017 / 23:42