terça-feira, 8 de julho de 2014

Monitorando conexões TCP usando /proc/net/tcp

Podemos listar todas as conexões TCP , via IPv4 , através do arquivo /proc/net/tcp, como exemplo,
vou deixar o netcat escutando na porta 5555:

$ nc -lvvp 5555

e em outro terminal eu me conecto a porta 5555:

$ nc 127.0.0.1 5555

Agora se eu executar no terminal o comando

$ ss -atn -4

todas as conexões TCP serão listadas , não haverá resolução de nome (só o IP e a porta serão mostrados) e só conexões via IPv4 serão listadas.

$ ss -atn -4






$ cat /proc/net/tcp:







Através do arquivo /proc/net/tcp , consigo obter as mesmas informações usando ss, netstat ou qualquer outra ferramenta, isso porque essas ferramentas obtêm as informações de rede através dos arquivos presentes no diretório /proc/net.

Os dados são mostrados em colunas:

sl -> O número da linha referente a conexão.
local_address -> O endereço de IP local.
rem_address -> Endereço de IP Remoto.
st -> Estado do socket.
tx_queue:rx_queue -> O tamanho da transmissão e recepção de filas.
tr:tm->when -> O campo tr indica se o socket tem um tempo limite para ficar ativo , 0 significa que não existe tempo limite.tm->when indica quanto tempo falta até o socket se tornar invalido.
retrnsmt -> não é usado.
uid -> ID do usuario responsavel pelo socket
time-out -> não é usado.
inode -> mais informações.

Local_address e rem_address estão codificados em hexadecimal , precisamos converte-los em decimal para
obtermos um endereço de IP, mas antes disso , precisamos de inverter os pares hexadecimais, por exemplo:

0100007F:1768 se tornaria 7F000001:1768

A porta não precisa ser invertida , agora no endereço IP é só pegar os números hexadecimais e converto-los em decimal:

7F(16) = 127(10)
00(16) = 0(10)
00(16) = 0(10)
01(16) = 1(10)

No final temos : 127.0.0.1
e a porta:
1768(16) = 5992(10)

O estado do socket , vai de 1 a 11 , no arquivo /proc/net/tcp ele é exibido em hexadecimal , ou seja , vai de 1 a B, significado de cada estado:

Fonte:
$ cat /usr/src/*-common/include/net/tcp_states.h
git.kernel.org

Na ultima linha do arquivo /proc/net/tcp , podemos extrair a seguinte informação:

endereço local: 127.0.0.1:5992
endereço remoto: 127.0.0.1:45036
estado do socket: ESTABLISHED

A mesma informação que foi extraída usando o comando ss.
O que foi visto aqui também pode ser aplicado para conexões UDP, basta usar o arquivo /proc/net/udp.

Escrevi um script em perl para monitorar as conexões:

2 comentários: