Backup de conexão com a Internet para processos específicos

Backup de conexão com a Internet para processos específicos

Gostaria de adicionar uma conexão secundária de backup à Internet ao meu servidor Linux. Pretendo usar um modem USB LTE para essa finalidade.

Como esta conexão celular será medida, quero limitar a quantidade de dados que podem ser consumidos ao mínimo necessário.

Eu tenho um aplicativo de servidor personalizado no qual posso fazer alterações. Possui algumas tarefas onde a conectividade ininterrupta é crítica e outras tarefas onde o tempo de inatividade realmente não importa.

Estou imaginando algo assim:

  • O servidor precisa fazer uma solicitação de API HTTP externa. A primeira tentativa é feita pela rota padrão do sistema (ou seja, eth0, a conexão primária com a Internet).
  • Se a solicitação falhar ou expirar, tente novamente pela interface LTE.

Somente o tráfego que meu processo de servidor deseja enviar explicitamente por LTE deve ser enviado por LTE. Nenhum outro tráfego de qualquer parte do sistema deve passar por LTE.

  • Especificamente, usarei node'slocalAddressopção de soquete para especificar que a solicitação deve ser feita por LTE.
  • Como posso garantir que outro tráfego não acabe sendo roteado pela interface LTE (mesmo que a eth0 esteja inativa)?
  • E quanto à resolução DNS?

Responder1

Acabei conseguindo isso configurando umtabela de rotas alternativase umregra de política de roteamentopara o endereço de origem da interface de backup.

O modem USB LTE que tenho apresenta-se como um dispositivo NDIS, então ele simplesmente aparece eth1com um IP de 192.168.0.190 e faz roteamento NAT internamente. Configurei eth1com um IP estático e configurei rotas manualmente.

  1. A configuração padrão usa DHCP, portanto, desative a interface e certifique-se de que todas as rotas adicionadas automaticamente sejam excluídas.

  2. Adicione uma configuração de IP estático para a interface e abra-a.

  3. Adicione entradas a uma tabela de roteamento alternativa (eu escolhi 1) para a sub-rede e o gateway padrão.

    # 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. Defina regras de política de roteamento para que os aplicativos que usam explicitamente 192.168.1.190 como endereço de origem usem a tabela de roteamento 1 em vez do padrão.

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

Neste ponto, você poderá testar sua conectividade.

$ 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

Se tudo parecer bem, torne a configuração permanente. Eu adicionei 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

Agora, apenas os aplicativos que se vinculam explicitamente a 192.168.0.190 ao fazer conexões de saída serão roteados pela conexão de backup. Todo o outro tráfego é roteado eth0(ou o que estiver configurado na maintabela de roteamento [padrão]).

Isso épossívelque você tem algo que enumera todos os IPs disponíveis e tenta enviar tráfego deles, o que pode resultar em tráfego inesperado na conexão de backup, mas isso é improvável. Não observei esse tipo de tráfego.

Observe que isso não aborda a resolução de DNS. Em uma situação em que a conexão principal está offline, você pode ter sorte e conseguir uma pesquisa no cache, mas não é bom confiar nisso. Eu também não configuraria o resolvedor de todo o sistema para enviar solicitações pela interface LTE. Em vez disso, seu aplicativo poderia lidar manualmente com a resolução de DNS ao fazer solicitações de backup.


Com o node, é fácil fazer solicitações HTTP (ou qualquer conexão TCP) a partir de um endereço de origem específico. Basta especificar olocalAddressopção, por exemplo:

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

Resolver a pesquisa de DNS é um pouco mais complicado. Também está disponível uma lookupopção que permite substituir o processo de resolução de DNS padrão. Você pode usar um personalizadodns.Resolverpara fazer pesquisas. Infelizmente, o nó não tinha como especificar o endereço de origem para pesquisas de DNS,então eu adicionei. Com isso pronto, você pode juntar as peças:

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) { … });

informação relacionada