Si necesitamos reenviar todo el tráfico que llega a un puerto de un servidor Linux hacia otro equipo en la red, socat es buena opción. Indicamos, como ejemplo, cómo redirigir el tráfico del puerto 41121 de un servidor Linux Ubuntu a otro equipo (Linux o Windows), cómo convertirlo en un servicio systemd que arranque automáticamente, y todos los comandos necesarios para gestionarlo: iniciar, detener, reiniciar, ver logs.
- ¿Qué es Socat?.
- Caso de uso para aplicar redirección de tráfico.
- Gestión del servicio.
- Modificar la configuración del servicio.
- Consideraciones sobre el equipo destino.
- Posibles problemas y soluciones.
- Conclusión.
¿Qué es Socat?
Socat (SOcket CAT) es una herramienta de línea de comandos para Unix/Linux que permite establecer conexiones bidireccionales entre diferentes tipos de flujos de datos: sockets TCP, UDP, archivos, pipes, etc.
En ocasiones, se requiere redirigir el tráfico que llega a un puerto de un servidor hacia otro equipo. Esto se conoce como Proxy TCP/UDP (un intermediario que reenvía paquetes sin modificar), Port forwarding (reenvío de puertos) o Redirección de tráfico o TCP relay.
Esta tarea es posible por ejemplo, con Python, con el siguiente script:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
import socket import threading import sys def manejar_cliente(socket_cliente, host_remoto, puerto_remoto): """Recibe datos del cliente y los reenvía al servidor remoto""" # Conectar al destino remoto socket_remoto = socket.socket(socket.AF_INET, socket.SOCK_STREAM) socket_remoto.connect((host_remoto, puerto_remoto)) def reenviar(origen, destino): """Reenvía datos de origen a destino""" while True: try: datos = origen.recv(4096) if not datos: break destino.sendall(datos) except: break origen.close() destino.close() # Dos hilos: cliente -> remoto y remoto -> cliente hilo_cliente_a_remoto = threading.Thread(target=reenviar, args=(socket_cliente, socket_remoto)) hilo_remoto_a_cliente = threading.Thread(target=reenviar, args=(socket_remoto, socket_cliente)) hilo_cliente_a_remoto.start() hilo_remoto_a_cliente.start() hilo_cliente_a_remoto.join() hilo_remoto_a_cliente.join() def iniciar_proxy(puerto_local, host_remoto, puerto_remoto): """Escucha en puerto_local y reenvía todo a host_remoto:puerto_remoto""" servidor = socket.socket(socket.AF_INET, socket.SOCK_STREAM) servidor.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) servidor.bind(('0.0.0.0', puerto_local)) servidor.listen(5) print(f"Proxy escuchando en puerto {puerto_local}, reenviando a {host_remoto}:{puerto_remoto}") while True: socket_cliente, direccion = servidor.accept() print(f"Conexión desde {direccion}") manejador_cliente = threading.Thread(target=manejar_cliente, args=(socket_cliente, host_remoto, puerto_remoto)) manejador_cliente.start() if __name__ == "__main__": if len(sys.argv) != 4: print("Uso: python proxy.py <puerto_local> <ip_destino> <puerto_destino>") print("Ejemplo: python proxy.py 41121 192.168.1.100 41121") sys.exit(1) puerto_local = int(sys.argv[1]) host_remoto = sys.argv[2] puerto_remoto = int(sys.argv[3]) iniciar_proxy(puerto_local, host_remoto, puerto_remoto) |
Aunque, para mayor fiabilidad, suele ser conveniente usar herramientas ya consolidadas, como socat.
Caso de uso para aplicar redirección de tráfico
En una organización disponemos de un servidor de monitorización con Pandora FMS, con IP 192.168.1.200. Enviando datos a este servidor hay 100 agentes, en cuya configuración de pandora_agent.conf todos apuntan a la IP 192.168.1.200 y envían el tráfico por el puerto 41121. Dado que la organización quiere cambiar el servidor de Pandora FMS, porque el actual está obsoleto (tanto el sistema operativo como el propio Pandora FMS), ha decidido desplegar un nuevo servidor, con nuevo sistema operativo y nuevo Pandora FMS, con IP 192.168.202.

El servidor actual de Pandora FMS (a sustituir) tiene Linux Ubuntu Server 19.04 y el nuevo Rocky Linux 10.
La organización quiere mantener durante un tiempo la configuración de los agentes, que siguen «apuntando» a la IP del servidor «viejo», pero quiere que la información se envíe al nuevo servidor, desde el viejo, hasta haber reconfigurado todos los agentes.
En esta situación, usar un redirección TCP para que todo el tráfico que llegue al servidor «viejo» de Pandora FMS por el puerto 41121 de Tentacle sea reenviado al servidor nuevo, por el mismo puerto, es lo más rápido y práctico. Por lo tanto, convertiremos el viejo servidor de Pandora en un proxy transparente, recibiendo los datos y reenviándolos al servidor nuevo.
Requisitos previos
- Servidor Linux que hará de proxy transparente.
- Servidor Linux de destino del tráfico (a este servidor no necesitaremos acceder).
- Acceso
rooto usuario consudoal servidor proxy transparente. - El puerto que vamos a usar (41121) debe estar libre (ningún otro proceso escuchando). Para este cometido, dado que solo una aplicación puede escuchar por un puerto, lo primero que tendremos que hacer es detener los servicios de tentacle del servidor de Pandora FMS viejo, para que no siga usando el puerto 41121, de lo contrario, no podríamos usar socat para reenviar este tráfico, porque detectaría que el puerto ya está siendo usado por otra aplicación.
- Conectividad de red entre el servidor origen y servidor destino.
Paso 1: Instalar Socat en Ubuntu Server Pandora antiguo
En el servidor antiguo, que hará de proxy transparente, si socat no está instalado, lo instalaremos, con el comando:
|
1 |
sudo apt install socat -y |
Para verificar que se instaló correctamente:
|
1 |
socat -V |
Devolverá la versión de socat y otros datos:

Si quisiéramos instalarlo en otras distribuciones Linux:
|
1 2 3 4 5 6 7 |
# CentOS / RHEL / Fedora sudo yum install socat -y # o bien sudo dnf install socat -y # Debian más antiguos sudo apt-get install socat -y |
Paso 2: Probar el reenvío de puertos manualmente
Para este tipo de reenvíos, lo ideal y lógico, es crear un servicio para que el reenviador quede permanentemente activado. Pero, antes de crear un servicio permanente, es conveniente probar que el comando funciona correctamente. El comando básico para un proxy TCP es:
|
1 |
socat TCP-LISTEN:PUERTO_LOCAL,fork,reuseaddr TCP:IP_DESTINO:PUERTO_DESTINO |
En el estudio de caso, el comando será:
|
1 |
socat TCP-LISTEN:41121,fork,reuseaddr TCP:192.168.1.202:41121 |
Explicación de cada parte:
| Opción | Significado |
|---|---|
TCP-LISTEN:41121 | Escucha conexiones TCP entrantes en el puerto 41121 |
,fork | Crea un proceso hijo por cada conexión (permite múltiples clientes simultáneos) |
,reuseaddr | Reutiliza el puerto inmediatamente después de cerrar una conexión |
TCP:192.168.1.202:41121 | Conecta al destino (IP:puerto) y reenvía los datos |
Para probar socat en modo debug:
Es conveniente, incluso, probar el comando socat en modo debug/verbose, que nos devuelva más datos sobre el reenvío, para asegurarnos de que funciona perfectamente. Para ello, ejecutaremos el comando con los siguientes parámetros:
|
1 |
socat -d -d TCP-LISTEN:41121,fork,reuseaddr TCP:192.168.1.202:41121 |
Los -d -d aumentan el nivel de detalle en la salida, mostrando conexiones y transferencia de datos.
Si necesitáramos redireccionar tráfico UDP, usaríamos:
|
1 |
socat UDP-LISTEN:41121,fork,reuseaddr UDP:192.168.1.202:41121 |
Nota: Si el puerto está ocupado por otro proceso, mostrará el error
Address already in use. En este caso, se debe detener el proceso que use este puerto.
Cuando confirmemos que funciona, podremos detener socat pulsando Ctrl+C y pasar al siguiente paso (crear servicio permanente).
Paso 3: Crear un servicio systemd para que socat arranque automáticamente
Lo conveniente es dejar permanente la ejecución de socat, para que permanezca ejecutado incluso si se reinicia el servidor, por ello necesitamos:
- Se inicie automáticamente al arrancar el servidor.
- Se ejecute en segundo plano.
- Se reinicie automáticamente si falla.
- Podamos gestionarlo con comandos estándar (
start,stop,status,logs).
Todo esto lo logramos creando un servicio systemd. Para crear el servicio ejecutaremos:
|
1 |
sudo nano /etc/systemd/system/socat-proxy.servicio |
Se abrirá un editor, pegaremos el siguiente contenido (cambiando el puerto y la IP de destino por el que necesitemos):
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
[Unit] Description=Socat Proxy Service - Redirige tráfico del puerto 41121 a 192.168.1.202:41121 After=network-online.target Wants=network-online.target [Service] Type=simple User=root Restart=always RestartSec=5 ExecStart=/usr/bin/socat TCP-LISTEN:41121,fork,reuseaddr TCP:192.168.1.202:41121 [Install] WantedBy=multi-user.target |

Explicación de las directivas:
| Directiva | Valor | Qué hace |
|---|---|---|
Description | Texto libre | Descripción del servicio para identificación |
After | network-online.target | El servicio se inicia DESPUÉS de que la red esté activa |
Wants | network-online.target | Indica que la red debe estar disponible |
Type | simple | El proceso principal es socat |
User | root | Ejecuta como root (necesario para puertos bajos, opcional) |
Restart | always | Reinicia siempre, incluso si falla o termina normalmente |
RestartSec | 5 | Espera 5 segundos antes de reintentar el reinicio |
ExecStart | comando socat | La línea de comando que ejecuta el proxy |
WantedBy | multi-user.target | El servicio se inicia en modo multiusuario (arranque normal) |
Guardaremos los cambios con Ctrl+O y cerraremos la edición con Ctrl+X .
Recargar systemd para que reconozca el nuevo servicio con:
|
1 |
sudo systemctl daemon-reload |
Habilitaremos el servicio para que arranque automáticamente en el inicio del equipo:
|
1 |
sudo systemctl enable socat-proxy.servicio |
El comando anterior creará los enlaces simbólicos necesarios en /etc/systemd/system/multi-user.target.wants/.
Iniciaremos el servicio para comprobar que funciona correctamente, con:
|
1 |
sudo systemctl start socat-proxy.servicio |
Verificaremos que está funcionando, con:
|
1 |
sudo systemctl status socat-proxy.servicio |
Si el servicio se ha iniciado, devolverá:
socat-proxy.servicio - Socat Proxy Service - Redirige tráfico del puerto 41121 a 192.168.1.202:41121
Loaded: loaded (/etc/systemd/system/socat-proxy.servicio; enabled; vendor preset: enabled)
Active: active (running) since Sun 2026-04-13 20:30:00 UTC; 10s ago
Main PID: 3327123 (socat)
Tasks: 1 (limit: 2291)
Memory: 1.2M
CPU: 12ms
CGroup: /system.slice/socat-proxy.service
└─3327123 /usr/bin/socat TCP-LISTEN:41121,fork,reuseaddr TCP:192.168.1.202:41121
Los campos más importantes:
loaded: el archivo de servicio se cargó correctamente.enabled: está configurado para iniciar con el sistema.active (running): el proceso está ejecutándose.
Comprobaremos también que el puerto está en escucha, con el comando:
|
1 |
ss -tulpn | grep 41121 |
Salida esperada:
tcp LISTEN 0 5 0.0.0.0:41121 0.0.0.0:* users:(("socat",pid=3327123,fd=5))
Gestión del servicio
Una vez configurado el servicio, se puede gestionar con los comandos estándar de systemctl.
Ver el estado actual
sudo systemctl status socat-proxy.servicio
Detener el servicio
sudo systemctl stop socat-proxy.servicio
Iniciar el servicio (si está detenido)
sudo systemctl start socat-proxy.servicio
Reiniciar el servicio
sudo systemctl restart socat-proxy.servicio
Deshabilitar el arranque automático (sin detenerlo ahora)
sudo systemctl disable socat-proxy.servicio
Ver los logs en tiempo real
sudo journalctl -u socat-proxy.servicio -f
Ver logs históricos (últimas líneas)
sudo journalctl -u socat-proxy.servicio -n 50
Ver logs con marcas de tiempo completas
sudo journalctl -u socat-proxy.servicio --since today
Modificar la configuración del servicio
Si necesitas cambiar la IP de destino o el puerto:
- Edita el archivo de servicio:bashsudo nano /etc/systemd/system/socat-proxy.service
- Modifica la línea
ExecStartcon la nueva IP/puerto. - Guarda y sal.
- Recarga systemd y reinicia:bashsudo systemctl daemon-reload sudo systemctl restart socat-proxy.service
Consideraciones sobre el equipo destino
El equipo de destino puede ser Windows, Linux, MAC, etc., cualquier sistema operativo, porque socat actúa como un cliente TCP estándar. El equipo destino (en el estudio de caso el 192.168.1.202:41121) puede ser:
- Linux: con cualquier servicio escuchando en ese puerto (puede ser otro
socat, un servidor web, una base de datos, etc.). - Windows: con un servicio TCP escuchando (por ejemplo, un servidor personalizado, un programa que acepte conexiones en ese puerto).
- Cualquier otro sistema: mientras tenga un servicio TCP escuchando en el puerto indicado, la conexión funcionará.
- En el estudio de caso se trata de un equipo Linux con el servicio Tentacle escuchando lo que se envía al 41121.
Posibles problemas y soluciones
Error: «Address already in use»
Causa: Otro proceso ya está usando el puerto 41121.
Solución:
# Ver qué proceso usa el puerto sudo ss -tulpn | grep 41121 # o sudo lsof -i :41121 # Detener ese proceso o cambiar el puerto en socat
Error: «Connection refused» en el destino
Causa: El equipo destino no tiene ningún servicio escuchando en el puerto 41121.
Solución: Asegúrate de que en 192.168.1.202:41121 haya un proceso escuchando (por ejemplo, otro socat, un servidor, etc.).
El servicio no arranca al inicio
Solución: Verifica que esté habilitado:
sudo systemctl is-enabled socat-proxy.servicio
Si devuelve disabled, ejecuta sudo systemctl enable socat-proxy.servicio
El servicio se detiene inesperadamente
Solución: Revisa los logs:
sudo journalctl -u socat-proxy.servicio -n 50 --no-pager
La opción Restart=always debería reiniciarlo automáticamente, pero los logs te indicarán la causa.
Resumen de comandos útiles
| Acción | Comando |
|---|---|
| Instalar socat | sudo apt install socat -y |
| Probar manualmente | socat TCP-LISTEN:41121,fork,reuseaddr TCP:192.168.1.202:41121 |
| Crear servicio | sudo nano /etc/systemd/system/socat-proxy.servicio |
| Recargar systemd | sudo systemctl daemon-reload |
| Habilitar arranque automático | sudo systemctl enable socat-proxy.servicio |
| Iniciar servicio | sudo systemctl start socat-proxy.servic |
| Ver estado | sudo systemctl status socat-proxy.servic |
| Detener servicio | sudo systemctl stop socat-proxy.servic |
| Reiniciar servicio | sudo systemctl restart socat-proxy.servic |
| Ver logs en tiempo real | sudo journalctl -u socat-proxy.servic |
| Verificar puerto | ss -tulpn | grep 41121 |
Conclusión
Socat es una herramienta extremadamente potente y sencilla para redirigir tráfico entre puertos y equipos. Con una sola línea de comando se resuelven problemas complejos de proxy, reenvío de puertos y balanceo básico.
Al combinarlo con systemd, se obtiene una solución robusta, persistente y gestionable como cualquier otro servicio del sistema: arranque automático, reinicio ante fallos, logs integrados y control estándar.
Ya sea que se necesite reenviar datos de monitoreo (como el caso de Pandora FMS), conectar dos aplicaciones a través de un servidor intermedio, o simplemente redirigir tráfico entre servidores, socat puede ser una buena alternativa.