Por defecto, en Linux el parámetro de keepalive en Linux está configurado a 7200 segundos. Esto lo podemos ver con el siguiente comando:
[[email protected] ~]# sysctl -a |grep -i keepalive_time
net.ipv4.tcp_keepalive_time = 7200
[[email protected] ~]#
Esto significa que el sistema operativo enviará una señal de «esta conexión está viva» a todas las conexiones que están todavía establecidas en el servidor, cada dos horas (7200 segundos).
Pero, por alguna razón, puede que nos interese modifica este parámetero.
¿Por qué modificar el valor por defecto del keepalive?
Es una situación habitual encontrarse con el siguiente caso:
- Un usuario envía una consulta a una base de datos.
- La base de datos tarda mucho tiempo en devolver el resultado. Imaginemos, más de cinco minutos.
- Durante ese tiempo, la conexión desde el servidor cliente hacia la base de datos está activa pero no hace nada. Simplemente espera la respuesta de la base de datos.
- En el firewall hay configurado un timeout de cinco minutos y corta todas las conexiones que no han tenido actividad durante cinco minutos.
- El usuario que ha lanzado la consulta a la base de datos recibe un error.
Para este problema hay dos soluciones:
- Aumentar el timeout configurado en el firewall
- Configurar un keepalive en el sistema operativo que mande una señal a la conexión activa de «estoy viva» antes de los cinco minutos para que el firewall no la corte.
Aprende más sobre la configuración de red en Linux
¿Cómo modificar el parámetro de keeplive en Linux RedHat?
Para hacer una prueba en caliente, es decir, el parámetro no se guardará en el siguiente reboot del servidor, lo haremos así:
[[email protected] ~]# sysctl -w net.ipv4.tcp_keepalive_time=10
net.ipv4.tcp_keepalive_time = 10
[[email protected] ~]#
En este caso el keepalive configurado está en diez segundos.
Si queremos configurar el keepalive de forma permanente, el fichero /etc/systl.conf, escribiremos la siguiente directiva:
[[email protected] ~]# vi /etc/sysctl.conf
net.ipv4.tcp_keepalive_time = 10
[[email protected] ~]# sysctl -p
Pongamos en práctica con un ejemplo lo explicado anteriormente:
- Lanzo con curl una consulta que fallará porque el firewall cortará la conexión antes:
[[email protected] ~]# date; time curl --max-time 450 "http://10.49.64.26/gica0com/axl/apps/scripts/conexiones.php?prt=test&time=350"; date
Thu Jul 1 11:49:02 CEST 2021
curl: (56) Failure when receiving data from the peer
real 5m6.922s
user 0m0.001s
sys 0m0.011s
Thu Jul 1 11:54:09 CEST 2021
[[email protected] ~]#
- Desde curl también puedo modificar el keepalive para esa consulta en concreto, con el parámetro keepalive-time:
[[email protected] ~]# date; time curl --max-time 450 --keepalive-time 10 "http://10.49.64.26/gica0com/axl/apps/scripts/conexiones.php?prt=test&time=350"; date
Thu Jul 1 11:54:29 CEST 2021
DONE
real 5m50.066s
user 0m0.007s
sys 0m0.005s
Thu Jul 1 12:00:19 CEST 2021
[[email protected] ~]#
Esta vez, el resultado devuelve «DONE». No ha fallado.
Ahora que sé que el parámetro que he de modificar es el keealive, lo modifico a nivel de sistema operativo, tal y como he explicado anteriormente y vuelvo a lanzar la primera consulta que había fallado:
[[email protected] ~]# sysctl -a |grep -i keepalive_time
net.ipv4.tcp_keepalive_time = 10
[[email protected] ~]# date; time curl --max-time 450 "http://10.49.64.26/gica0com/axl/apps/scripts/conexiones.php?prt=test&time=350"; date
Thu Jul 1 12:10:04 CEST 2021
DONE
real 5m50.100s
user 0m0.011s
sys 0m0.003s
Thu Jul 1 12:15:54 CEST 2021
[[email protected] ~]#