![特定のプロセスのためのインターネット接続のバックアップ](https://rvso.com/image/756268/%E7%89%B9%E5%AE%9A%E3%81%AE%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%8D%E3%83%83%E3%83%88%E6%8E%A5%E7%B6%9A%E3%81%AE%E3%83%90%E3%83%83%E3%82%AF%E3%82%A2%E3%83%83%E3%83%97.png)
Linux サーバーにセカンダリ バックアップ インターネット接続を追加したいと考えています。この目的のために USB LTE モデムを使用する予定です。
この携帯電話接続は従量制なので、消費できるデータの量を必要最小限に制限したいと考えています。
変更できるカスタム サーバー アプリケーションがあります。中断のない接続が重要なタスクがいくつかあり、ダウンタイムがそれほど問題にならないタスクもあります。
私は次のようなことを想像しています:
- サーバーは外部 HTTP API リクエストを行う必要があります。最初の試行はシステムのデフォルト ルート (つまり、eth0、プライマリ インターネット接続) 経由で行われます。
- 要求が失敗するかタイムアウトした場合は、LTE インターフェイス経由で要求を再試行します。
サーバー プロセスが明示的に LTE 経由で送信したいトラフィックのみを LTE 経由で送信する必要があります。システムのどの部分からのその他のトラフィックも LTE 経由で送信しないでください。
- 具体的には、ノードの
localAddress
要求を LTE 経由で行うように指定するソケット オプション。 - 他のトラフィックが LTE インターフェイス経由でルーティングされないようにするにはどうすればよいですか (eth0 がダウンしている場合でも)?
- DNS 解決はどうですか?
答え1
私は最終的に、代替ルートテーブルそしてルーティングポリシールールバックアップ インターフェイスの送信元アドレス。
eth1
私が持っている USB LTE モデムは NDIS デバイスとして表示されるため、 IP が 192.168.0.190 として表示され、内部で NAT ルーティングが行われます。eth1
静的 IP を設定し、ルートを手動で設定しました。
デフォルト設定では DHCP が使用されるため、インターフェイスを停止し、自動的に追加されたルートが削除されていることを確認します。
インターフェースに静的 IP 構成を追加して起動します。
1
サブネットとデフォルト ゲートウェイのエントリを代替ルーティング テーブル ( を選択) に追加します。# 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
ルーティング ポリシー ルールを設定して、送信元アドレスとして 192.168.1.190 を明示的に使用するアプリが、デフォルトではなくルーティング テーブル 1 を使用するようにします。
# ip rule add from 192.168.0.190/32 table 1 # ip rule add to 192.168.0.190/32 table 1
この時点で、接続をテストできるはずです。
$ 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
すべてがうまくいけば、設定を永続化します。以下を追加しました/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
これで、送信接続を行うときに 192.168.0.190 に明示的にバインドするアプリのみがバックアップ接続経由でルーティングされるようになります。その他のすべてのトラフィックはeth0
(または [デフォルト] ルーティング テーブルで構成されているものmain
) 経由でルーティングされます。
それは可能利用可能なすべての IP を列挙し、そこからトラフィックを送信しようとするものがあり、その結果、バックアップ接続で予期しないトラフィックが発生する可能性がありますが、その可能性は低いです。私はそのようなトラフィックを観察したことはありません。
これは DNS 解決には対応していないことに注意してください。プライマリ接続がオフラインの場合、運が良ければキャッシュから検索できるかもしれませんが、それに頼るのはよくありません。システム全体のリゾルバを構成して、LTE インターフェイス経由でリクエストを送信することもお勧めしません。代わりに、バックアップ リクエストを行うときに、アプリで DNS 解決を手動で処理できます。
ノードを使用すると、特定の送信元アドレスからHTTPリクエスト(または任意のTCP接続)を簡単に行うことができます。localAddress
オプション例:
https.get('https://wtfismyip.com/text', { localAddress: '192.168.0.190' }, …);
DNSルックアップの解決は少し複雑です。lookup
デフォルトのDNS解決プロセスを上書きできるオプションもあります。カスタムのdns.Resolver
残念ながら、ノードにはDNS検索のソースアドレスを指定する方法がなかったため、それで追加しました. これで、ピースをまとめることができます。
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) { … });