Centro de ayuda

Guías paso a paso sobre servidores, redes y tu cuenta.

Red e IP

Optimización de red en Linux para conexiones de larga distancia: búferes TCP, BBR + fq, MTU/MSS y sysctl

Optimización de red en Linux para conexiones de larga distancia: búferes TCP, BBR + fq, MTU/MSS y sysctl

En una ruta larga y con mucha latencia (por ejemplo, un VPS en Tokio, Seúl o Moscú que atiende a usuarios en Europa o en China continental), la velocidad de una sola conexión TCP suele estar limitada por los búferes de socket del kernel y el control de congestión, no por el puerto de 500 Mbps. En esta guía vas a calcular ese límite, aplicar un perfil sysctl seguro con búferes TCP más grandes y BBR + fq, corregir problemas de MTU/MSS en túneles, comparar antes y después con iperf3 y deshacer todo si lo necesitas.

Si solo quieres activar BBR, te basta con la guía corta Cómo activar BBR. Este artículo va más allá y explica también los búferes y el MTU. Los comandos funcionan en Debian 12/13, Ubuntu 22.04/24.04 y Rocky Linux/AlmaLinux 9, que traen kernels con BBR.

Por qué la distancia limita la velocidad de una conexión

TCP solo puede tener cierta cantidad de datos sin confirmar «en vuelo». Esa cantidad es el producto ancho de banda-retardo (BDP): ancho de banda × tiempo de ida y vuelta (RTT). Si la ventana que permiten los búferes es menor que el BDP, la conexión se queda esperando confirmaciones y nunca llena el enlace, por rápido que sea el puerto.

Ejemplo práctico: un puerto de 500 Mbps y un RTT de 180 ms.

  • BDP = 500.000.000 bit/s × 0,18 s = 90.000.000 bits = unos 11,25 MB.
  • El búfer de recepción máximo habitual de Linux (tcp_rmem) es de 6 MB, y una parte se reserva para sobrecarga. 6 MB ÷ 0,18 s ≈ 280 Mbps en el mejor caso, y en la práctica a menudo 150–200 Mbps por conexión.
  • Con un techo de 32 MB, el límite teórico a 180 ms pasa de 1 Gbps, así que en un puerto de 500 Mbps el búfer deja de ser el cuello de botella.

La pérdida de paquetes lo empeora: el algoritmo clásico CUBIC reduce mucho su velocidad con cada pérdida y en una ruta larga tarda bastante en recuperarse. BBR, en cambio, estima el ancho de banda disponible y el RTT, por lo que tolera mucho mejor las pérdidas ocasionales de las rutas internacionales. Mide tu propio RTT con ping, porque depende de dónde estén tus usuarios.

Sobre la ruta en sí: JUSTG Moscú usa China Telecom CN2 GIA, que ofrece un camino más limpio hacia China continental; Tokio y Seúl usan rutas optimizadas para Asia. Una buena ruta reduce la pérdida y el jitter, pero el RTT lo marca la física, así que ajustar los búferes ayuda en cualquier ubicación.

Paso 1: Revisa la configuración actual

uname -r
sysctl net.ipv4.tcp_congestion_control net.ipv4.tcp_available_congestion_control
sysctl net.core.default_qdisc net.core.rmem_max net.core.wmem_max
sysctl net.ipv4.tcp_rmem net.ipv4.tcp_wmem net.ipv4.tcp_mtu_probing
ip -br link
tc qdisc show

Apunta la versión del kernel, el control de congestión actual (normalmente cubic), la qdisc por defecto (normalmente fq_codel), los valores de los búferes y el nombre de tu interfaz de red (eth0, ens3, etc.; más abajo cambia eth0 por la tuya).

Paso 2: Guarda una copia y busca archivos en conflicto

sudo sysctl -a 2>/dev/null | grep -E 'tcp_(rmem|wmem|congestion_control|mtu_probing|notsent_lowat)|core\.(rmem_max|wmem_max|default_qdisc|somaxconn)' | sudo tee /root/sysctl-before.txt
grep -rnE 'congestion|qdisc|rmem|wmem' /etc/sysctl.conf /etc/sysctl.d/ 2>/dev/null

El primer comando guarda los valores actuales en /root/sysctl-before.txt para que puedas restaurarlos después. El segundo muestra otros archivos que ya definen las mismas claves. Los archivos de /etc/sysctl.d/ se aplican por orden de nombre y /etc/sysctl.conf (si existe) se aplica al final, así que una línea antigua ahí puede anular tu archivo nuevo sin avisar. Elimina o comenta los duplicados.

Debian 13 ya no lee /etc/sysctl.conf por defecto, otra razón para guardar tus ajustes en un archivo dentro de /etc/sysctl.d/.

Paso 3: Crea el perfil de ajustes

sudo tee /etc/sysctl.d/99-network-tuning.conf > /dev/null <<'EOF'
# Queueing discipline and congestion control
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr

# Socket buffer ceilings (32 MB) for high-RTT paths
net.core.rmem_max = 33554432
net.core.wmem_max = 33554432
net.ipv4.tcp_rmem = 4096 131072 33554432
net.ipv4.tcp_wmem = 4096 16384 33554432

# Recover from PMTU black holes
net.ipv4.tcp_mtu_probing = 1

# Keep unsent data in the send buffer small (lower latency)
net.ipv4.tcp_notsent_lowat = 131072

# Larger accept queue for busy services
net.core.somaxconn = 4096
EOF
echo tcp_bbr | sudo tee /etc/modules-load.d/bbr.conf

Qué hace cada parte:

  • default_qdisc = fq y bbr: BBR para el control de congestión y la cola fq para un ritmo de envío (pacing) limpio. Desde el kernel 4.13, BBR funciona también sin fq, pero sigue siendo la pareja recomendada.
  • rmem_max/wmem_max y tcp_rmem/tcp_wmem: los tres números son mínimo, valor por defecto y máximo en bytes por socket. El autoajuste de Linux solo agranda el búfer de una conexión cuando lo necesita, así que un techo de 32 MB no significa que cada conexión use 32 MB. En el plan mini (512 MB de RAM) puedes usar 16777216 (16 MB), que aún cubre 500 Mbps hasta unos 150 ms de RTT.
  • tcp_mtu_probing = 1: cuando el kernel detecta un «agujero negro» de MTU (paquetes grandes descartados en silencio), reduce el tamaño de paquete de esa conexión en lugar de quedarse colgado.
  • tcp_notsent_lowat: limita cuántos datos aún sin enviar esperan en el socket, lo que mantiene baja la latencia del tráfico interactivo y de HTTP/2 sin reducir el rendimiento.
  • somaxconn = 4096: el límite de la cola de conexiones aceptadas. En kernels 5.4 y posteriores ya es 4096; la línea solo importa en sistemas antiguos y deja clara la intención.

La última línea asegura que el módulo tcp_bbr se cargue al arrancar, antes de aplicar los valores de sysctl.

Paso 4: Aplica y comprueba

sudo modprobe tcp_bbr
sudo sysctl --system
sysctl net.ipv4.tcp_congestion_control net.core.default_qdisc net.ipv4.tcp_rmem net.ipv4.tcp_wmem

Deberías ver bbr, fq y los nuevos valores de búfer. Cambiar default_qdisc solo afecta a las colas que se creen después, así que la interfaz actual mantiene su qdisc antigua hasta reiniciar. Para cambiarla ya:

sudo tc qdisc replace dev eth0 root fq
tc -s qdisc show dev eth0

Luego abre una conexión nueva (por ejemplo, otra sesión SSH o una descarga) y revísala con ss, usando la IP del otro extremo:

ss -tin dst 203.0.113.20

La salida muestra bbr, el rtt medido y la ventana de congestión actual de cada conexión. Las conexiones abiertas antes del cambio conservan los ajustes antiguos hasta que se reconecten.

Paso 5: Detecta y corrige problemas de MTU/MSS

Los problemas de MTU se ven muy distintos a los de búferes pequeños. Síntomas típicos:

  • el ping y las peticiones pequeñas funcionan, pero las descargas o subidas grandes se cuelgan tras unos pocos kilobytes;
  • SSH inicia sesión, pero se congela cuando un comando muestra mucha salida;
  • algunos sitios HTTPS cargan a medias o no cargan, sobre todo a través de una VPN, WireGuard, GRE o PPPoE.

La causa suele ser un tramo con MTU menor que 1500 donde se bloquean los mensajes ICMP «fragmentation needed». Prueba con la opción «no fragmentar». Una carga de 1472 bytes más 28 bytes de cabeceras da justo un paquete de 1500 bytes:

ping -c 3 -M do -s 1472 203.0.113.20
ping -c 3 -M do -s 1400 203.0.113.20
tracepath -n 203.0.113.20
ip link show dev eth0

Si 1472 falla pero 1400 funciona, ve bajando el tamaño hasta que pase: el mayor tamaño que funciona + 28 es el MTU de la ruta. tracepath también muestra el pmtu a lo largo del camino. No bloquees todo el ICMP en tu firewall: el descubrimiento del MTU de ruta depende de él.

Si el servidor enruta tráfico de otros (un servidor WireGuard u otra VPN, un túnel GRE, una pasarela NAT), limita el MSS de TCP en las conexiones reenviadas para que ambos extremos acuerden un tamaño de segmento que quepa en el túnel. Con nftables (por defecto en Debian 12/13 y Rocky/Alma 9):

sudo tee /etc/nftables-mssfix.nft > /dev/null <<'EOF'
table inet mssfix
delete table inet mssfix
table inet mssfix {
    chain forward {
        type filter hook forward priority mangle; policy accept;
        tcp flags & (syn | rst) == syn tcp option maxseg size set rt mtu
    }
}
EOF
sudo nft -f /etc/nftables-mssfix.nft
sudo nft list table inet mssfix

La regla reescribe el MSS de los paquetes SYN según el MTU de la ruta de salida. Para que se mantenga tras reiniciar en Debian/Ubuntu, añade include "/etc/nftables-mssfix.nft" al final de /etc/nftables.conf y ejecuta sudo systemctl enable nftables. En Rocky/Alma con firewalld, no actives el servicio nftables aparte; usa el método PostUp de WireGuard que verás abajo. La misma regla con iptables (instala el paquete iptables si hace falta):

sudo iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

Con WireGuard, lo más sencillo y persistente es ponerlo en la configuración de wg-quick (por ejemplo, /etc/wireguard/wg0.conf), así la regla aparece y desaparece con el túnel:

[Interface]
MTU = 1420
PostUp = iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
PostDown = iptables -t mangle -D FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

Un MTU de 1420 es el valor por defecto de WireGuard y es seguro en una ruta normal de 1500 bytes. Para TCP sobre IPv4, MSS = MTU − 40, así que 1420 da un MSS de 1380. Si el servidor solo envía su propio tráfico y no enruta para nadie, normalmente no necesitas limitar el MSS: el kernel elige el MSS según el MTU de la interfaz y tcp_mtu_probing se encarga del resto.

Paso 6: Compara antes y después con iperf3

Haz la misma prueba antes y después del cambio, a una hora parecida del día. Instala iperf3 en ambos extremos (apt install iperf3 o dnf install iperf3):

# On the VPS (allow TCP 5201 in the firewall only for the test)
iperf3 -s

# On your own computer
iperf3 -c 203.0.113.10 -t 20            # upload: you -> VPS
iperf3 -c 203.0.113.10 -t 20 -R         # download: VPS -> you
iperf3 -c 203.0.113.10 -t 20 -R -P 4    # download, 4 parallel streams

Cómo interpretar el resultado:

  • -R es la dirección que ven los visitantes de tu web y quienes descargan archivos, porque el VPS es quien envía. Aquí lo que más pesa es el control de congestión y el búfer de envío del VPS.
  • -P 4 abre cuatro conexiones. Si cuatro flujos juntos son mucho más rápidos que uno, una sola conexión está limitada por la ventana o por las pérdidas, que es justo lo que resuelven los búferes y BBR. Si ambos son igual de lentos, revisa la ruta, la conexión del cliente o su búfer de recepción.
  • En modo -R tu ordenador es el receptor, así que su búfer de recepción también cuenta. Windows, macOS y Linux modernos lo ajustan solos, pero un router antiguo o una VPN de tu lado pueden seguir siendo el límite.
Haz pruebas cortas (20–30 segundos), detén iperf3 -s con Ctrl+C al terminar y vuelve a cerrar el puerto 5201. Las pruebas largas a toda velocidad consumen tráfico, y usar más del 70% del puerto compartido durante mucho tiempo va contra las normas de uso razonable.

Paso 7: Deshaz los cambios si hace falta

La forma más limpia de volver atrás es borrar los dos archivos y reiniciar:

sudo rm /etc/sysctl.d/99-network-tuning.conf /etc/modules-load.d/bbr.conf
sudo reboot

Borrar el archivo y ejecutar sysctl --system no restablece los valores: siguen activos hasta el próximo reinicio. Para restaurarlos sin reiniciar, aplica los valores de tu copia de seguridad. Los valores por defecto habituales en los kernels actuales de Debian/Ubuntu son:

cat /root/sysctl-before.txt
sudo sysctl -w net.ipv4.tcp_congestion_control=cubic net.core.default_qdisc=fq_codel
sudo sysctl -w net.ipv4.tcp_rmem="4096 131072 6291456" net.ipv4.tcp_wmem="4096 16384 4194304"
sudo sysctl -w net.core.rmem_max=212992 net.core.wmem_max=212992

Si también añadiste la regla de MSS, quítala con sudo nft delete table inet mssfix (o cambia -A por -D en el comando de iptables) y elimina la línea include o las líneas PostUp/PostDown de la configuración.

FAQ

¿Bajará mi ping con estos ajustes?

No. El RTT lo determinan la distancia y el enrutamiento. Los búferes y BBR permiten que una sola conexión aproveche más ancho de banda con ese RTT, y fq junto con tcp_notsent_lowat ayudan a mantener baja la latencia de cola bajo carga, pero la latencia base no cambia.

¿Es seguro usar búferes de 32 MB en un plan de 1 GB?

Sí, con cargas normales. Son techos por socket, el autoajuste solo agranda un búfer cuando la conexión lo necesita de verdad y el límite global del kernel, tcp_mem, se calcula a partir de tu RAM. En el plan mini de 512 MB, 16 MB es una buena elección.

La velocidad sigue baja tras el ajuste. ¿Qué envío a soporte?

Abre un ticket en Technical support con la IP del servidor, la hora con zona horaria, tus resultados de iperf3 con y sin -R y -P 4, y la salida de mtr en ambos sentidos. Nuestra guía de prueba de velocidad explica cómo obtenerlos. JUSTG ofrece soporte con IA 24/7 por ticket, y los ingenieros se encargan de los casos que necesitan a una persona.

¿Le ha resultado útil esta respuesta?
Centro de ayuda
AlipayUnionPayVISAMastercardPayPalUSDTstripe