2020/05/30

Qué podés hacer cuando tenés dos ISPs

Debido a que en casa estamos cambiando de ISP, hemos tenido unas semanas de doble servicio, ¿qué experimentos podemos hacer que habitualmente no con una sola conexión?

Si no estuviera un poco aburrido del asunto de la ciberseguridad, me pondría a tirar nmaps y esas cosas... bueno, lo hice igual, pero la verdad es que más es interesante...


Multitier torrent


Normalmente cuando usas bittorrent, si estás bajando algo popular alcanzás una muy alta velocidad, limitada en última instancia por los componentes cercanos a vos, o sea, tu ISP.

El experimento que voy a realizar es comparar bajar el mismo contenido de distintas maneras teniendo múltiples (dos) ISPs.

Limitaciones


No me interesa explorar si hay algún cliente que sabe cómo lidiar con la situación, pues es algo que no puedo generalizar luego para otras aplicaciones.

No puedo usar dos placas de red, pues me consta que la máquina donde puedo poner varias placas por tener bus PCI tiene contención de ese mismo bus, en otra oportunidad me afectó.

No puedo usar un dongle USB-Ethernet pues baja considerablemente la velocidad.

Tampoco pienso poner una placa en mi máquina pues en los últimos cinco años he andado con mala suerte y se me ha roto una proporción desproporcionada de las máquinas que he abierto.


Tres escenarios


En realidad son dos pero necesito uno de referencia para poder comparar.

Referencia


Hay que medir primero la performance de cada ISP por separado. Para ello agrego un router que tenía tirado por ahí y le conecto otra máquina. En ambas bajo lo mismo.

Considerá que todos estos números son un tanto imprecisos, sobre todo los del ISP 1, pues la misma conexión está siendo usada a la vez por otras personas.




Medición ISP 1

Bajé el archivo completo:

  • 3.86 GB
  • 21 minutos 1260 segundos
  • 3860398080 / 1260 = 3063808 B/s = 3.06 MB/s
  • por momentos 3.65 MB/s


Medición ISP 2


Cuando llegó a 15 minutos me aburrí, tomé estos datos parciales

  • 1.18 GB
  • 15 minutos  = 900 segundos
  • 1180000000  / 900 = 1311112 B/s = 1.31 MB/s
  • por momentos 1.54 MB/s


Vía ISP 2




Dos máquinas




Dos máquinas, cada una conectada a un ISP y aprovechar que mi cliente entiende buscar en la red local si hay alguien bajando lo mismo, de este modo quizás cada uno baje un mitad y la comparta con el otro.


Local Peer Discovery en ambas máquinas


Para esto hay que:
  • desactivar DHCP en el router del ISP2
  • poner al router en una IP de la red del ISP1, por ejemplo 192.168.1.10
  • poner a la máquina 2 con IP 192.168.1.11 y gateway 192.168.1.10
  • tirar un cable del router al switch
  • activar LPD en ambas máquinas

Pre prueba


Que una máquina vea a la otra en la red local y baje todo de ahí, ok, dejé que la segunda máquina terminara y anduvo.


Habiendo activado Local Peer Discovery


Medición dos máquinas


  • 3.86 GB
  • 16 minutos, son 960 segundos
  • 3860398080 / 960 = 4021248 B/s = 4MB/s
  • Por momentos 7MB/s


Bajada combinando un ISP y la otra instancia





Se ve la dirección local de la otra máquina


Es conveniente ejecutar en ambas máquinas como root o sudo:

$> mii-tool enp3s0
enp3s0: negotiated 100baseTx-FD flow-control, link ok


y las velocidades deberían coincidir.


Una máquina, dos rutas





En lo anterior no he cumplido con ser neutral con respecto al cliente de bittorrent, no sé si otros programas soportan LPD. Tampoco puedo contar con tener dos computadoras y espacio libre en ambas, notá que aunque bajé una sola instancia de la imagen, la tengo duplicada.

Lo que hay que hacer ahora es:
  • mantener el router del ISP2
    • DHCP desactivado
    • una IP estática conocida
    • cable al switch de la red principal
  • quitar la segunda máquina
  • LPD ya no es necesario
  • manipular sus rutas

Para manipular las rutas hace falta tener una vaga idea de cuál será la partición.

Tirando un

watch -n 10 netstat -tn >> ips.txt

toda la noche, me hice un mapa de las IPs típicas, el problema es que la salida me quedó con caracteres de escape, más o menos lo limpié con esto, seguro se puede hacer mejor:


 strings ips.txt | grep "[01234567890.]*:443" -o \
   | grep "\..*\..*\..*"  | cut -d "." -f 1-2 \
   | sort -n | uniq -c

Quitando los errores del comando anterior me deja:


      6 1.13
      5 2.16
      2 2.18
      2 2.43
      7 3.77
      2 52.1
      7 6.58
     62 8.43
      1 8.67
      3 13.33
      1 15.96
      6 16.58
      1 16.73
      1 16.74
     30 2.217
      8 23.12
      1 23.32
      1 23.55
    104 23.77
     52 3.107
    194 31.13
      3 3.223
      3 3.232
      4 34.98
      2 4.233
     12 4.244
      1 45.54
     10 5.201
    131 52.43
     54 68.67
      1 86.18
      1 88.99
     70 92.16
     31 104.87
      1 115.96
    148 13.107
      7 13.227
      1 144.76
      1 185.63
      7 186.18
    113 192.16
      1 192.73
     15 200.42
    260 216.58
      5 23.197
     10 23.222
      2 34.194
    199 35.201
      1 35.241
      2 52.195
      1 54.187
      1 54.219
    170 64.233
    297 72.217
      1 74.119
      2 74.125
      3 95.216
     99 104.244
      4 104.254
      1 108.174
      1 151.101
     16 152.195
      1 152.199
    953 172.217
     22 192.168

y agrupando a ojo:

  • redes entre 1.0.0.0 y 63.0.0.0 = 700
  • redes entre 64.0.0.0 y 127.0.0.0 = 1500
  • redes entre 128.0.0.0 y 255.0.0.0 = 1000

Ojo otra vez, esas IPs son las conexiones que hubieron durante un tiempo, no es un buen análisis pues no tengo idea del tráfico que hubo que es lo que realmente me interesa para particionar.

Veamos primero que hay:

$> route -n
Kernel IP routing table
Destination Gateway     Genmask       Flags Metric Iface
0.0.0.0     192.168.1.1 0.0.0.0       UG    100    enp3s0
169.254.0.0 0.0.0.0     255.255.0.0   U     1000   enp3s0
192.168.1.0 0.0.0.0     255.255.255.0 U     100    0     0 enp3s0



Lo que tengo que agregar es una ruta tal que el Gateway sea el router que conduce al ISP 2, esto es, 192.168.1.10. Luego usando dos servicios de identificación de cuál es mi IP, ver que uno me dice una y otro la otra.

Tengo dos, con ping -c 1 obtengo sus IP

https://whatismyipaddress.com  104.16.155.36
https://www.whatismyip.com     104.27.199.91

ufa, están muy juntas.

https://www.myip.com           172.67.208.45


Mejor, de paso ya hago el particionado en 128.0.0.0, todos los route add son como root.

route add -net 128.0.0.0 netmask 128.0.0.0 gw 192.168.1.10 metric 100

Lo que nos da:

$> route -n
Kernel IP routing table
Destination Gateway      Genmask       Flags Metric Ref Use Iface
0.0.0.0     192.168.1.1  0.0.0.0       UG    100    0   0   enp3s0
128.0.0.0   192.168.1.10 128.0.0.0     UG    100    0   0   enp3s0
169.254.0.0 0.0.0.0      255.255.0.0   U     1000   0   0   enp3s0
192.168.1.0 0.0.0.0      255.255.255.0 U     100    0   0   enp3s0



Observá las distintas IPs según a quien le preguntes


Listo para torrentear.


En uno de los momentos de máxima velocidad



  • 3.86 GB
  • 17 minutos 1020 segundos
  • 3860398080 / 1260 = 3063808 B/s = 3.78 MB/s
  • por momentos 4.77 MB/s


Resultados y reflexiones

Aun con un particionado muy bestia como el que he realizado, se pueden combinar exitosamente las velocidades de dos o más ISP.


 Modo tiempo
[s]
 velocidad
[MB/s]
 pico
[MB/s]
 ISP 1
 1260 3.06 3.65
 ISP 2
  1.31 1.54
 Dos máquinas
 960 4 7
 Dos rutas
 1020 3.78 4.77


El pico no es muy representativo, en "Dos Máquinas" indica lo que ocurrió en la LAN. Lo interesante es que la red local de 100 Mb está prácticamente saturada, si agregara un tercer proveedor como el primero no lo podría aprovechar completamente, tendría que usar una red interna de 1Gb.

Siguientes pasos


Me interesa mucho este tema, pero dentro de dos días me quedo sin el segundo ISP y la verdad es que no me paso el día bajando cosas y tengo otras muchas tan o más interesantes que hacer, lo que sigue te puede servir de inspiración para que lo hagas vos. ¿No tenés dos ISP? No hay problema, le pedís a un vecino que tenga WiFi con un proveedor distinto al tuyo mejor que te preste sus credenciales y ya tenés dos ISPs, o tres o más.


Distribución mediante DHCP


Todo lo que hice antes fué en una sola máquina, si querés que todas tus máquinas tomen esa configuración, parece que con DHCP se puede.

Balanceo dinámico con ruteo


Si tenés varios canales como es este caso y además tenés el control en ambos extremos, el balanceo debe ser sencillo, en particular en una red local lo he hecho usando trunking/bonding.

Para el caso actual, donde están de un sólo lado del caño, no es tan sencillo, habría que estar midiendo cual es el mejor camino, una combinación de ancho de banda, latencia, saltos hasta el destino. Debe existir una manera común y normal pero para mejor aprender e investigar voy a seguir sin buscarla y pensando.

Para ver el tráfico discriminado se me ocurre agregar una interfaz virtual, de este modo se puede ver la saturación y si a la vez mirás netstat, podrías ir reparticionando. Cuando le pescaste la mano, reemplazás con un script. Pero no debe ser ten fácil, ¿qué pasa con una conexión que tenés abierta si cambia el enrutamiento? ¿El kernel se dá cuenta y no te la corta? Ahí recordé que man route ofrece:

-C     operate on the kernel's routing cache.


Parece que el kernel tiene un cache y que a menos que uno le pida explícitamente, add no lo toca. Esto no sólo salvaría a una conexión existente si no que muchas otras conexiones nuevas no tomarían la nueva ruta, debe haber un TTL por ahí.

Es todo un tema, listo, ya me cansé de pensarlo.


Si ponés en google algo así como

"dynamically changing routes to balance traffic between two providers"

tenés para divertirte.




No hay comentarios:

Publicar un comentario