Você precisa ser root para fazer o tipo de espionagem que o tcpflow e o tcpdump fazem. Então, você precisa de sudo
ou de um wrapper de raiz setuid.
Bem, tecnicamente, tudo o que você precisa é da capacidade CAP_NET_RAW
. Se você instalar o libcap2-bin
pacote¹, você pode usar o comando setcap
para criar um “setcap- CAP_NET_RAW
”wrapper em torno de tcpflow
, em vez de um wrapper setuid. Mas isso só ajuda a fazer com que uma falha de segurança no invólucro seja um pouco menos prejudicial (um usuário que obtém CAP_NET_RAW
de acesso provavelmente pode ganhar raiz com pouco esforço).
Você pode usar sudo
ou um wrapper raiz setuid para permitir que o user1 execute um comando como tcpflow -i eth0 tcp and \( src host 1.2.3.4 and src port 3000 or dst host 1.2.3.4 and src port 3000 \)
. Note que você não pode simplesmente deixar o user1 executar um comando tcpflow
arbitrário: isso permitiria ao usuário1 executar coisas como tcpflow -r … -r /path/to/foo
e ler (pelo menos parcialmente) /path/to/foo
com permissões de root.
Eu não acho que você seja decentemente capaz de permitir que o usuário especifique uma expressão para corresponder aos pacotes. Em vez de conceder permissões extras para executar tcpflow
, sugiro dar permissões extras para executar um comando fixo tcpdump
(escrevendo para stdout, deixe o usuário redirecionar para um arquivo, se necessário). Em seguida, o usuário pode executar tcpflow -r
para analisar tcpdump
output (mesmo em tempo real, por meio de um pipe).
Agora, para lo
, permita que user1 execute este comando exato:
tcpdump -i lo tcp
Para outras interfaces, acho que o seguinte comando seleciona as portas tcp 3000-3999 (mas faça testes extensivos para ter certeza):
tcpdump -i eth0 tcp and \( \
\( src host 1.2.3.4 and 'tcp[0:2] >= 3000' and 'tcp[0:2] <= 3999' \) or
\( dst host 1.2.3.4 and 'tcp[2:2] >= 3000' and 'tcp[2:2] <= 3999' \) \)
Substitua 1.2.3.4 pelo endereço IP associado à interface. Eu não tenho uma boa solução para oferecer se o endereço IP não for corrigido: se você ler de ifconfig
output ou de outra forma no início do script wrapper, ele estará aberto para uma condição de corrida.
Minha recomendação para um wrapper é não usar um shell script (não sei se algum shells do Debian é adequado para escrever scripts setuid - shells tendem a usar muitas variáveis de ambiente), mas sim Perl ( onde esse tipo de coisa é explicitamente suportado), assim:
#!/usr/bin/perl -T
exec '/usr/sbin/tmpdump', '-i', 'lo', 'tcp'
Torne o script um executável comum (modo 755) e permita que o usuário1 o execute através do sudo.
Para outras distribuições Linux: você precisa do kernel 2.6.24 ou superior e do comando setcap
.