Ir directamente al contenido

Ajustes de cookies

Elija por tipo qué cookies permite. Puede cambiar su elección en cualquier momento en Ajustes de cookies, al pie de cada página. Declaración de privacidad

Necesarias

Siempre activadas

Necesarias para iniciar sesión, conservar su carrito y recordar sus preferencias. Siempre están activadas.

¿Qué cookies?
  • weboke_sessie, weboke_klant, weboke_remember: su sesión y mantener la sesión iniciada
  • weboke_basket: su carrito
  • wkBtwIncl: mostrar los precios con o sin IVA
  • wok_cookies: su elección de cookies, 12 meses

Mide qué anuncio lleva a una visita o a un pedido, para no pagar por anuncios que no sirven de nada.

¿Qué cookies?
  • Google Ads a través de Google Tag Manager (_gcl_au, _gcl_aw), hasta 90 días
  • OpenAI Ads, anuncios en ChatGPT
  • wok_aff: a través de qué socio llegó a nosotros (programa de afiliados), 60 días

4,6

País e idioma

Cada país tiene su propio sitio, con los precios y el IVA de ese país.

Ver

Módulo 5 · 5.1

Puertos y servicios a la escucha

Módulo 5: Proteger la red · Tiempo de lectura: 10 minutos

Objetivo de aprendizaje: Después de esta lección podrá ver qué servicios escuchan en su servidor y en qué dirección, explicar la diferencia entre 0.0.0.0 y 127.0.0.1, y comprobar desde fuera lo que cualquiera en internet ve de su servidor.

Conceptos clave: puerto, TCP y UDP, escuchar, ss -tulpn, 0.0.0.0 y [::], 127.0.0.1 y [::1], bind-address, abierto, cerrado y filtrado, superficie de ataque, escáneres

Una dirección IP con 65.535 puertas

Su servidor tiene una dirección IP, por ejemplo 192.0.2.10 y 2001:db8::10. En esa dirección pueden estar accesibles varios programas a la vez, cada uno en su propio puerto: un número del 1 al 65.535. Un programa que acepta conexiones escucha en un puerto. Algunos conocidos:

PuertoProtocoloServicio
22TCPSSH
80TCPhttp (servidor web)
443TCP y UDPhttps (UDP para HTTP/3)
25TCPcorreo entre servidores de correo (SMTP)
3306TCPMySQL y MariaDB
5432TCPPostgreSQL
6379TCPRedis

TCP es el protocolo para conexiones que deben llegar de forma fiable (web, SSH, bases de datos). UDP sirve para paquetes sueltos y rápidos (DNS, VPN como WireGuard, HTTP/3). Un servicio escucha en TCP, en UDP o en ambos.

Cada puerto a la escucha es una puerta a su servidor. Detrás de cada puerta hay software que puede contener errores. El conjunto de puertas accesibles desde fuera se llama su superficie de ataque. Cuanto más pequeña, mejor: un servidor con un sitio web solo necesita desde fuera los puertos 22, 80 y 443.

Ver qué está a la escucha: ss

El comando ss (socket statistics) muestra lo que está a la escucha en su servidor. Con las opciones -t (TCP), -u (UDP), -l (solo a la escucha), -p (qué programa) y -n (números, no nombres):

anna@web1:~$ sudo ss -tulpn
Netid State  Local Address:Port  Peer Address:Port Process
udp   UNCONN 127.0.0.54:53       0.0.0.0:*         users:(("systemd-resolve",pid=402,fd=16))
tcp   LISTEN 0.0.0.0:22          0.0.0.0:*         users:(("sshd",pid=611,fd=3))
tcp   LISTEN 0.0.0.0:80          0.0.0.0:*         users:(("nginx",pid=902,fd=6))
tcp   LISTEN 0.0.0.0:443         0.0.0.0:*         users:(("nginx",pid=902,fd=7))
tcp   LISTEN 127.0.0.1:3306      0.0.0.0:*         users:(("mariadbd",pid=755,fd=21))
tcp   LISTEN 0.0.0.0:6379        0.0.0.0:*         users:(("redis-server",pid=780,fd=6))
tcp   LISTEN [::]:22             [::]:*            users:(("sshd",pid=611,fd=4))
tcp   LISTEN [::]:80             [::]:*            users:(("nginx",pid=902,fd=8))
tcp   LISTEN [::]:443            [::]:*            users:(("nginx",pid=902,fd=9))

La columna más importante es Local Address: la dirección en la que escucha el programa.

DirecciónSignificado
0.0.0.0Todas las direcciones IPv4 del servidor, incluida la pública: accesible desde fuera (salvo que un firewall lo impida)
[::]Todas las direcciones IPv6: lo mismo para IPv6
127.0.0.1 o [::1]Solo el propio servidor (loopback): nunca accesible desde fuera
127.0.0.53, 127.0.0.54También loopback; aquí escucha el asistente DNS local de systemd-resolved
192.0.2.10Solo esa dirección concreta

En el ejemplo anterior, MariaDB está bien: escucha en 127.0.0.1, así que solo los programas del propio servidor (su sitio web) pueden acceder. Pero Redis escucha en 0.0.0.0:6379. Si el firewall no está bien configurado, todo internet puede acceder. Ese es exactamente el tipo de error del que trata esta lección.

Escuchar en la dirección correcta

Una base de datos, una caché o un panel de administración casi nunca deberían ser accesibles desde fuera. La primera y mejor defensa es que el servicio escuche solo en loopback. Un firewall (lección 5.2) es la segunda capa; puede estar desactivado por descuido o no aplicarse (por ejemplo con Docker, lección 9.3).

Dónde se configura depende de cada programa:

ProgramaAjusteArchivo (Debian/Ubuntu)
MariaDB/MySQLbind-address = 127.0.0.1/etc/mysql/mariadb.conf.d/50-server.cnf
PostgreSQLlisten_addresses = 'localhost'/etc/postgresql/<versie>/main/postgresql.conf
Redisbind 127.0.0.1 -::1 y protected-mode yes/etc/redis/redis.conf

Los paquetes de Debian y Ubuntu ya configuran estos servicios en localhost por defecto. Normalmente el problema surge cuando alguien sigue un manual que dice "ponga bind-address en 0.0.0.0 para conectarse desde fuera". Si usted quiere acceder a la base de datos desde su portátil, utilice un túnel SSH (lección 2.3): el puerto permanece cerrado y solo quien entra por SSH puede acceder.

Después de un cambio, reinicie el servicio y vuelva a comprobarlo con ss -tulpn.

Abierto, cerrado y filtrado

Visto desde fuera, un puerto puede estar en tres estados:

  • Abierto: algo está a la escucha y la conexión se establece.
  • Cerrado (closed): no hay nada a la escucha, o un firewall rechaza activamente. El servidor devuelve de inmediato un "no" (en TCP, un paquete RST). La conexión falla al instante con "Connection refused".
  • Filtrado (filtered): un firewall descarta el paquete en silencio. La conexión se queda colgada hasta que se agota el tiempo de espera.

Para su base de datos, cerrado y filtrado son ambos correctos: nadie puede acceder. La diferencia solo le indica por qué: filtrado casi siempre significa que su firewall lo está bloqueando.

Mirar desde fuera

ss muestra lo que está a la escucha en el servidor, pero no lo que es accesible desde fuera. Entre medias hay además un firewall, y a veces también un firewall de red en su proveedor. Por eso la única comprobación real es: mirar desde fuera, desde otro ordenador.

Desde su propio ordenador (no desde el propio servidor, porque entonces pasaría por loopback) puede hacerlo con nc (netcat) para un solo puerto:

anna@laptop:~$ nc -vz -w 3 192.0.2.10 6379
nc: connect to 192.0.2.10 port 6379 (tcp) failed: Connection refused
anna@laptop:~$ nc -vz -w 3 192.0.2.10 22
Connection to 192.0.2.10 22 port [tcp/ssh] succeeded!

En Windows, PowerShell hace lo mismo con Test-NetConnection 192.0.2.10 -Port 6379. Un escáner de puertos como nmap puede revisar varios puertos a la vez; utilice un escáner así solo en su propio servidor.

No se olvide de IPv6. Un error frecuente es tener un firewall con reglas solo para IPv4, mientras el servicio también escucha en [::]. Compruebe por tanto también la dirección IPv6: nc -6 -vz -w 3 2001:db8::10 6379.

Por qué esto es tan importante

Su servidor recibe escaneos desde el primer minuto. Los buscadores de dispositivos y servicios en internet, y los bots de delincuentes, prueban continuamente todas las direcciones IPv4 en puertos conocidos. Un Redis abierto sin contraseña, un clúster de Elasticsearch o un MongoDB sin control de acceso se encuentran en poco tiempo. Las filtraciones de datos por bases de datos y clústeres de búsqueda abiertos aparecen con regularidad en las noticias, y casi siempre se deben precisamente a este error: un servicio pensado para uso interno escuchaba en todas las direcciones.

El puerto de SSH también recibe intentos durante todo el día. Es normal y, con claves (lección 2.2) y fail2ban (lección 5.3), no supone ningún problema.

La comprobación del curso

En el ejercicio de esta lección, el programa del curso comprueba desde fuera cinco puertos de bases de datos fijos de su servidor: 3306 (MySQL/MariaDB), 5432 (PostgreSQL), 6379 (Redis), 9200 (Elasticsearch/OpenSearch) y 27017 (MongoDB). El programa solo intenta establecer una conexión, no envía datos y no inicia sesión en ningún sitio. No escanea otros puertos. Las comprobaciones proceden de la dirección IP indicada en el ejercicio, para que pueda reconocerlas en su propio registro. Una dirección solo puede comprobarse unas pocas veces por hora.

En AlmaLinux y Rocky Linux

ss funciona igual. Los archivos de los servicios están en otras ubicaciones (por ejemplo /etc/my.cnf.d/ para MariaDB, /var/lib/pgsql/data/postgresql.conf para PostgreSQL). Además, SELinux puede bloquear un servicio que quiera escuchar en un puerto poco habitual; eso lo verá en journalctl (lección 6.2) y no en ss.

Resumen

  • Cada puerto a la escucha es una puerta; mantenga abierto desde fuera solo lo realmente necesario (normalmente 22, 80 y 443).
  • sudo ss -tulpn muestra qué programa escucha en qué dirección y en qué puerto.
  • 0.0.0.0 y [::] significan "todas las direcciones", 127.0.0.1 y [::1] significan "solo el propio servidor". Las bases de datos, cachés y clústeres de búsqueda deben estar en loopback.
  • Cerrado y filtrado son ambos correctos para una base de datos; abierto es un error.
  • Compruébelo siempre desde fuera, para IPv4 y también para IPv6, porque ss no ve el firewall.

Cuestionario

1. En ss -tulpn aparece 127.0.0.1:3306 junto a mariadbd. ¿Qué significa?



2. Redis escucha en 0.0.0.0:6379. Su firewall no permite el puerto 6379. ¿Cuál es el mejor enfoque?



3. Usted prueba desde fuera el puerto 5432 y la conexión se queda colgada 3 segundos y luego falla. ¿Cuál es el estado más probable?



4. ¿Por qué debe comprobar un puerto abierto desde fuera y no solo con ss en el servidor?



5. Su firewall tiene reglas para IPv4, pero su servidor también tiene una dirección IPv6. Redis escucha en [::]:6379. ¿Cuál es el riesgo?



Ejercicio

Ejercicio Z5.1: Puertos de bases de datos cerrados desde fuera. Ejecute sudo ss -tulpn en su servidor y averigüe en qué direcciones escuchan sus servicios. Después, deje que el programa del curso compruebe desde fuera que los puertos 3306, 5432, 6379, 9200 y 27017 de su servidor no son accesibles, por IPv4 y (si su servidor tiene un registro AAAA) por IPv6. Indique también qué servicios escuchan en su caso en 0.0.0.0 o [::]. El programa solo establece una conexión con esos cinco puertos y no envía nada.

Ejercicio Z5.1: Puertos de bases de datos cerrados desde fuera

No iniciamos sesión ni probamos ninguna contraseña o clave. Primero demuestre que el servidor es suyo: haga clic en "Mostrar mi código" y coloque un archivo /.well-known/weboke-cursus-<code>.txt que contenga solo ese código en el servidor web de su nombre de host. Lo descargamos directamente de cada dirección IP que comprobamos (IPv4 e IPv6 por separado); un registro TXT no sirve aquí. La comprobación se realiza desde heavy.webawere.nl (185.158.167.16 y 2a07:ae80:100:0:185:158:167:16), no desde nuestro servidor web. Solo para alumnos registrados; como máximo 6 comprobaciones por hora y servidor. Solo establecemos una conexión TCP con los puertos 3306, 5432, 6379, 9200, 27017 y 2375 (IPv4 e IPv6) y no enviamos nada.




No guardamos lo que escriba ni lo que encontremos. Su navegador recuerda sus respuestas y si ha superado el ejercicio. Si ha iniciado sesión, en Mis cursos solo guardamos que el ejercicio estaba (casi) correcto; allí también puede eliminarlo.

Para saber más

Un momento…

Configure sus dominios

Configure para cada dominio los servidores de nombres, la vinculación a su hosting y quién será el titular.

Cargando sus dominios…