Problema

En entornos de producción basados en OCI (Oracle Cloud Infrastructure) o cualquier nube pública, es frecuente que una instancia en una subnet pública necesite acceder a APIs externas mediante HTTPS. Cuando la conectividad falla de forma intermitente o total, los síntomas típicos son:

  • curl https://api.ejemplo.com nunca devuelve una respuesta, se agota el timeout de conexión.
  • Descargas de paquetes (apt update, yum install) fallan aleatoriamente.
  • Algunas URLs (GitHub, PECL) funcionan sin problemas, mientras que otras (Fastly, servicios de IA) presentan pérdida de paquetes desde el primer salto fuera del edge de la nube.
  • Herramientas de diagnóstico como mtr o traceroute muestran que los primeros dos hops (edge de OCI y el punto de handoff del ISP) son 0 % loss, pero a partir del tercer hop la pérdida sube a 100 % o a valores altos.

El patrón es claro: la ruta está intacta dentro de la VCN, el problema aparece en la capa de tránsito regional o de peering con el ISP del datacenter. Este tipo de “blackhole” suele afectar sólo a ciertos rangos de IP (por ejemplo, bloques de Fastly o de un proveedor de IA) y no a la internet en general.

Causa

Varias causas pueden generar este comportamiento:

  1. Problemas de peering o tránsito del ISP
    El edge de OCI entrega el tráfico a un punto de intercambio (IX) que, por alguna razón, no tiene rutas correctas hacia los prefijos del destino. Cuando el ISP pierde o filtra esos prefijos, el paquete desaparece sin respuesta TCP.

  2. Filtrado implícito por listas de control de acceso (ACL) o security groups
    En OCI, los security lists y network security groups son stateful, pero una regla de denegación explícita en la salida (por rango de IP o puerto) puede bloquear el tráfico antes de que salga del VCN. A veces, reglas heredadas de plantillas de VCN se activan solo para rangos específicos.

  3. Problemas de MTU y fragmentación
    Si la ruta incluye enlaces con MTU menor a 1500 bytes y la instancia no realiza Path MTU Discovery (PMTUD) correctamente, los paquetes TCP SYN pueden ser descartados. Esto se manifiesta como timeout inmediato.

  4. Preferencia de IPv6 sin interfaz global
    Cuando el DNS devuelve registros AAAA y la instancia no tiene una dirección IPv6 configurada, el stack intenta conectar vía IPv6, espera y luego falla. La configuración de gai.conf puede forzar IPv4, pero si la preferencia persiste, el SYN se envía a una ruta inexistente.

  5. Problemas de NAT o de la Internet Gateway
    En configuraciones con NAT Gateway o con un Internet Gateway mal asociado a la tabla de rutas, el tráfico puede salir por una ruta que no tiene salida real, provocando pérdida total.

Solución

Una estrategia modular permite aislar rápidamente la causa y aplicar la corrección adecuada.

1. Verificar la tabla de rutas y la IGW

# Lista de rutas de la VCN
oci network vcn get --vcn-id <VCN_OCID>
oci network route-table list --compartment-id <COMPARTMENT_OCID> --vcn-id <VCN_OCID>

Asegúrate de que exista una ruta 0.0.0.0/0 apuntando a la Internet Gateway y que la tabla esté asociada a la subnet usada por la instancia.

2. Revisar security lists y NSG

# Security lists
oci network security-list list --compartment-id <COMPARTMENT_OCID> --vcn-id <VCN_OCID>

# Network security groups
oci network nsg list --compartment-id <COMPARTMENT_OCID>

Confirma que haya una regla de salida ALL o al menos TCP 443 sin restricción de CIDR. Elimina cualquier regla de denegación que incluya los prefijos de los proveedores problemáticos (Fastly, AS399358, etc.).

3. Forzar IPv4 y descartar problemas de IPv6

sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1

O bien, ajusta /etc/gai.conf:

precedence ::ffff:0:0/96 100

Esto obliga a que curl y demás herramientas prefieran IPv4 cuando ambas versiones están disponibles.

4. Probar la MTU y habilitar PMTUD

# Detectar MTU óptima
ping -M do -s 1472 -c 4 8.8.8.8   # 1472 + 28 = 1500 bytes

Si el ping falla, reduce la MTU de la interfaz:

sudo ip link set dev eth0 mtu 1400

En la mayoría de los casos, OCI ya gestiona PMTUD, pero forzar una MTU menor elimina la variable de fragmentación.

5. Utilizar traceroute/mtr con TCP y puerto 443

mtr -T -p -c 20 -P 443 api.anthropic.com

Observa en qué hop aparece la pérdida. Si la pérdida comienza después del hop de OCI (por ejemplo, 84.8.76.x) y se mantiene en todos los saltos siguientes, el problema está fuera de tu control y requiere escalamiento al ISP o a OCI.

6. Escalar a OCI Support con evidencia

Prepara un ticket que incluya:

  • Salida completa de mtr o traceroute.
  • Capturas de tcpdump -i eth0 -nn -s 0 port 443 en la instancia (para demostrar que el SYN sale).
  • Configuración de rutas y security lists.

OCI suele abrir un caso de “Network Connectivity” y, si el problema está en el tránsito regional, la respuesta puede tardar desde horas hasta días, dependiendo de la gravedad y del SLA.

7. Alternativas de contingencia

  • Mirror de paquetes: Cambia temporalmente a un mirror de Debian alojado en una región con buena conectividad (por ejemplo, http://mirrors.edge.kernel.org/debian en Europa) y actualiza /etc/apt/sources.list.
  • Egress a través de VPN o WireGuard: Configura un túnel a una región diferente (us-east-1, us-west-2) y enruta el tráfico problemático mediante ip rule y ip route. Esto evita el tramo defectuoso sin necesidad de cambiar la arquitectura principal.

Cuándo aplicar esta solución

Utiliza este enfoque cuando observes:

  • Timeouts consistentes en curl https://<host> mientras otros hosts funcionan.
  • Pérdida de paquetes en mtr que inicia después del hop de la nube.
  • Fallos intermitentes de apt update o de descargas de paquetes en contenedores Docker.
  • No hay evidencia de firewall interno bloqueando el puerto 443.

No es necesario aplicar todo el proceso si ya sabes que la causa es IPv6 o MTU; basta con el paso correspondiente. En caso de que el tráfico falle solo para un único rango de IP y la tabla de rutas sea correcta, el escalamiento a OCI es la única vía viable.

Código

# 1. Verificar salida de paquetes con tcpdump
sudo tcpdump -i eth0 -nn -s 0 'tcp port 443 and (((ip[2:2] - ((ip[0] & 0xf)<<2)) - ((tcp[12] & 0xf0)>>2)) != 0)'

# 2. Forzar IPv4 en curl
curl -4 -v https://api.anthropic.com

# 3. Cambiar mirror de Debian (ejemplo)
sed -i 's|http://deb.debian.org|http://mirrors.edge.kernel.org/debian|g' /etc/apt/sources.list
apt update

Verificación

  1. Ejecuta curl -4 -v https://api.anthropic.com. La respuesta debe incluir HTTP/2 200 o al menos el handshake SYN‑ACK.
  2. Repite mtr -T -p -c 10 -P 443 api.anthropic.com. La pérdida debe ser 0 % en todos los hops.
  3. Corre apt update dentro del contenedor Docker. La salida no debe mostrar “Unable to locate package”.
  4. Si configuraste un túnel WireGuard, verifica que curl a través del túnel funciona y que el tráfico no pasa por la ruta original (ip route get 160.79.104.1 debería mostrar la interfaz wg0).

Notas adicionales

  • Los proveedores de CDN como Fastly pueden redirigir tráfico a PoPs lejanos; en regiones con rutas subóptimas, la latencia y la pérdida pueden incrementarse. Mantener una lista de mirrors alternativos reduce la dependencia de un solo PoP.
  • Cuando trabajas con Docker, recuerda que la red del contenedor hereda la configuración del host. Si el host tiene una regla iptables -A OUTPUT -p tcp --dport 443 -j DROP, todos los contenedores fallarán de la misma forma.
  • En entornos multi‑region, la política de “failover” a nivel de DNS (por ejemplo, usando Route53 con health checks) puede redirigir automáticamente a un endpoint saludable si el primer PoP está caído. Configurar health checks para APIs críticas evita interrupciones visibles al usuario final.