Reutilización de puertos en GNU/Linux

Para todos los sistemas operativos, una conexión (comunicación) entre dos equipos está definida por cualquier combinación de la tupla formada por la dirección IP origen y destino, el puerto de origen y destino y el protocolo de transporte (TCP o UDP).  Así, en cualquier nodo de nuestra red, podremos utilizar la función bind para “anclar” nuestro servidor a cualquier puerto libre. Si el puerto ya está en uso, y si nuestro nodo dispone de más de una dirección IP, podremos unir nuestro proceso utilizando otra IP que no tenga “ocupado” el puerto que nos interesa. Si el puerto y la dirección están en uso, siempre podremos usar el otro protocolo de transporte, suponiendo, nuevamente, que esté libre (y nos interese, claro).

En definitiva, esta tupla (recordemos: ip origen, puerto origen, ip destino, puerto destino, protocolo de transporte) le permiten al sistema operativo identificar unívocamente, el proceso que debe encargarse de los datos de aplicación.

Así que, ¿a qué viene el título de la entrada? ¿Qué es reutilizar puertos?

Pues para responder, debemos ver las opciones SO_REUSEADDR y, sobre todo, SO_REUSEPORT cuyo comportamiento es distinto en función del sistema operativo donde las utilicemos (ver [1]).

La opción SO_USEADDR ya la mencioné en esta entrada en la que comentaba los timeouts de TCP; en ella indicaba que, en general, interviene en el tiempo de espera…

antes de poner disponible, de nuevo, un puerto tras su cierre y el objetivo es dejar tiempo suficiente para que los segmentos de esta conexión saliente desaparezcan del sistema

aunque hay más y es lo que voy a tratar en el resto de la entrada junto con la opción SO_REUSEPORT. Ambas son importantes para la programación de Sistemas Distribuidos; y podemos usarlas cuando nos convenga, pero sin olvidarnos que debemos disponer de una versión del núcleo igual o superior a la 3.9.

SO_REUSEADDR, en GNU/Linux (así como en BSD y otros sistemas operativos) introduce, tal y como podemos comprobar en la página man de la función socket [2], la posibilidad de reutilizar la misma combinación IP-Puerto en un servidor, siempre y cuando el puerto no esté en escucha activa (es decir, se haya ejecutado la función listen para ese puerto). Básicamente, nos permite reutilizar puertos UDP, teniendo un comportamiento diferente en otros sistemas como por ejemplo BSD (ver [1]).

SO_REUSEPORT, en GNU/Linux, permite asociar un número arbitrario de sockets a la misma pareja IP-puerto, tanto para TCP como para UDP. Esto solo tiene una limitación (además de que el flag debe estar activo, antes de ejecutar bind, en todos los procesos): todos los sockets deben de pertenecer a procesos con el mismo EUID (identificador de usuario efectivo) para evitar el secuestro de puertos (port hijacking).

¿Qué ventaja aporta? Si consultamos la página man de socket:

this option allows accept load distribution in a multi-threaded 
server to be improved by using a distinct listener socket for each 
thread.  This provides improved load distribution as compared to 
traditional techniques such using a single accepting thread 
that distributes connections, or having multiple threads that 
compete to accept from the same socket.
UDP sockets, the use of this option can provide better distribution
of incoming datagrams to multiple processes (or threads) las compared
to the traditional technique of having multiple processes compete 
to receive datagrams on the same socket.

¿Cómo lo implementamos? Veamos un ejemplo. Si tomamos el código del servidor sencillo descrito en esta entrada y le añadimos la siguiente orden, justo antes de invocar la función bind*:

s.setsockopt(socket.SOL_SOCKET, SO_REUSEPORT, 1)

tras varias ejecuciones del programa, tendremos el resultado de la imagen 1 :

Screenshot from 2015-03-20 10:53:54

Y ¿qué proceso recibe los datos de aplicación? ¿Todos? Pues no. Tanto en TCP como en UDP, el núcleo de GNU/Linux trata de repartir equitativamente el trabajo entre los procesos: las conexiones entrantes para TCP (las reparte equitativamente entre los procesos que están con la ejecución de la función accept en ese puerto) y los datagramas para UDP. En el caso específico de multicast, SO_REUSEADDR tiene el mismo comportamiento que SO_REUSEPORT en conexiones unicast.

Para el ejemplo visto, tras 2 conexiones (una desde el propio equipo y otra desde otro nodo de la red) tenemos que estas se asignan a 2 procesos diferentes (ver imagen 2)

Screenshot from 2015-03-20 10:56:55

¡Espero que os sea útil!

*Solo nos falta definir: SO_REUSEPORT=15

Referencias

1.- Muy completa la respuesta dada en: http://stackoverflow.com/questions/14388706/socket-options-so-reuseaddr-and-so-reuseport-how-do-they-differ-do-they-mean-t

2.- man socket

3.- man setsockopt


ownCloud y Raspberry PI

Tras un aviso de Dropbox para que reduzca los muchísimos GB que me sobran al haber “caducado la oferta” por pertenecer a la UA, he decidio crearme mi “ownCloud” con un disco duro de 1TB que tenía y una Raspberry PI.

Sobre como instalarlo hay muchas entradas en la red (I, II, III, IV,  …) así que poco más que añadir o comentar, salvo:

Leer más


Qué hacer para conectar un disco USB sin alimentación externa a una Raspberry PI

En las Raspberry PI  la corriente está limitada a 1.2A en los USB de modo que solo es posible conectar un disco duro USB, sin alimentación externa o sin HUB, si modificamos el fichero /boot/config.txt añadiéndole:

max_usb_current=1
safe_mode_gpio=4

Tras esto y reiniciada la Raspberry  podremos conectar y utilizar el disco USB sin necesidad de alimentación extra.

¡Espero que os sea útil!

PD: Falta un detalle: la alimentación debe ser de 5V y 2A.

 


Transparencias “viejunas” sobre IDS

Hace muchos años (en el 2006) impartí unas clases en la Universidad de Almería sobre sistemas de detección de intrusos en el curso anunciado aquí.

Las transparencias que hice las he subido a Slideshare y he hecho un collage para presentarlas en este blog como anuncié hace unos días. Aquí lo tenéis.

Sobre SNORT, teoría:

Y prácticas:

Sobre Honeyposts, teoría:

Y práctica:

Y, por último, sobre Tripwire:

¡¡¡Espero que os sean útiles a pesar del tiempo que tienen!!!


Transparencias de clase sobre DHCP

Tal y como comentaba ayer en esta entrada, voy a ir dejando todas mis transparencias de clases, ponencias, conferencias y cursos en Slideshare.

Hoy toca el turno del servicio DHCP, clase que impartía en la asignatura de Administración e Instalación de Redes de Computadores en las titulaciones de Informática.

De las diferentes versiones (en función de los años) que tengo, he decidido publicar estas:


Transparencias de la clase sobre DNS en el Grado de Informática

Revisando el material de clase que tengo, he comprobado que creé transparencias de temas que, casi seguramente, no vuelva a utilizar y antes de que se pierdan en la profundidad de mi sistema, las he dejado (o dejaré ya que tengo que revisar muchas de ellas) en Slideshare.

De la asignatura de Administración de Redes de Computadores, he dejado, por ahora, la dedicada al servicio DNS.

Aquí la tenéis:

¡¡¡Espero que os sean útiles!!!


Más sobre WordPress

WordPress, como gestor de contenidos (CMS) ampliamente utilizado, se encuentra en el punto de mira de los “analizadores y aprovechadores” de agujeros de seguridad. Cualquier preocupación es poca y, por tanto, además de las tareas de fortalecimiento y análisis tratadas antes en este blog (I y II), debemos considerar aplicar otras: básicamente plugins que nos ayudan a mejorar la seguridad de nuestro sitio. Un listado bastante completo de ellos lo podéis encontrar en este gran trabajo recopilatorio de David Hernández.

Leer más


list open files (lsof)

lsof es una utilísima orden que nos muestra la información relacionada con los descriptores de archivo de nuestro sistema. Por ejemplo, cuando queremos desmontar un sistema de archivo y la respuesta es “Error: sistema ocupado”, con ‘lsof +D /punto_de_montaje‘ podemos saber todos los procesos (la primera columna de la fila, o filas, que obtenemos como respuesta) que están utilizando dicho sistema de archivos (y actuar en consecuencia).

¿Qué más podemos saber con él? Pues conocer/obtener el listado de:

Leer más


Las cookies nos permiten ofrecer nuestros servicios. Al utilizar nuestros servicios, aceptas el uso que hacemos de las cookies. Más información.