Fundo
Estou executando o BusyBox no servidor remoto.
Eu tenho um script bash que faz duas coisas:
1. via ssh, inicia um subprocesso para monitorar o tráfego tcp usando o comando tcpdump. Salve os resultados em um arquivo - na máquina remota ou na máquina local. Tentei ambos.
2. inicia um segundo subprocesso para gerar tráfego TCP.
Fragmento de código:
#html_tcpdumpfile="$(ssh remotemachine.mydomain.net \"mktemp\")"
html_tcpdumpfile=$(mktemp)
test_steps=(
#"{ ssh remotemachine.mydomain.net \"timeout -t 20 tcpdump -nvi eth0 port 5060 > "$html_tcpdumpfile" \" ; }"
"{ ssh remotemachine.mydomain.net \"timeout -t 20 tcpdump -i eth0 port 5060 \"> $html_tcpdumpfile; }"
"{ ssh remotemachine.mydomain.net \"timeout -t 15 cat /tmp/htmlemail.txt | /etc/postfix/process_email.py \"; }"
)
pids=()
for index in ${!test_steps[@]}; do
(echo "${test_steps[$index]}" | bash) &
pids[${index}]=$!
echo "$pids[${index}] is the pid"
done
#shouldn't really need this because of the timers but... just in case...
for pid in ${pids[*]};
do
wait $pid;
done;
# ============ ANALYZE TEST RESULTS
echo "========== html_tcpdumpfile CONTENTS ============="
cat $html_tcpdumpfile
echo "========== html_tcpdumpfile CONTENTS ============="
Problema
Às vezes, o comando tcpdump não captura nada e, outras vezes, sim. Não há mensagens de erro quando há falha na captura.
O que eu tentei até agora
Como você pode ver, tentei alterar a localização do arquivo dump entre a máquina remota e a local. Isso não parece fazer diferença.
Eu provei que o tráfego TCP SEMPRE é gerado ... toda vez que executo o script porque tenho outra sessão ssh aberta e posso ver o tráfego sendo gerado. É que meu script falha intermitentemente em capturá-lo.
Tentei aumentar o valor do tempo limite na sessão tcp para algo enorme para garantir que eu desse tempo suficiente. Mas não acho que seja esse o problema.
Qualquer sugestão seria apreciada. Obrigado.
EDITAR 1
Tentei introduzir um sono entre o lançamento de cada subprocesso:
pids=()
for index in ${!test_steps[@]}; do
(echo "${test_steps[$index]}" | bash) &
sleep 5
pids[${index}]=$!
echo "$pids[${index}] is the pid"
done
Mas isso também não faz diferença.
EDITAR 2
Alterei o comando tcpdump para ficar assim:
test_steps=(
"{ ssh remotemachine.mydomain.net \"timeout -t 30 tcpdump -nlc 100 -i eth0 port 5060 \"> $rtf_tcpdumpfile; }"
"{ ssh remotemachine.mydomain.net \"timeout -t 20 tail -f /var/log/messages \" > $syslog; }"
"{ ssh remotemachine.mydomain.net \"timeout -t 15 cat /tmp/htmlemail.txt | /etc/postfix/process_email.py \"; }"
)
O tcpdump ainda falha na captura de forma intermitente, mas... o interessante é que o syslog sempre é capturado com sucesso. (o script python realmente grava no syslog quando é invocado e assim posso ver/provar que o script está funcionando)
Em primeiro lugar, se você estiver lidando com um dispositivo/iOT com espaço limitado, eu lidaria com a saída no lado da chamada, ou seja, usando o > após os
ssh
comandos como emQuanto a
tcpdump
eu não mataria como política o tempo todo, arriscando perder buffers. Você pode não ter produzido talvez por causa disso.Eu colocaria um limite nos pacotes capturados. Eu também tentaria não resolver o DNS. Como em, para capturar 100 pacotes:
Ao armazenar o arquivo de captura no sistema local, você deve executar apenas
cat
localmente e não remotamente e localmente.Da mesma forma, quando você está executando os dois remotamente
tcpdump
,cat
está iniciando os dois ao mesmo tempo, e o remoto e o localcat
não terão nada para mostrar.Seguindo a sugestão de @MarkPlotnick, também adicionei
-l
paratcpdump
torná-lo em buffer de linha. Isso pode evitar a necessidade da-c
opção. Eu usaria os dois.Então, eu mudaria esse script para:
Ou talvez nem precisemos criar explicitamente um arquivo temporário:
Por fim, aconselho excluir todos os arquivos temporários criados, especialmente no lado remoto.
PS: o OP mencionado nos comentários do sistema remoto é o BusyBox e, como tal, as
timeout
opções são diferentes das docoretutils
pacote. Eu também edito a pergunta para mencionar o BusyBox.