Ir al contenido principal

Gestión de la red usando la línea de comandos (IV): monitorización de conexiones

 

Introducción

En este artículo de la serie de gestión de la red usando la línea de comandos nos vamos a centrar en la monitorización de las conexiones. Para ello vamos a utilizar el comando netstat, que es el decano de los comandos de monitorización de la red. También mostraremos el comando ss, que viene a sustituir a netstat en las funciones de monitorización de conexiones de red.
Asimismo mostraré una breve explicación de los conceptos que se van a trabajar en el artículo.

Sockets, puertos, protocolos y procesos

En primer lugar vamos a empezar con un poco de teoría para alumbrar lo que luego se explicará en el artículo. Si ya sabes de lo que estamos hablando, sáltate esta sección y ve al meollo del asunto [1].

Nos referiremos al contexto de la conexiones TCP/IP. Dentro de este contexto, cada conexión queda definida por dos endpoints, puntos finales, uno en el host, equipo, que establece la conexión y otro en el host con el que se comunica. Generalmente este último es el anfitrión de algún servicio al que el primero se quiere conectar. Cada uno de estos endpoints está definido por una dirección IP y un puerto (port) y es a esta combinación a la que se llama socketSe dice que el anfitrión está escuchando por nuevas conexiones en ese socket

De este modo, en una conexión TCP/IP interviene una pareja de sockets, identificada por una 4-tupla consistente por la dirección IP del cliente, el puerto de conexión del cliente, la dirección IP del servidor y el puerto de conexión del servidor.

Dado que un mismo host/anfitrión puede ofrecer varios servicios o establecer varias conexiones concurrentes de un mismo servicio, en la definición de cada socket se establece un número de puerto diferente. Así, el propósito de los puertos es diferenciar múltiples endpoints para una determinada dirección IP. Se puede decir que cada puerto es una virtualización del endpoint. Y es esa virtualización la que hace posible que múltiples conexiones concurrentes se puedan establecer en una misma interfaz de red. Permitiendo además liberar el puerto que se haya publicado para la escucha del servicio, tras una fase de negociación, para que otro cliente pueda establecer una nueva conexión. En principio un equipo puede gestionar 65535 puertos diferentes en un mismo momento, aproximadamente 2^16. Sin embargo, los primeros 1024 puertos suelen estar reservados para uso del propio sistema operativo y servicios estandarizados. Por ejemplo, para un servidor web suele reservarse los puertos 80 y 443, éste último para el tráfico seguro, para un servidor de hora se suele reservar el puerto 123, para un servidor de nombres de dominio (DNS) se suele reservar el puerto 53, etc.

Para aclarar este concepto pongamos un ejemplo. Hay un servidor que está sirviendo páginas web en Internet. Este servidor tiene la dirección IP pública W1.X1.Y1.Z1 y se encuentra escuchando en el puerto 80 para establecer nuevas conexiones y servir las páginas web a los clientes. Por otro lado, hay un equipo cliente que quiere acceder a las páginas web alojadas en el servidor. Ese equipo cliente tiene una dirección IP pública W2.X2.Y2.Z2 y ha establecido un socket en, por ejemplo, el puerto 20000 con el fin de establecer una conexión al servidor. En el momento de establecer la conexión hay varias fases. A groso modo, primero el cliente intenta establecer la conexión sobre el puerto estándar establecido para el servicio que va a usar, en nuestro ejemplo un servidor web en el puerto 80, recibe una respuesta del servidor diciendo que ese puerto está disponible. Entonces el cliente solicita un endpoint al que conectarse para acceder al servicio y el servidor establece un socket local identificado por un puerto, pongamos el 40000 (aunque podría ser incluso el mismo número de puerto que usa el cliente ya que cada número se refiere a su propio equipo). Una vez abierto el socket se lo comunica al cliente que establece la conexión y empieza a acceder al servicio web para ver las páginas que desea. De tal modo que la conexión TCP/IP entre los dos equipos queda definida por un endpoint en el servidor W1.X1.Y1.Z1:40000, los dos puntos tras una dirección IP indican el puerto,  y el endpoint en el equipo cliente W2.X2.Y2.Z2:20000. Estableciéndose así una conexión única entre los dos equipos y liberando el puerto 80 del servidor para que pueda establecer nuevas conexiones con otros clientes.

Pues bien, una vez establecida la conexión los ordenadores tienen que intercambiar la información. Es ahí donde entran en juego los protocolos TCP, de las siglas en inglés de Transmission Control Protocol, o el protocolo UDP, de las siglas en inglés User Datagram Protocol. Estos protocolos son los más comunes para intercambiar información entre ordenadores, aunque no los únicos. Digamos por simplificar que en conexiones donde es importante la recepción de todos los paquetes de información se usa el protocolo TCP porque los paquetes están identificados en una secuencia en el ordenador de origen que ha de ser reconstruida en el ordenador de destino. Esto es así porque los paquetes enviados desde el origen pueden ser enrutados por diferentes caminos hasta llegar al destino y pueden no llegar en el orden adecuado. Además contiene mecanismos para controlar la integridad de los paquetes que llegan al destino. Si alguno de los paquetes no se reciben, el destinatario puede volver a solicitarlo al emisor hasta que todos los paquetes que integran el mensaje lleguen a su destino. Por tanto se debe haber establecido previamente una conexión entre ambos. Por eso se dice que es un protocolo orientado a la conexión, confiable, ordenado y con control de errores. 

Por otro lado, el protocolo UDP está basado en la transmisión de datagramas sin establecer una conexión previa entre emisor y destinatario. Las propias cabeceras de los paquetes (datagramas) contienen información suficiente para identificar al destinatario del mensaje. No tiene confirmación ni control de flujo, por lo que los paquetes pueden adelantarse unos a otros; y tampoco se sabe si han llegado correctamente, ya que no hay un mecanismo de confirmación de entrega o recepción. La comunicación usando este protocolo suele ser más rápida aunque sin garantías de que se reciba toda la información enviada por el emisor. 

Ambos protocolos forman parte de la capa 4 del modelo OSI, la capa de transporte. En la comunicación entre ordenadores suelen entrar en juego varios protocolos. Pero no vamos a entrar en detalles con ningún otro aparte de los dos que ya he mencionado. Para más detalles les he puesto los enlaces a la Wikipedia de cada uno de ellos y al modelo OSI, por si quieren profundizar en el tema.

Por último nos queda aclarar lo que son los procesos. De una forma informal podemos decir que los procesos son los programas que se están ejecutando en un ordenador. Más específicamente un proceso está formado por la secuencia de instrucciones que componen el programa, más los datos de entrada necesarios, más los recursos que se le asignan para llevar a cabo las instrucciones. Está explicado más detalladamente en la Wikipedia.

Netstat

Este, por decirlo de alguna manera, es el comando de toda la vida para monitorizar las conexiones de red. Sin embargo, es un comando que ya está marcado como obsoleto. Que, aunque ya no venga instalado por defecto en Ubuntu, puede seguir usándose si se instalan la net-tools

Para instalar el paquete con las net-tools hay que ejecutar
sudo apt install net-tools

En la página del manual, que se puede consultar con el comando man netstat, se muestra una nota que explica cuales son los sustitutos de las funcionalidades que realiza este programa:

NOTES

       This program is mostly obsolete.  Replacement for netstat is ss.  Replacement for netstat -r is ip route.  Replacement for netstat -i is ip -s link.  Replacement  for netstat -g is ip maddr.

Que traducido nos viene a decir:

Este programa está prácticamente obsoleto. El reemplazo para netstat es ss. El reemplazo para netstat -r es ip route. El reemplazo para  netstat -i es ip -s link. El reemplazo para netstat -g es ip maddr.

Veamos ahora algunos de los modificadores del comando netstat que nos ayudarán a afinar la salida.

-a    por defecto, netstat, muestra sólo las conexiones establecidas. Si queremos que se muestren todas las conexiones debemos utilizar este modificador

-n    muestra las direcciones en formato numérico, en vez de tratar de resolverlas para mostrar los nombres de hosts.

-r    resuelve las direcciones para mostrar los nombres de hosts.

-t    muestra sólo las conexiones TCP.

-u    muestra sólo las conexiones UDP.

-e    muestra información adicional.

-p    muestra el PID (identificador del proceso) y el nombre del programa al que pertenece cada socket. Si se muestra un guión es que el proceso pertenece al kernel de Linux.

-l    muestra sólo las conexiones que se encuentran escuchando.

-x    muestra las conexiones a socket de Unix. Estas conexiones son las que se realizan por procesos que se ejecutan dentro del sistema para recibir o enviar información entre distintos procesos que se ejecutan en el propio sistema. No acceden ni reciben datos de fuera del propio ordenador.

Hay más opciones que se pueden utilizar, para conocer la totalidad de las funcionalidades del comando, como siempre, recomiendo consultar el manual (man netstat).

Así, por ejemplo, si queremos que se nos muestren todas las conexiones TCP en formato numérico con su proceso e información extendida tendremos que ejecutar el comando:

sudo netstat -atnpe

Lo ejecutamos con privilegios de superusuario para que se muestren todos los procesos. De otro modo, puede que algunos procesos, a los que nuestro usuario no tenga acceso, no se muestren.

El resultado de ese comando sería el que se muestra en la siguiente imagen:


ss

El comando ss está diseñado para volcar la información estadística de las conexiones vía socket. Muestra información similar a la mostrada por netstat. Sin embargo, puede mostrar más información que aquel. Es el sustituto más moderno para algunas de las funcionalidades que obteníamos con netstat.

El comando ss dispone de muchas más opciones de las que dispone netstat. Sin embargo, en este artículo sólo mostraremos las más comunes. Para consultar el resto, como siempre, los remito a la página del manual: man ss.

-O    muestra la información de cada socket en una sola línea.

-a    al contrario que netstat, este es el comportamiento por defecto de ss. Este modificador hace que se muestren todas las conexiones.

-n    muestra las direcciones en formato numérico, en vez de tratar de resolverlas para mostrar los nombres de hosts.

-r    resuelve las direcciones para mostrar los nombres de hosts.

-t    muestra sólo las conexiones TCP.

-u    muestra sólo las conexiones UDP.

-e    muestra información adicional. El formato de salida es uid:<uid_number> ino:<inode_number> sk:<cookie>.

-p    muestra el proceso que utiliza el socket

-l    muestra sólo las conexiones que se encuentran escuchando.

-x    muestra las conexiones a socket de Unix.

-i    muestra la información interna del socket TCP. 

Así, si queremos obtener, para seguir con el mismo ejemplo que para el comando netstatque se nos muestren todas las conexiones TCP en formato numérico con su proceso e información extendida tendremos que ejecutar el comando:

sudo ss -Oantpe

Y obtendríamos el resultado que se muestra a continuación:

De entrada ya vemos que se nos muestra más información sobre el proceso que ejecuta el socket que el comando anterior. El resto de las columnas puede decirse que son iguales.

Conclusión

Aunque en apariencia ambos comandos parece que muestran los mismos resultados, con el sencillo ejemplo mostrado se ve que ss muestra más información para la misma situación. Además de que netstat está obsoleto y desaparecerá de un momento a otro, mi recomendación es empezar a usar ss para la monitorización de la red. Al principio costará, como todos los cambios, pero al final te acostumbrarás a usarlo y ya no echarás de menos a netstat.

 

 

 

 

Comentarios

Entradas populares de este blog

Zed: ahora un editor de código de código abierto

  Zed: ahora un editor de código de código abierto Introducción Como ya les comenté en un artículo anterior  Atom ha muerto, viva ZED , Microsoft dejó de dar soporte para el editor de código Atom en el año 2022 en beneficio del Visual Studio Code . En aquel artículo les comentaba que para mi el sucesor de Atom era Zed pues era un editor que se estaba creando por el mismo grupo de trabajo que creó el Atom . Además de que parecía que iba a seguir con la misma filosofía con la que nació  Atom . El editor Zed, una descripción de sus características Zed es un editor de código desarrollado en Rust que, como deberíamos saber, es un lenguaje de programación de sistemas que se enfoca en la seguridad, el rendimiento y la concurrencia. Pues, como decíamos, Zed acaba de dar el salto a ser de código abierto bajo la licencia GPL v3 . Este cambio no solo representa una nueva era para Zed , sino que también nos dirige a un nuevo mundo de colaboración y desarrollo en el ámbito de la programación.

Atom ha muerto, viva Zed

El día 8 de junio de 2022, Microsoft anunció que a partir del día 31 de diciembre de este mismo año dejaría de dar soporte para el editor de código Atom .  ¿En qué nos afecta esto a nosotros? Bueno, pues si me han seguido en artículos anteriores saben que tras una comparativa de varios IDEs había decidido utilizar Atom para los ejemplos que tuviera que hacer en este blog. Sobre todo los artículos que prepararé para ilustrar el uso de Laravel . Amén de los miles de programadores que actualmente usan Atom  en sus proyectos, claro. Pero, ¿qué editor de código abierto podremos utilizar para sustituir a Atom ? En el mismo comunicado, Microsoft explicaba que el abandono del proyecto Atom  se debía a que querían volcar todos sus esfuerzos en el Visual Studio Code y, por supuesto, recomendó a los usuarios de Atom la utilización del mismo como alternativa natural. No quiero entrar en las bondades o defectos del Visual Studio Code  si quieres elegirlo como tu IDE para desarrollo predeterm

Gestión de la red usando la línea de comandos (III): gestión DNS

  Introducción En este nuevo artículo de la serie vamos a hablar de la gestión del DNS, Domain Name System. El sistema de resolución de nombres nos permite traducir los nombres de los dominios de Internet en direcciones IP númericas. Más difíciles de recordar para los humanos.  El DNS fue concebido a mediados de los años 80. Hasta esa época, los ordenadores conectados a una red disponían de una dirección numérica, la dirección IP. Pero con el tiempo, cada vez había más ordenadores conectados a las redes. Esto hacía que cada vez fuera más difícil recordar las direcciones IP. Sobre el año 1983, Paul Mockapetris , un informático estadounidense, desarrolló un sistema jerárquico de nombres para identificar a los ordenadores conectados a una red. Y, a mediados de la década, ya se convirtió en un estándar. Pueden consultar más información sobre el sistema DNS consultando el artículo de la Wikipedia: Sistema de nombres de dominio . En este artículo, no vamos a explicar como montar un servidor