Conexión a Internet de respaldo para un proceso específico

Conexión a Internet de respaldo para un proceso específico

Me gustaría agregar una conexión a Internet de respaldo secundaria a mi servidor Linux. Planeo usar un módem USB LTE para este propósito.

Debido a que esta conexión celular será medida, quiero limitar la cantidad de datos que se pueden consumir al mínimo absoluto necesario.

Tengo una aplicación de servidor personalizada en la que puedo realizar cambios. Tiene algunas tareas en las que la conectividad ininterrumpida es fundamental y otras tareas en las que el tiempo de inactividad realmente no importa.

Me estoy imaginando algo como esto:

  • El servidor necesita realizar una solicitud de API HTTP externa. El primer intento se realiza a través de la ruta predeterminada del sistema (es decir, eth0, la conexión principal a Internet).
  • Si la solicitud falla o se agota el tiempo de espera, vuelva a intentar realizar la solicitud a través de la interfaz LTE.

Sólo el tráfico que el proceso de mi servidor desea enviar explícitamente a través de LTE debe enviarse a través de LTE. Ningún otro tráfico de ninguna parte del sistema debe pasar por LTE.

  • Específicamente, usaré nodoslocalAddressopción de socket para especificar que la solicitud debe realizarse a través de LTE.
  • ¿Cómo me aseguro de que el resto del tráfico no termine enrutando a través de la interfaz LTE (incluso si eth0 está inactivo)?
  • ¿Qué pasa con la resolución DNS?

Respuesta1

Terminé logrando esto configurando untabla de ruta alternativay unregla de política de enrutamientopara la dirección de origen de la interfaz de respaldo.

El módem USB LTE que tengo se presenta como un dispositivo NDIS, por lo que simplemente aparece eth1con una IP de 192.168.0.190 y realiza enrutamiento NAT internamente. Lo configuré eth1con una IP estática y rutas configuradas manualmente.

  1. La configuración predeterminada utiliza DHCP, así que cierre la interfaz y asegúrese de que se eliminen las rutas agregadas automáticamente.

  2. Agregue una configuración de IP estática para la interfaz y ábrala.

  3. Agregue entradas a una tabla de enrutamiento alternativa (he elegido 1) para la subred y la puerta de enlace predeterminada.

    # ip route add 192.168.0.0/24 dev eth1 src 192.168.1.190 table 1
    # ip route add default via 192.168.0.1 table 1
    
  4. Establezca reglas de política de enrutamiento para que las aplicaciones que usan explícitamente 192.168.1.190 como dirección de origen usen la tabla de enrutamiento 1 en lugar de la predeterminada.

    # ip rule add from 192.168.0.190/32 table 1
    # ip rule add to 192.168.0.190/32 table 1
    

En este punto, debería poder probar su conectividad.

$ curl https://wtfismyip.com/text
1.2.3.4  # primary ISP external IP
$ curl --interface 192.168.0.190 https://wtfismyip.com/text
5.6.7.8  # backup LTE external IP

Si todo se ve bien, haga que la configuración sea permanente. Agregué a /etc/network/interfaces:

iface eth1 inet static
        address 192.168.0.190
        netmask 255.255.255.0
        post-up ip route add 192.168.0.0/24 dev eth1 src 192.168.0.190 table 1
        post-up ip route add default via 192.168.0.1 table 1
        post-up ip rule add from 192.168.0.190/32 table 1
        post-up ip rule add to 192.168.0.190/32 table 1

Ahora solo las aplicaciones que se vinculen explícitamente a 192.168.0.190 al realizar conexiones salientes se enrutarán a través de la conexión de respaldo. Todo el resto del tráfico se enruta eth0(o lo que esté configurado en la maintabla de enrutamiento [predeterminada]).

Esposibleque tiene algo que enumera todas las IP disponibles e intenta enviar tráfico desde ellas, lo que podría generar tráfico inesperado a través de la conexión de respaldo, pero eso es poco probable. No he observado ningún tráfico de este tipo.

Tenga en cuenta que esto no aborda la resolución de DNS. En una situación en la que la conexión principal está fuera de línea, es posible que tenga suerte y realice una búsqueda desde el caché, pero no es bueno confiar en eso. Tampoco configuraría el solucionador de todo el sistema para enviar solicitudes a través de la interfaz LTE. En cambio, su aplicación podría manejar manualmente la resolución de DNS al realizar solicitudes de respaldo.


Con node, realizar solicitudes HTTP (o cualquier conexión TCP) desde una dirección de origen específica es fácil. Simplemente especifique ellocalAddressopción, p.ej:

https.get('https://wtfismyip.com/text', { localAddress: '192.168.0.190' }, …);

Resolver la búsqueda de DNS es un poco más complicado. También hay una lookupopción disponible que le permite anular el proceso de resolución de DNS predeterminado. Puedes usar un personalizadodns.Resolverpara realizar búsquedas. Desafortunadamente, el nodo no tenía una manera de especificar la dirección de origen para las búsquedas de DNS,así que lo agregué. Una vez hecho esto, puedes juntar las piezas:

const resolver = new dns.Resolver();
resolver.setServers(['8.8.8.8']);
resolver.setLocalAddress('192.168.0.190'); // requires node > v15.0.0

https.get('https://wtfismyip.com/text', {
  localAddress: '192.168.0.190',
  lookup: function(hostname, opts, cb) {
    resolver.resolve(hostname, function(err, records) {
      if (err) cb(err);
      else if (!records[0]) cb(new Error('Missing DNS record'));
      else cb(null, records[0], 4);
    });
  }
}, function(res) { … });

información relacionada