Todo lo que has hecho en este módulo ocurría dentro de srv-tramontana. Pero un servidor solo existe para quien pueda llegar hasta él, y cuando Marta escribe «la web de reservas no carga», ninguna de las herramientas anteriores te sirve para averiguar dónde está el corte. Puede estar en la red, en la resolución de nombres, en el puerto, en la aplicación o en el propio navegador de Marta, y son cinco problemas completamente distintos con cinco soluciones distintas.

Esta lección te da las herramientas de diagnóstico y, sobre todo, el orden en que se usan. Ese orden es lo que separa a quien resuelve una incidencia en cinco minutos de quien pasa dos horas tocando cosas al azar. No configuramos nada aquí: la configuración persistente de red es 06-01, el firewall es 06-03 y SSH a fondo es 06-02. Aquí se mira, se mide y se concluye.

Contenido

  1. El repaso mínimo imprescindible
  2. ip: leer la configuración real
  3. Conectividad y camino: ping, traceroute, mtr
  4. Resolución de nombres
  5. Puertos y sockets con ss
  6. Probar servicios: curl, wget, nc
  7. Qué te dice cada herramienta cuando «la web no va»
  8. Transferencia: scp y rsync sobre SSH
  9. Ancho de banda con iperf3
  10. Metodología de diagnóstico en capas
  11. Caso Tramontana: «la web de reservas no carga»

  1. El repaso mínimo imprescindible

Lo justo para entender la salida de los comandos, no un curso de redes.

  • Capas. Los datos viajan encapsulados: la aplicación (HTTP) va dentro de transporte (TCP/UDP), que va dentro de red (IP), que va dentro de enlace (Ethernet). Cada herramienta mira una capa distinta, y por eso el diagnóstico se hace de abajo arriba.
  • IP, máscara y CIDR. 10.0.2.15/24 significa que los tres primeros octetos identifican la red y el último el host. Todo lo que esté en 10.0.2.x es alcanzable directamente; para el resto hace falta un intermediario.
  • Puerta de enlace (gateway). Ese intermediario: la dirección a la que se envía todo lo que no es local.
  • DNS. Traduce nombres a direcciones. Es una capa aparte y falla por su cuenta, lo que explica el clásico «el navegador no va pero el ping a la IP sí».
  • Puertos. Un número de 16 bits que identifica el servicio dentro de una máquina: 22 SSH, 80 HTTP, 443 HTTPS, 5432 PostgreSQL, 8080 el de nuestra aplicación. Por debajo de 1024 requieren privilegios para abrirse.
  • TCP frente a UDP. TCP establece conexión, garantiza orden y reenvía lo perdido; es lo que usa la web. UDP dispara y olvida; lo usan DNS y streaming. La diferencia importa al diagnosticar: en TCP existen estados observables, en UDP no hay nada que mirar.

  1. ip: leer la configuración real

ip sustituye a ifconfig, route y arp, que llevan más de una década obsoletos y pueden ni estar instalados.

operador@srv-tramontana:~$ ip -brief a
lo               UNKNOWN        127.0.0.1/8 ::1/128
enp0s3           UP             10.0.2.15/24 fe80::a00:27ff:fe4b:1c2a/64

-brief da la vista compacta que quieres el 90 % de las veces: interfaz, estado y direcciones. lo es el bucle local; enp0s3 es la tarjeta de la VM, UP y con la 10.0.2.15/24 que conoces desde el Módulo 1.

operador@srv-tramontana:~$ ip r
default via 10.0.2.2 dev enp0s3 proto dhcp src 10.0.2.15 metric 100
10.0.2.0/24 dev enp0s3 proto kernel scope link src 10.0.2.15 metric 100

Dos rutas. La segunda dice que la red 10.0.2.0/24 es directamente alcanzable. La primera, default, es la puerta de enlace: todo lo que no sea local sale por 10.0.2.2, que en una VM con NAT de VirtualBox es el propio anfitrión haciendo de router. proto dhcp indica que la configuración la dio un servidor DHCP, no un fichero.

operador@srv-tramontana:~$ ip -s link show enp0s3 | tail -4
    RX: bytes  packets  errors  dropped  missed   mcast
    182934012   248117       0        0       0       0
    TX: bytes  packets  errors  dropped  missed   mcast
     94120833   187204       0        0       0       0
operador@srv-tramontana:~$ ip neigh
10.0.2.2 dev enp0s3 lladdr 52:54:00:12:35:02 REACHABLE

-s link da los contadores: errors y dropped distintos de cero apuntan a un problema físico o de saturación, y aquí están a cero. ip neigh es la tabla ARP —qué direcciones MAC hemos resuelto— y REACHABLE confirma que hablamos con la puerta de enlace ahora mismo, sin necesidad de enviar ni un ping.

  1. Conectividad y camino: ping, traceroute, mtr

operador@srv-tramontana:~$ ping -c 3 10.0.2.2
64 bytes from 10.0.2.2: icmp_seq=1 ttl=64 time=0.412 ms
64 bytes from 10.0.2.2: icmp_seq=3 ttl=64 time=0.388 ms
--- 10.0.2.2 ping statistics ---
3 packets transmitted, 2 received, 33% packet loss, time 2031ms

Tres datos: el TTL (64 sugiere un Linux a un salto), el tiempo de ida y vuelta y la pérdida. Falta la respuesta 2.

Por qué un ping perdido no siempre es un fallo. ICMP es el tráfico de menor prioridad de la red: los equipos lo descartan en cuanto tienen cosas más importantes que hacer, y muchos cortafuegos lo bloquean por completo. Un 33 % de pérdida sobre tres paquetes tampoco es estadísticamente nada. Consecuencias prácticas:

  • Que el ping falle no demuestra que el host esté caído. Puede estar filtrado.
  • Que el ping funcione no demuestra que el servicio funcione. La máquina responde; la aplicación puede estar muerta.
  • Una pérdida ocasional en ICMP no implica pérdida en TCP.

ping responde a una sola pregunta: «¿hay camino IP hasta ahí?». Nada más. Con -c limitas los paquetes, con -i 0.2 acortas el intervalo y con -M do -s 1472 puedes diagnosticar problemas de MTU.

operador@srv-tramontana:~$ traceroute -n 8.8.8.8 | head -4
traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets
 1  10.0.2.2  0.331 ms  0.298 ms  0.276 ms
 2  192.168.1.1  2.104 ms  2.087 ms  2.201 ms
 3  * * *

Cada línea es un salto. -n evita la resolución inversa y acelera mucho la salida. Los asteriscos del salto 3 significan que ese equipo no responde, no que el camino se corte ahí: si los saltos posteriores sí contestan, simplemente ese router ignora el tráfico de diagnóstico. tracepath hace lo mismo sin privilegios y descubre la MTU del camino.

mtr combina ping y traceroute en tiempo real y es la mejor herramienta para pérdidas intermitentes: mtr -rwc 100 destino envía cien paquetes y da un informe con el porcentaje de pérdida y la latencia de cada salto, que es como se distingue un problema propio de uno del proveedor.

  1. Resolución de nombres

El orden lo fija /etc/nsswitch.conf:

operador@srv-tramontana:~$ grep '^hosts' /etc/nsswitch.conf
hosts: files mdns4_minimal [NOTFOUND=return] dns

files significa /etc/hosts primero. Por eso una entrada olvidada ahí gana a cualquier DNS del mundo y produce incidencias desconcertantes: la máquina resuelve un nombre a una IP que ya no existe y ningún cambio en el DNS lo arregla. Cuando un nombre resuelve mal, mira /etc/hosts antes que nada.

operador@srv-tramontana:~$ cat /etc/hosts
127.0.0.1       localhost
127.0.1.1       srv-tramontana
10.0.2.15       reservas.tramontana.example
operador@srv-tramontana:~$ dig +short reservas.tramontana.example
operador@srv-tramontana:~$ dig reservas.tramontana.example | sed -n '/QUESTION/,/^$/p'
;; QUESTION SECTION:
;reservas.tramontana.example.   IN      A

;; ANSWER SECTION:
reservas.tramontana.example. 300 IN A   10.0.2.15

Detalle importante: dig no consulta /etc/hosts, va directo al DNS. Es exactamente lo que quieres para distinguir «el DNS está mal» de «alguien tocó /etc/hosts». Las secciones de la respuesta son QUESTION (qué se preguntó), ANSWER (la respuesta, con su TTL en segundos), AUTHORITY y ADDITIONAL.

Comando Para qué
dig +short nombre solo la IP, para usar en tuberías
dig -x 10.0.2.15 resolución inversa
dig @1.1.1.1 nombre preguntar a un servidor concreto
dig nombre MX otro tipo de registro
dig +trace nombre recorrido desde los servidores raíz
host nombre consulta rápida y legible
resolvectl status qué servidores DNS usa el sistema

dig @1.1.1.1 frente a dig a secas es el diagnóstico decisivo: si un servidor externo resuelve y el tuyo no, el problema es tu resolvedor, no el dominio.

  1. Puertos y sockets con ss

ss sustituye a netstat y es la herramienta central de esta lección.

operador@srv-tramontana:~$ sudo ss -tulpn
Netid State  Recv-Q Send-Q Local Address:Port Peer Address:Port Process
udp   UNCONN 0      0          127.0.0.54:53        0.0.0.0:*     users:(("systemd-resolve",pid=398,fd=18))
tcp   LISTEN 0      4096   127.0.0.53%lo:53        0.0.0.0:*     users:(("systemd-resolve",pid=398,fd=16))
tcp   LISTEN 0      128          0.0.0.0:22        0.0.0.0:*     users:(("sshd",pid=889,fd=3))
tcp   LISTEN 0      511        127.0.0.1:8080      0.0.0.0:*     users:(("ejecutable",pid=1284,fd=7))

Opción por opción:

Opción Qué añade
-t sockets TCP
-u sockets UDP
-l solo los que están escuchando
-p el proceso dueño (necesita sudo para ver los ajenos)
-n números en vez de nombres de servicio (más rápido y sin ambigüedad)
-a todos, incluidos los establecidos
-s resumen estadístico
state ESTABLISHED / dport = :443 filtros

La columna Local Address es la que más información da y la que menos gente lee:

Valor Significa
0.0.0.0:22 escucha en todas las interfaces: accesible desde fuera
127.0.0.1:8080 escucha solo en el bucle local: inaccesible desde otra máquina
10.0.2.15:8080 solo en esa interfaz concreta
[::]:22 equivalente IPv6 de 0.0.0.0

Mira la última línea de la salida de arriba. ejecutable escucha en 127.0.0.1:8080. Guarda ese dato.

Estados TCP

Estado Significa
LISTEN esperando conexiones
SYN-SENT / SYN-RECV negociación en curso
ESTABLISHED conexión activa
FIN-WAIT, CLOSE-WAIT cierre en curso
TIME-WAIT cerrada, esperando paquetes rezagados

TIME-WAIT merece explicación porque asusta sin motivo: tras cerrar una conexión, el extremo que cerró primero mantiene el socket unos 60 segundos por si llega algún paquete retrasado. Miles de TIME-WAIT en un servidor con tráfico son normales. Muchos CLOSE-WAIT, en cambio, sí son un síntoma: significan que la aplicación no cierra sus sockets, y eso acaba agotando descriptores.

netstat -tulpn hace lo mismo y todavía lo verás en documentación antigua; está en el paquete net-tools, que ya no se instala por defecto. Escribe ss.

  1. Probar servicios: curl, wget, nc

operador@srv-tramontana:~$ curl -s -o /dev/null -w '%{http_code} %{time_total}s\n' http://127.0.0.1:8080/
200 0.043s

Ese one-liner es el que más vas a usar: -s silencia la barra de progreso, -o /dev/null descarta el cuerpo y -w imprime justo lo que te interesa. Un código y un tiempo.

Opción Para qué
-I solo las cabeceras (petición HEAD)
-v todo el diálogo, incluido el handshake TLS
-L seguir redirecciones
-o fichero guardar el cuerpo
-w '%{http_code}' extraer un dato concreto
--resolve host:puerto:IP forzar a qué IP conectar, saltándose el DNS
--max-time 5 límite total
-k ignorar errores de certificado (solo para diagnosticar)

--resolve es la opción que resuelve más incidencias de las que parece: permite probar el servidor antes de tocar el DNS, o comprobar si el problema es de resolución sin cambiar nada.

operador@srv-tramontana:~$ curl -I --resolve reservas.tramontana.example:80:10.0.2.15 \
    http://reservas.tramontana.example/ 2>&1 | head -2
curl: (7) Failed to connect to reservas.tramontana.example port 80: Conexión rehusada

«Conexión rehusada» es un mensaje muy informativo: significa que el paquete llegó y la máquina contestó activamente que ahí no hay nadie escuchando. No es un cortafuegos —eso daría un tiempo de espera agotado— ni un problema de ruta.

nc comprueba un puerto sin más ceremonia, y wget descarga ficheros (-c reanuda, -r recursivo, -O - vuelca a stdout):

operador@srv-tramontana:~$ nc -zv 127.0.0.1 8080
Connection to 127.0.0.1 8080 port [tcp/http-alt] succeeded!
operador@srv-tramontana:~$ nc -zv 10.0.2.15 8080
nc: connect to 10.0.2.15 port 8080 (tcp) failed: Connection refused

Dos pruebas casi idénticas con resultados opuestos. Eso es un hallazgo, y confirma lo que ya vimos en ss.

telnet host puerto sigue sirviendo como último recurso para hablar a mano con un servicio de texto, pero nc y curl lo hacen mejor y están más presentes.

  1. Qué te dice cada herramienta cuando «la web no va»

Herramienta Responde a Si falla, el problema está en
ip a / ip r ¿tengo dirección y ruta? configuración local
ping puerta de enlace ¿hay red local? cable, interfaz, VM
ping externo ¿hay salida? encaminamiento, NAT
dig ¿el nombre resuelve? DNS o /etc/hosts
traceroute / mtr ¿dónde se corta el camino? red intermedia
ss -tulpn ¿alguien escucha ese puerto y en qué dirección? el servicio o su configuración
curl ¿el servicio responde y qué contesta? la aplicación

La lectura importante de la tabla: cada herramienta descarta una capa. No sirven para «probar cosas»; sirven para eliminar hipótesis en orden.

  1. Transferencia: scp y rsync sobre SSH

operador@srv-tramontana:~$ scp /srv/tramontana/backups/envios/datos-2026-08-18.tar.gz [email protected]:/tmp/
datos-2026-08-18.tar.gz                       100%   47MB  38.2MB/s   00:01
operador@srv-tramontana:~$ rsync -avz --dry-run /srv/tramontana/backups/envios/ [email protected]:/tmp/copias/
sending incremental file list
datos-2026-08-18.tar.gz
sent 132 bytes  received 19 bytes  302.00 bytes/sec

scp copia y punto. rsync es superior en casi todo: transfiere solo las diferencias, comprime con -z, conserva permisos con -a, muestra el progreso con --progress y —lo esencial según la convención del curso— admite --dry-run para ver qué haría antes de hacerlo. Ya lo usabas en local desde 02-04; sobre SSH funciona igual, solo cambia que el destino lleva usuario@host:.

  1. Ancho de banda con iperf3

ping mide latencia, no capacidad. Para medir el caudal real hace falta generar tráfico: en un extremo iperf3 -s y en el otro iperf3 -c <servidor> -t 10. El informe da los Mbit/s alcanzados y, con -u, la pérdida y el jitter en UDP. Es la forma de responder con datos a «la red va lenta», que casi siempre resulta ser otra cosa.

  1. Metodología de diagnóstico en capas

Este es el apartado que hay que recordar. Se avanza de abajo arriba y no se salta ningún paso.

flowchart TD
    A["1. ¿Tengo IP y ruta?<br/>ip -brief a / ip r"] -->|sí| B["2. ¿Llego a la puerta de enlace?<br/>ping 10.0.2.2"]
    A -->|no| A1["Interfaz caída o sin DHCP"]
    B -->|sí| C["3. ¿Resuelvo nombres?<br/>dig +short / /etc/hosts"]
    B -->|no| B1["Red local, VM o cable"]
    C -->|sí| D["4. ¿El puerto escucha<br/>y en qué dirección?<br/>ss -tulpn"]
    C -->|no| C1["DNS o /etc/hosts"]
    D -->|sí| E["5. ¿El servicio responde?<br/>curl -I"]
    D -->|no| D1["Servicio caído<br/>o escuchando mal"]
    E -->|sí| F["El corte está fuera:<br/>cliente, proxy o navegador"]
    E -->|no| E1["Aplicación: mirar sus logs"]

Tres reglas que acompañan al diagrama:

  1. Anota el resultado de cada paso. Un diagnóstico es una cadena de descartes, y sin registro acabas repitiendo pruebas.
  2. No cambies nada mientras diagnosticas. Si tocas la configuración a mitad, ya no sabes qué causó qué.
  3. Prueba desde los dos lados. Que funcione en el servidor y no desde fuera acota el problema mejor que cualquier otra prueba.

  1. Caso Tramontana: «la web de reservas no carga»

13:05. Mensaje de Marta. Aplicamos el procedimiento.

Paso 1: ¿IP y ruta? ip -brief a da enp0s3 UP 10.0.2.15/24 e ip r muestra la ruta por defecto vía 10.0.2.2. Correcto.

Paso 2: ¿puerta de enlace?

operador@srv-tramontana:~$ ping -c 2 10.0.2.2 | tail -2
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 0.298/0.355/0.412/0.057 ms

Sin pérdida y con latencia de décimas de milisegundo. Correcto.

Paso 3: ¿resuelve el nombre?

operador@srv-tramontana:~$ getent hosts reservas.tramontana.example
10.0.2.15       reservas.tramontana.example

getent hosts es mejor que dig para esta pregunta: consulta por el mismo camino que las aplicaciones, respetando /etc/nsswitch.conf, así que incluye /etc/hosts. Resuelve a 10.0.2.15, que es la IP correcta. Correcto.

Paso 4: ¿escucha el puerto?

operador@srv-tramontana:~$ sudo ss -tulpn | grep 8080
tcp LISTEN 0 511 127.0.0.1:8080 0.0.0.0:* users:(("ejecutable",pid=1284,fd=7))

Aquí está. El proceso escucha, pero en 127.0.0.1:8080: solo acepta conexiones desde la propia máquina. Desde el portátil de Marta es inalcanzable, y ningún cortafuegos ni ningún DNS tiene nada que ver.

Paso 5: confirmarlo desde los dos lados.

operador@srv-tramontana:~$ curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/
200
operador@srv-tramontana:~$ curl -s -o /dev/null -w '%{http_code}\n' --max-time 5 http://10.0.2.15:8080/
curl: (7) Failed to connect to 10.0.2.15 port 8080: Conexión rehusada

Diagnóstico cerrado: la aplicación funciona perfectamente y está escuchando en la interfaz equivocada. Responde 200 por el bucle local y rehúsa la conexión por su propia IP.

La causa. El proceso se reinició anoche, y app.conf no fija la dirección de escucha, de modo que la aplicación usó su valor por defecto. Antes del reinicio llevaba meses funcionando porque alguien la había arrancado a mano con un parámetro que no quedó registrado en ninguna parte. Es el patrón exacto contra el que te prevenía 03-06: un servicio lanzado a mano no sobrevive a un reinicio con la misma configuración.

La solución es añadir la dirección de escucha a /etc/tramontana/app.conf con la convención de siempre —copia .bak-$(date +%F), sed -i, diff -u— y reiniciar el proceso con SIGTERM y espera. La solución definitiva, que la configuración quede fijada en una unidad de servicio que arranque sola y siempre igual, es systemd y es 05-05.

Informe para Marta. El servicio nunca dejó de funcionar: seguía atendiendo peticiones, pero solo desde el propio servidor, porque tras el reinicio de anoche arrancó escuchando únicamente en su dirección interna. Ya está corregido en el fichero de configuración, de modo que el próximo reinicio conservará el ajuste. Esto protege frente a que la incidencia se repita por la misma causa. No protege frente a dos cosas: nadie nos avisó del corte —lo detectamos porque tú lo dijiste, no por un sistema de vigilancia—, y el servicio sigue arrancándose de una forma que depende de que alguien lo haga bien. Ambas cosas tienen solución conocida —monitorización y gestión de servicios— y propongo abordarlas en el próximo módulo.

Errores Comunes y Consejos

  • Concluir «está caído» porque el ping falla. ICMP se filtra constantemente. Prueba el puerto con nc o curl.
  • Concluir «funciona» porque el ping responde. La máquina responde; el servicio puede estar muerto.
  • Probar solo desde el servidor. curl a 127.0.0.1 funciona incluso con el servicio mal enlazado. Prueba también por la IP real.
  • Ignorar la columna Local Address de ss. 127.0.0.1:puerto frente a 0.0.0.0:puerto es la diferencia entre accesible e inaccesible.
  • Olvidar /etc/hosts. Gana al DNS y produce incidencias imposibles de explicar mirando solo el DNS.
  • Usar dig para saber cómo resuelve una aplicación. dig ignora /etc/hosts; usa getent hosts.
  • Alarmarse por los TIME-WAIT. Son normales. Los CLOSE-WAIT acumulados sí son un síntoma.
  • Tocar la configuración a media investigación. Diagnostica primero, cambia después, y solo una cosa cada vez.
  • Consejo: curl -w '%{http_code} %{time_namelookup} %{time_connect} %{time_total}\n' reparte el tiempo total entre DNS, conexión y respuesta. Con un solo comando sabes qué fase es la lenta.
  • Consejo: guarda la salida de ip a, ip r y ss -tulpn de un servidor cuando funciona bien. Comparar con diff -u contra el estado actual es el diagnóstico más rápido que existe.

Ejercicios

Ejercicio 1. Documenta la configuración de red completa de tu VM: interfaces con su estado y dirección, puerta de enlace, servidores DNS y contadores de error. Guárdalo en /home/operador/datos/red-referencia.txt con la fecha, y explica para qué servirá ese fichero.

Ejercicio 2. Comprueba si el servicio de la aplicación es accesible desde otra máquina sin salir del servidor, y explica por qué curl http://127.0.0.1:8080/ no responde a esa pregunta. Indica qué comando te da la respuesta definitiva y por qué.

Ejercicio 3. Aplica la metodología de diagnóstico a este caso: desde portatil-alumno, ping srv-tramontana responde, pero el navegador se queda cargando indefinidamente al abrir http://reservas.tramontana.example:8080/. Enumera las comprobaciones en orden, con el comando de cada una, y di qué conclusión sacarías de cada resultado posible.

Soluciones

Solución 1.

operador@srv-tramontana:~$ { echo "=== Red de srv-tramontana — $(date +'%F %T') ==="
    echo '--- Interfaces ---';   ip -brief a
    echo '--- Rutas ---';        ip r
    echo '--- DNS ---';          resolvectl status | grep -E 'DNS Servers|Current DNS'
    echo '--- Contadores ---';   ip -s link show enp0s3 | tail -4
  } > /home/operador/datos/red-referencia.txt
operador@srv-tramontana:~$ head -4 /home/operador/datos/red-referencia.txt
=== Red de srv-tramontana — 2026-08-18 13:22:41 ===
--- Interfaces ---
lo               UNKNOWN        127.0.0.1/8 ::1/128
enp0s3           UP             10.0.2.15/24 10.0.2.15/24

Las llaves agrupan varios comandos para redirigir toda la salida del bloque con un único >, como aprendiste en 03-04. Su utilidad es la del último consejo: cuando dentro de tres meses algo deje de funcionar, un diff -u red-referencia.txt <(ip -brief a) te dirá en un segundo qué ha cambiado, que es la pregunta que de verdad importa en una incidencia. Un servidor documentado cuando funciona se diagnostica en minutos; uno sin referencia, a base de conjeturas.

Solución 2.

operador@srv-tramontana:~$ sudo ss -tulpn | grep ':8080'
tcp LISTEN 0 511 127.0.0.1:8080 0.0.0.0:* users:(("ejecutable",pid=1284,fd=7))
operador@srv-tramontana:~$ curl -s -o /dev/null -w '%{http_code}\n' --max-time 5 http://10.0.2.15:8080/
curl: (7) Failed to connect to 10.0.2.15 port 8080: Conexión rehusada

curl http://127.0.0.1:8080/ no responde a la pregunta porque el bucle local es un camino distinto: el tráfico ni siquiera sale por la interfaz de red, así que funciona aunque el servicio esté enlazado solo a 127.0.0.1. Es la prueba que más falsos «pues a mí me funciona» genera.

El comando definitivo es ss -tulpn, y concretamente su columna Local Address: 127.0.0.1:8080 dice, sin ambigüedad y sin depender de ninguna otra máquina, que el servicio no puede ser accesible desde fuera. curl contra la IP real lo confirma empíricamente, pero ss te da la causa además del síntoma.

Solución 3. El detalle clave del enunciado es que el navegador se queda cargando en lugar de dar un error inmediato. «Conexión rehusada» es rápida; un tiempo de espera largo apunta a que los paquetes se pierden sin respuesta, lo que sugiere filtrado antes que servicio caído. Con esa hipótesis, el orden:

  1. ping srv-tramontana — ya sabemos que responde: hay IP y ruta, capas 1 a 3 descartadas.
  2. getent hosts reservas.tramontana.example desde el portátil. Si resuelve a una IP distinta de 10.0.2.15, ahí está el fallo y se acabó. Si resuelve bien, seguimos.
  3. nc -zv 10.0.2.15 8080 desde el portátil. Distinguir las tres respuestas es lo importante: succeeded significa que el puerto es alcanzable y el problema está en la capa HTTP; Connection refused significa que nadie escucha o escucha solo en local; y un bloqueo sin respuesta hasta agotar el tiempo es la firma de un cortafuegos descartando paquetes en silencio, que es lo que encaja con el síntoma descrito.
  4. sudo ss -tulpn | grep 8080 en el servidor, para saber si escucha y en qué dirección. Si es 0.0.0.0:8080, el servicio está bien y el corte es intermedio.
  5. curl -s -o /dev/null -w '%{http_code} %{time_connect} %{time_total}\n' http://10.0.2.15:8080/ desde el servidor. Si responde 200 y desde fuera no llega nada, queda confirmado que el problema está entre las dos máquinas.
  6. Comparar la vista de red de la VM con la de referencia del ejercicio 1.

Conclusión más probable dado el síntoma: un filtrado en el camino, sea el cortafuegos del servidor o la configuración de red de la VM. Y aquí está el límite honesto de esta lección: el diagnóstico llega hasta identificar que el corte es de filtrado; corregirlo es materia de 06-01 y 06-03. Saber dónde termina tu diagnóstico y decirlo con claridad vale más que aventurar una solución que no puedes justificar.

Conclusión

Cierras el Módulo 3 con la capacidad de mirar hacia fuera del servidor y decir, con pruebas, dónde está el problema.

  • Tienes el repaso mínimo —capas, CIDR, puerta de enlace, DNS, puertos, TCP frente a UDP— suficiente para leer la salida de cualquiera de estas herramientas.
  • Lees la configuración real con ip: -brief a para interfaces, ip r para la ruta por defecto, -s link para los contadores de error y ip neigh para la tabla ARP.
  • Usas ping sabiendo que responde a una sola pregunta, y que ni un fallo prueba que algo esté caído ni un éxito prueba que el servicio funcione; recorres el camino con traceroute y persigues pérdidas intermitentes con mtr.
  • Entiendes el orden de resolución de /etc/nsswitch.conf, sabes que /etc/hosts gana al DNS, lees las secciones de una respuesta de dig y conoces la diferencia crucial entre dig y getent hosts.
  • Desglosas ss -tulpn opción por opción, y sobre todo lees la columna Local Address, que distingue un servicio accesible de uno enlazado solo al bucle local; interpretas los estados TCP sin alarmarte por los TIME-WAIT.
  • Pruebas servicios con curl —-I, -v, -w '%{http_code}', --resolve—, con nc y con wget, y transfieres con scp y rsync sobre SSH.
  • Y tienes una metodología en capas —¿IP?, ¿puerta de enlace?, ¿DNS?, ¿puerto?, ¿servicio?— que has aplicado a un caso real hasta encontrar una aplicación escuchando en 127.0.0.1, con el informe correspondiente para Marta y la honestidad de señalar qué queda sin cubrir.

Haz balance del módulo entero. Llegaste sabiendo ejecutar comandos y te vas sabiendo componerlos: has moldeado tu entorno con variables, alias e historial; has aprendido a describir conjuntos de archivos con comodines y patrones de texto con expresiones regulares, teniendo claro quién expande qué; has interrogado un servidor con find, locate y grep hasta encontrar una credencial expuesta; has entendido por dónde circula cada byte con las tuberías y la redirección; has convertido acceso.log y reservas.csv en informes con sort, uniq, sed y awk; has diagnosticado una aplicación bloqueada por una copia de seguridad que saturaba el disco; has reprogramado esa copia con bloqueo, prioridad y registro; y acabas de localizar un servicio escuchando en la interfaz equivocada. Eso es exactamente lo que anunciaba la filosofía Unix del Módulo 1, ahora en tus manos.

Y también has topado varias veces con el mismo muro. La línea de crontab del último ejercicio acumulaba escapes hasta volverse ilegible. La tubería del informe de facturación ya no cabía en una pantalla. Cada procedimiento que has diseñado —comprobar antes de borrar, copiar antes de editar, verificar el resultado— dependía de que tú te acordaras de hacerlo, paso a paso, sin equivocarte, a las tres de la madrugada. En el Módulo 4: Scripting en Shell ese muro desaparece. Aprenderás a guardar tus procedimientos en ficheros con nombre, con variables, argumentos y estructuras de control; a escribir funciones reutilizables; a depurar con set -x y a blindar tus scripts con set -euo pipefail y un manejo de errores serio; y a llegar hasta los scripts de producción, incluido el de copia de seguridad que llevas tres lecciones prometiendo. Todo lo que has aprendido aquí es el vocabulario; el Módulo 4 es la gramática que te permite escribir con él. Actualiza el snapshot de tu VM y nos vemos allí.

Curso de Linux: De Principiante a Administrador de Sistemas

Módulo 1: Introducción a Linux

Módulo 2: Comandos Básicos de Linux

Módulo 3: Habilidades Avanzadas en la Línea de Comandos

Módulo 4: Scripting en Shell

Módulo 5: Administración del Sistema

Módulo 6: Redes y Seguridad

Módulo 7: Temas Avanzados

Módulo 8: Proyectos Prácticos

© Copyright 2026. Todos los derechos reservados