
NO CLICK-ME THIS TIME :/
Este artigo foi publicado no blog do Colméia , no fórum do slackbr e no vivaolinux
e por fim público aqui
Como verificar as conexões abertas no seu Linux de várias maneiras
Estivemos com um problema em um projeto que precisava verificar se o serviço xdmcp estava aberto, porém ele não é um processo independente, ele fica interligado ao X, kdm, gdm, xdm, para tanto a solução mais cabível era procurar saber se a porta estava aberta na máquina.
Sim, talvez pudesse existir outras maneiras de resolver isso, mas esta se fez mais interessante. A clássica solução que me veio a cabeça foi usar o netstat, mas pensei em porque não ir mais a fundo e como resultado venho por este artigo mostrar algumas coisas que aprendi.
As formas que executei este processo foram:
- Geek hacker ninja style form – procura no proc pelas conexões abertas (mais interessante e a que mais aprendi);
- Status network – usa o comando de status de rede para listar;
- Open Files – Procura baseado nos arquivos abertos o que está ligado a porta.
Geek hacker ninja style form
A forma mais baixo nível e estilosa =], vamos aos arquivos de kernel analisar suas saídas, está é a base utilizada por programas como o netstat, o qual converte os dados deste e mostra com uma saída personalizada. Foi publicado um artigo antes explicando sobre a conversão de bases, então não vou abordar este assunto aqui.
O arquivo em questão utilizado é o /proc/net/tcp.
Exemplo de /proc/net/tcp:
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
0: 9E00A8C0:D3FD E1D7BCCD:1F4A 01 00000000:0003163C 00:00000000 00000000 1000 0 383991 1 cb042500 102 12 4 2 100
1: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 626508 1 c299db80 750 0 0 2 -1
Onde:
- sl: O número de identificador da linha.
- local_address: O endereço local e o número da porta do socket. O endereço local está codificado em little-endian em quatro seqüências de números em hexadecimal, isso significa que o byte mais importante é listado primeiro e você necessita fazer a inversão da ordem dos bytes para converter para o endereço de IP. O número da porta é um hexadecimal simples utilizado pelo programa.
- rem_address – O endereço remoto e o número da porta do socket. O endereço local está codificado em little-endian em quatro seqüências de números em hexadecimal, isso significa que o byte mais importante é listado primeiro e você necessita fazer a inversão da ordem dos bytes para converter para o endereço de IP. O número da porta é um hexadecimal simples.
- st: Status do socket (depois de muita busca encontrei onde estava o padrão de código daqui e o porque do valor ficar com 0A – segue tabela de referência no final).
- tx_queue rx_queue: O tamanho de transmissão e recebimento das filas de pacotes.
- tr tm->when: tr é o campo que indica se o medidor de tempo está ativo para este socket. Um valor zero indica que o medidor de tempo não está ativo. O tm->when indica tempo que o sock está sendo utilizado em jiffies (usado basicamente para debug).
- retrnsmt: Campo de informação interna do socket do kernel (usado basicamente para debug).
- uid: O uid do usuário dono da conexão.
- time-out: Campo de informação interna do socket do kernel (usado basicamente para debug).
- inode: Um número encriptado de identificação do socket para o sistema de arquivos do Linux (não encontrei qual é a criptografia utilizada aqui).
Achei a representação padrão do cat do arquivo /proc/net/tcp muito extensa, então refiz ela na horizontal para melhor explicar o exemplo acima e traduzi alguns dados:
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
0: 9E00A8C0:D3FD E1D7BCCD:1F4A 01 00000000:0003163C 00:00000000 00000000 1000 0 383991 1 cb042500 102 12 4 2 100
1: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 626508 1 c299db80 750 0 0 2 -1
sl : 0 – linha indicadora da primeira conexão
local_address: 9E00A8C0:D3FD – convertendo fica 192.168.0.158:151775
rem_address: E1D7BCCD:1F4A – convertendo fica 205.188.215.225:8010
st: 01 – TCP ESTABELISHED – conexão estabelecida
tx_queue rx_queue: 00000000:0003163C – fila de dados transmitidos
tm->when retrnsmt: 00:00000000 00000000 – dados utilizados para debug
uid: 1000 – id do usuário dono da conexão
timeout: 0 – dado utilizado para debug
inode: 383991 1 cb042500 102 12 4 2 100 – identificador criptografado
sl : 1 – linha indicadora da primeira conexão
local_address: 00000000:0016 – convertendo fica localhost:22
rem_address: 00000000:0000 – não tem ninguém conectado
st: 0A – TCP_LISTEN – escutando conexão
tx_queue rx_queue: 00000000:0003163C – fila de dados transmitida
tm->when retrnsmt: 00:00000000 00000000 – dados utilizados para debug
uid: 1000 – id do usuário dono da conexão
timeout: 0 – dado utilizado para debug
inode: 383991 1 cb042500 102 12 4 2 100 – identificador criptografado
Status network
Podemos ver as conexões abertas através do comando netstat. O mesmo é um programa de estatísticas de rede utilizado amplamente para este fim. Não tem muitos segredos e as informações que ele mostra são muito legíveis. Alguém percebeu a similaridade com um outro arquivo no modo que as informações aparecem?
# netstat -tl – lista as conexões abertas de tcp em modo de escuta
# netstat -t – lista as conexões tcp estabelecidas
# netstat -p – lista os programas que estão usando a conexão
# netstat –numeric-ports – não converte o número da porta para ser listado
# netstat –numeric-hosts – não converte o número de ip para nome do host
Comando que resolveu meu problema:
# netstat -t -l -p –numeric-ports
Open Files
Vendo as conexões abertas através do comando lsof. O comando lsof lista os arquivos abertos, através disto vamos procurar o arquivo aberto relacionado às portas tcp.
Obs.: Ele pode pegar muitas informações interessantes sobre os arquivos abertos, mas não é escopo deste artigo.
Sintaxe: lsof -i protocolo
Exemplo:
# lsof -i tcp
Tabela de dados para o status do socket – versão do kernel 2.6.21.5 Slackware Linux 12
| st status socket values |
| significado |
valor |
| TCP_ESTABLISHED |
01 |
| TCP_SYN_SENT |
02 |
| TCP_SYN_RECV |
03 |
| TCP_FIN_WAIT1 |
04 |
| TCP_FIN_WAIT2 |
05 |
| TCP_TIME_WAIT |
06 |
| TCP_CLOSE |
07 |
| TCP_CLOSE_WAIT |
08 |
| TCP_LAST_ACK |
09 |
| TCP_LISTEN |
0A |
| TCP_CLOSING |
0B |
| TCP_MAX_STATES |
0C |
Ambiente de teste
- Slackware 12.0
- kernel 2.6.21.5
Conclusão
Estas foram apenas algumas maneiras, devem ter mais. Espero que tenham gostado e que algum dia isto seja útil a alguém =], bom para mim foi um grande aprendizado.
(Desculpe qualquer erro de português :X)
Definições
jiffy – medida utilizada para representar o uso de uma tarefa em chamadas de interrupção no processador (medida em um Linux com kernel 2.6.13 em um Intel 386 é de 4 ms ou 1/250 avos de um segundo)
Referências