systemadmin.es > Storage > Sistemas de ficheros > Buscar el puerto de escucha mediante el /proc

Buscar el puerto de escucha mediante el /proc

Mediante el /proc podemos obtener la misma información que obtenemos con muchos binarios, únicamente que tenemos la información más esparcida y sin tratar. Vamos a ver cómo obtener la información de conexiones y puertos en escucha mediante el /proc.

Vamos a usar de ejemplo un netcat escuchando al puerto 1234:

$ nc -l 1234

Una vez conocido el PID, mediante el listado de descriptores de fichero podemos ver que esta escuchando mediante un socket:

$ ls -la /proc/1028/fd
total 0
dr-x------ 2 jprats jprats  0 Nov 30 09:59 .
dr-xr-xr-x 8 jprats jprats  0 Nov 30 09:59 ..
lrwx------ 1 jprats jprats 64 Nov 30 09:59 0 -> /dev/pts/6
lrwx------ 1 jprats jprats 64 Nov 30 09:59 1 -> /dev/pts/6
lrwx------ 1 jprats jprats 64 Nov 30 09:59 2 -> /dev/pts/6
lrwx------ 1 jprats jprats 64 Nov 30 09:59 3 -> socket:[28039738]

En este caso, sabemos que es TCP, por lo que buscamos el identificador de socket en el /proc/net/tcp:

$ grep 28039738 /proc/net/tcp 
   6: 00000000:04D2 00000000:0000 0A 00000000:00000000 00:00000000 00000000   500        0 28039738 1 e183b700 299 0 0 2 -1                          

Podemos ver el identificador que hemos buscado hacia el final, los dos primeros campos nos muestran origen y destino de la conexión. Podemos traducir el puerto de hexadecimal a decimal con:

$ echo $((0x04D2))
1234

Podemos encontrar que significa cada dato de esta linea en la documentación del kernel, en el fichero Documentation/networking/proc_net_tcp.txt:

   46: 010310AC:9C4C 030310AC:1770 01 
   |      |      |      |      |   |--> connection state
   |      |      |      |      |------> remote TCP port number
   |      |      |      |-------------> remote IPv4 address
   |      |      |--------------------> local TCP port number
   |      |---------------------------> local IPv4 address
   |----------------------------------> number of entry

   00000150:00000000 01:00000019 00000000  
      |        |     |     |       |--> number of unrecovered RTO timeouts
      |        |     |     |----------> number of jiffies until timer expires
      |        |     |----------------> timer_active (see below)
      |        |----------------------> receive-queue
      |-------------------------------> transmit-queue

   1000        0 54165785 4 cd1e6040 25 4 27 3 -1
    |          |    |     |    |     |  | |  | |--> slow start size threshold, 
    |          |    |     |    |     |  | |  |      or -1 if the threshold
    |          |    |     |    |     |  | |  |      is >= 0xFFFF
    |          |    |     |    |     |  | |  |----> sending congestion window
    |          |    |     |    |     |  | |-------> (ack.quick<<1)|ack.pingpong
    |          |    |     |    |     |  |---------> Predicted tick of soft clock
    |          |    |     |    |     |              (delayed ACK control data)
    |          |    |     |    |     |------------> retransmit timeout
    |          |    |     |    |------------------> location of socket in memory
    |          |    |     |-----------------------> socket reference count
    |          |    |-----------------------------> inode
    |          |----------------------------------> unanswered 0-window probes
    |---------------------------------------------> uid

Para poder obtener el estado de la conexión (campo después de la dirección destino) deberemos buscar en el fichero include/net/tcp_states.h, dónde encontramos:

enum {
        TCPF_ESTABLISHED = (1 << 1),
        TCPF_SYN_SENT    = (1 << 2),
        TCPF_SYN_RECV    = (1 << 3),
        TCPF_FIN_WAIT1   = (1 << 4),
        TCPF_FIN_WAIT2   = (1 << 5),
        TCPF_TIME_WAIT   = (1 << 6),
        TCPF_CLOSE       = (1 << 7),
        TCPF_CLOSE_WAIT  = (1 << 8),
        TCPF_LAST_ACK    = (1 << 9),
        TCPF_LISTEN      = (1 << 10),
        TCPF_CLOSING     = (1 << 11) 
};

Por lo que podemos resumir en que:

  • Si la conexión esta en estado ESTABLISHED, obtendremos un 01 como estado.
  • Si la conexión esta en estado TIME_WAIT, obtendremos un 06 como estado.
  • Si la conexión esta en estado LISTEN, como en el caso del ejemplo, el estado que marca indica 0A

Por lo tanto, mediante el /proc y mucha paciéncia, podemos obtener los mismos datos que obtenemos mediante netstat o ss.

One comment to “Buscar el puerto de escucha mediante el /proc”

  1. plas,plas,plas,plas

    Nunca se me hubiese ocurrido.

    Santi.

Deja un comentario:

XHTML - Tags permitidos:<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>