SSD Nodes Learn Hosting plans →
ガイド Matt Connor著者 Matt Connor

異なるプロバイダーのVPSをWireGuardで接続する方法

異なるプロバイダーのVPSを1つのシステムとして連携する方法を解説します。WireGuardで暗号化し、遅延や両端の外向き通信コストも確認できます。

異なるプロバイダーの2台のVPSを1つのシステムとして連携できますか

はい。異なるプロバイダー間で2台のVPSを接続するには、プライベートネットワークを自分で構築します。通常は WireGuard を使い、パブリックインターネット上に暗号化されたオーバーレイネットワークを構成します。各プロバイダーのプライベートネットワークは自社のネットワーク境界で終わるため、プロバイダーが接続を構成してくれることはありません。接続に伴うコストとして、設定では解消できない遅延と、両端で計測される外向き通信の転送量が発生します。また、トンネル内ではパケットのサイズが小さくなるため、ネットワーク障害とは分かりにくい問題が起きることもあります。

通常、別の質問として扱われるのは、誰がマシンを管理するかです。これは マネージド VPS とアンマネージド VPS の違いに関する質問 であり、別の論点です。このページでは相互運用性を扱います。つまり、東京のサーバーと別の国にあるサーバーが1つのプライベートアドレス範囲を共有し、名前で互いを検索し、互いの通信を受け入れ、その他の通信を拒否できるかどうかを説明します。

日本の利用者にとって一般的な構成は、東京または大阪のVPSで国内ユーザー向けのサービスを提供し、海外の安価なVPSでバッチ処理、バックアップ、またはビルド処理を実行する形です。この分担は適しています。一方、同じ2台のサーバーに1つのリクエスト経路を分散すると、通常はうまくいきません。その理由をこのページの以降で説明します。

プロバイダーのプライベートネットワークが自社の境界で止まる理由

プロバイダーのプライベートネットワークは、そのプロバイダーのデータセンター内にある仮想 LAN(local area network)です。2 番目のインターフェースに割り当てられた 10.x.x.x アドレスは、そのプロバイダーのスイッチによってのみルーティングされます。RFC 1918 のプライベートアドレスであり、プライベートアドレスはパブリックインターネット上ではルーティングされません。10.0.0.5 宛てのパケットをインターネットへ送信すると、それを認識するプロバイダー外部の最初のルーターで破棄されます。そのため、2 つのアカウントを接続する設定は、どちらのコントロールパネルにもありません。同じプロバイダー内では事情が異なります。両方のマシンが同じアカウントにある場合は、同じプロバイダーの 2 台のマシン間にある無料のプライベートネットワークが適切な手段です。

プロバイダーをまたぐ通信では、管理できないトランジットネットワークやインターネットエクスチェンジを通過します。平文で送信したデータは、そこで読み取られます。オーバーレイは任意の追加対策ではありません。それが接続手段です。

競合しないアドレスを選ぶ

鍵を生成する前に実施します。両方のサーバーで次を実行します。

ip -4 addr show
ip route show
ip -4 addr show docker0 2>/dev/null

すでに使用されている範囲をすべて記録します。2 つのプロバイダーが重複する RFC 1918 範囲を割り当てることは珍しくありません。また、Docker はデフォルトで docker0 に 172.17.0.0/16 を割り当てます。どちらの一覧にも存在しないオーバーレイ範囲を選びます。たとえば 10.83.7.0/24 です。192.168.0.0/24 と 192.168.1.0/24 は避けてください。同じオーバーレイにノート PC を追加した時点で、自宅ルーターと競合するためです。

重複していてもエラーにはなりません。カーネルが最も具体的な一致ルートを選ぶため、誤った経路になります。より広いプロバイダーのルートは選ばれません。たとえば、オーバーレイが 10.0.0.0/24 で、プロバイダーが 2 番目のインターフェイスから 10.0.0.0/16 をルーティングする場合、wg0 の /24 が優先され、ピアのパケットはトンネルに入ります。問題になるのは、オーバーレイと同じか、それより具体的なプロバイダーのルートです。2 番目のインターフェイスに接続済みの 10.0.0.0/24 がある場合や、ピアのアドレスを含む 10.0.0.0/25 のような、さらに狭い範囲がある場合、ピア宛てのパケットがプロバイダーのネットワークから送信され、ログにも記録されずに失われることがあります。

各マシンにその範囲内の固定アドレスを割り当て、記録します。このガイドでは、東京のサーバーに 10.83.7.1、海外のサーバーに 10.83.7.2 を使用します。

トンネルを構築する: 両方のボックスで WireGuard を設定する

WireGuard にはクライアント役割やサーバー役割はありません。両方のマシンで同じソフトウェアを実行し、それぞれが 1 組の鍵を保持して、相手を peer として登録します。各ボックスで次を実行します。

sudo apt update && sudo apt install -y wireguard
sudo install -d -m 700 /etc/wireguard
sudo sh -c 'umask 077; wg genkey > /etc/wireguard/host.key'
sudo sh -c 'wg pubkey < /etc/wireguard/host.key > /etc/wireguard/host.pub'
sudo chmod 600 /etc/wireguard/host.key
sudo cat /etc/wireguard/host.pub

東京のボックスでは、ここでの公開アドレスが 203.0.113.10 なので、/etc/wireguard/wg0.conf を記述します。

[Interface]
Address = 10.83.7.1/24
ListenPort = 51820
PrivateKey = <contents of host.key on the Tokyo box>

[Peer]
PublicKey = <contents of host.pub on the overseas box>
AllowedIPs = 10.83.7.2/32
Endpoint = 198.51.100.20:51820
PersistentKeepalive = 25

海外のボックスでは、ここでの公開アドレスが 198.51.100.20 なので、同じファイルに次を記述します。

[Interface]
Address = 10.83.7.2/24
ListenPort = 51820
PrivateKey = <contents of host.key on the overseas box>

[Peer]
PublicKey = <contents of host.pub on the Tokyo box>
AllowedIPs = 10.83.7.1/32
Endpoint = 203.0.113.10:51820
PersistentKeepalive = 25

両方で sudo chmod 600 /etc/wireguard/wg0.conf を実行します。AllowedIPs がアクセスモデル全体を定義します。送信時にパケットをどの peer へ送るか、受信時にその peer からどの送信元アドレスを受け入れるかを決めます。WireGuard が公開鍵をアドレス範囲に関連付ける仕組みである Cryptokey routing は、3 台目のマシンを追加する前に一度読んでおくとよいでしょう。2 台のボックスを対等に接続するのではなく、1 台で多数のクライアントを提供する場合は、WireGuard サーバー完全ガイドを参照してください。

両端が公開アドレスを持つ場合、PersistentKeepalive = 25 は必須ではありません。それでも設定してください。多くのプロバイダーはインスタンスの前段にステートフルファイアウォールを配置しています。その UDP エントリは 1、2 分通信がないと期限切れになるため、アイドル状態の後に送信した最初のパケットが破棄され、リンクの復旧が遅いように見えることがあります。

起動して確認します。

sudo systemctl enable --now wg-quick@wg0
sudo wg show
ping -c 3 10.83.7.2

wg show には、数秒前の latest handshake と、両方向の転送カウンターが 0 ではない値で表示されるはずです。ハンドシェイク行がない peer では、パケットが到達していません。プロバイダー独自のネットワークファイアウォールで UDP 51820 を許可してください。これは多くの管理パネルで ufw とは別の制御です。その後、受信側のボックスで sudo tcpdump -ni any udp port 51820 を実行し、パケットがそもそも到達しているか確認します。

公開インターフェイスではなくトンネルをファイアウォールで保護する

このリンクの目的は、サービスが公開アドレスで待ち受けないようにすることです。各サービスをオーバーレイアドレスにバインドします。PostgreSQL では listen_addresses = '10.83.7.1' を postgresql.conf に設定します。その他の多くのデーモンでは、bind または address の行を設定します。

次に、トンネルインターフェイスだけでポートを開きます。

sudo ufw allow from 198.51.100.20 to any port 51820 proto udp
sudo ufw allow in on wg0 to any port 5432 proto tcp
sudo ufw enable

最初のルールだけが、このリンクに必要な公開範囲です。対象も 1 つのアドレスに限定されています。2 番目のルールは、インターネットからのパケットには一致しません。パケットが wg0 に現れるのは、WireGuard が復号し、その送信元がピアの AllowedIPs と一致することを確認した後だけだからです。これらのルールに慣れていない場合は、VPS の ufw ファイアウォールの基本でデフォルトポリシーとルールの順序を説明しています。

オーバーレイにバインドすると、別の問題が発生することがあります。wg0 が存在する前にサービスが起動すると、そのアドレスはまだマシンに設定されていないため、バインドに失敗します。PostgreSQL は次のように明確なエラーを出します。

could not bind IPv4 address "10.83.7.1": Cannot assign requested address

最も簡単な対処は、まだ存在しないアドレスへのバインドを許可することです。

echo 'net.ipv4.ip_nonlocal_bind = 1' | sudo tee /etc/sysctl.d/99-overlay.conf
sudo sysctl --system

もう 1 つの方法は、トンネルの後にサーバーが起動するよう順序を設定することです。ただし Ubuntu では、編集する unit は分かりやすい名前のものではありません。postgresql.service は起動コマンドが /bin/true である包括的な unit にすぎません。サーバー自体は Ubuntu 24.04 ではクラスタごとの unit である postgresql@16-main として実行され、包括的な unit より先に起動するよう設定されています。そのため、postgresql に drop-in を追加しても、必要な起動処理は遅延しません。sudo systemctl edit postgresql@16-main を使ってクラスタ unit に設定し、[Unit] の下に After=wg-quick@wg0.service 行を追加します。バージョンやクラスタ名が異なる場合は、先に systemctl list-units 'postgresql@*' を実行します。sysctl の方法のほうが簡単です。また、wg0 が停止している間でも PostgreSQL を再起動できますが、起動順序を変更する方法ではできません。

リージョン間のレイテンシがアプリケーションに与える影響

ラウンドトリップ時間(RTT)が下限になります。現在の CPU では、パケットごとの暗号化にかかる時間は 1 ミリ秒を大きく下回るため、トンネル自体が体感上の遅延になるわけではありません。距離が原因です。光ファイバー中の光速は毎秒約 200,000 km ですが、実際の経路は直線ではありません。そのため RTT は地理的な距離と、2 つのプロバイダー間で選択される経路によって決まります。

グラフTypical published round-trip times from Tokyo, and what 200 sequential queries cost
このグラフのデータ
[
  {
    "label": "Tokyo to Osaka",
    "rtt_ms": 8,
    "seconds_for_200_queries": 1.6
  },
  {
    "label": "Tokyo to Singapore",
    "rtt_ms": 70,
    "seconds_for_200_queries": 14
  },
  {
    "label": "Tokyo to US West",
    "rtt_ms": 100,
    "seconds_for_200_queries": 20
  },
  {
    "label": "Tokyo to Frankfurt",
    "rtt_ms": 235,
    "seconds_for_200_queries": 47
  }
]

これは接続性の高い経路で一般に公表されている代表値であり、2 台のサーバー間を測定した値ではありません。数値を前提に設計する前に、自分の環境で測定してください。

国内のホップで 8 ms であれば、ユーザーは遅延を意識しません。東京から米国西海岸まで 100 ms かかる場合は意識され、東京から Frankfurt まで 235 ms かかる場合は、問題の性質が変わります。多くの人が驚くのは、レイテンシが積み重なる点です。オブジェクトリレーショナルマッパーを使って構築されたアプリケーションでは、200 回のデータベースクエリを順番に実行することがあります。各クエリで 1 回の RTT が発生するため、クエリが 1 バイトも処理しない段階で、国内リンクでは 1.6 秒、Frankfurt リンクでは 47 秒かかります。

スループットも同じ原因の影響を受けます。TCP ストリームで転送中の未確認応答データを保持できるウィンドウは 1 つだけなので、上限はウィンドウサイズを RTT で割った値になります。Linux は net.ipv4.tcp_rmem の最大値までウィンドウを自動的に拡大しますが、経路が長いとパケット損失によってウィンドウが縮小し、回復にも時間がかかります。1 本の rsync ストリームで大きなバックアップをコピーすると、同じコピーを 8 本の並列ストリームに分割した場合より大幅に遅くなります。

自分のリンクを正確に測定する方法

ping -c 100 10.83.7.2 を実行し、1 回のサンプルではなく min/avg/max/mdev の要約行を確認します。mdev が大きい場合、経路が不安定です。平均値が高い場合よりも、アプリケーションへの影響が大きくなります。次に、一方のサーバーで iperf3 -s、もう一方で iperf3 -c 10.83.7.2 -t 30 を実行して単一ストリームを測定し、その後 iperf3 -c 10.83.7.2 -t 30 -P 8 で 8 本のストリームを測定します。8 本のストリームが 1 本より大幅に速い場合、制限要因は帯域幅ではなく、ウィンドウサイズとパケット損失です。最後に、実際の処理時間を測定します。トンネル越しに psql 内で \timing を使って 1 つのクエリを計測するほうが、合成テストより多くの情報を得られます。

送信課金は両端で発生する

ほぼすべてのプロバイダーは送信データを従量課金し、受信データを無料にしています。トンネルでは双方向にトラフィックが流れるため、Tokyo のサーバーが送信するデータは Tokyo のプロバイダーから課金され、overseas のサーバーが送信するデータは overseas のプロバイダーから課金されます。2026 年 9 月時点でも、これが一般的な仕組みです。ただし、ホストによって無料枠と超過料金は桁違いに異なるため、両方のアカウントを確認してください。

見落としやすい点が 2 つあります。バックアップとレプリケーションのトラフィックは送信側で全量が課金されます。そのため、Tokyo から毎晩取得する 50 GB のデータベースダンプは、overseas 側ではなく、毎晩 Tokyo の無料枠を 50 GB 消費します。また、WireGuard のパケットごとのオーバーヘッドも課金対象のトラフィックです。1500 byte のパケットを最大サイズで送る場合は約 4 パーセントなので、通常は気になりません。しかし、100 byte のペイロードを送る通信量の多いプロトコルでは、各パケットが回線上で 160 byte になるため、オーバーヘッドはペイロードの 60 パーセントに達します。

ここでの設計は単純です。リクエストごとではなく、スケジュールしたバッチ単位でデータを移動し、送信前に圧縮します。通信量の多い処理は、リンクの片側に寄せてください。

MTU とフラグメンテーションは小さな転送ではなく大きな転送を壊す

MTU (maximum transmission unit) は、インターフェイスが送信できる最大パケットサイズです。WireGuard は元のパケットを外側の IP ヘッダー、UDP ヘッダー、独自のメッセージヘッダー、認証タグでカプセル化します。

グラフWireGuard overhead and the tunnel MTU that fits
このグラフのデータ
[
  {
    "label": "1500 byte path, IPv4 outer",
    "overhead_bytes": 60,
    "tunnel_mtu": 1440
  },
  {
    "label": "1500 byte path, IPv6 outer",
    "overhead_bytes": 80,
    "tunnel_mtu": 1420
  },
  {
    "label": "1492 byte path, IPv4 outer",
    "overhead_bytes": 60,
    "tunnel_mtu": 1432
  },
  {
    "label": "1400 byte path, IPv4 outer",
    "overhead_bytes": 60,
    "tunnel_mtu": 1340
  }
]

IPv4 ではオーバーヘッドが 60 バイトです。そのため、通常の 1500 バイトの経路では、トンネル内に 1440 バイトを収容できます。IPv6 では 80 バイトです。wg-quick は常に大きいほうの値を差し引くため、デフォルトでインターフェイスを 1420 に設定します。これは最適値ではなく、安全側の設定です。2 つのプロバイダー間のいずれかのホップが 1500 バイト未満しか扱えない場合は、必要な値はさらに小さくなります。1400 バイトの経路では、トンネル内に 1340 バイトしか収容できません。

症状には明確な特徴があります。毎回同じように混乱しやすい問題です。ping は動作します。SSH は接続でき、入力も通常どおりに感じられます。しかし apt update が停止し、大きな HTTPS レスポンスはヘッダー受信後に止まり、ファイルコピーは数 KB 進んだところで停止します。小さなパケットは通りますが、大きなパケットは通りません。カーネルは ICMP (internet control message protocol) の「fragmentation needed」メッセージから制限値を学習するはずです。しかし多くのネットワークは ICMP を破棄するため、送信側は制限値を学習できず、到達できないパケットを再送し続けます。

実際の制限値を手動で調べます。次のコマンドは 1472 バイトのペイロードを送信します。ICMP ヘッダー 8 バイトと IP ヘッダー 20 バイトを加えると、合計でちょうど 1500 バイトになります。フラグメンテーションは禁止します。

ping -M do -s 1472 -c 2 198.51.100.20

失敗した場合は、100 バイトずつ減らして試します。まず 1372、次に 1272 を試します。自分のインターフェイス上の制限は、すぐに応答として返ります。

ping: local error: message too long, mtu=1500

経路の途中にある制限は次のように応答します。メッセージ内の数値が、求めていた値です。

From 192.0.2.1 icmp_seq=1 Frag needed and DF set (mtu = 1400)

成功した最大のペイロードに 28 を加えて経路 MTU を求め、そこから 60 を引きます。その結果を両方のサーバーの [Interface] セクションに設定します。

MTU = 1340

sudo systemctl restart wg-quick@wg0 で再起動し、ping -M do -s 1312 -c 2 10.83.7.2 を使ってトンネル内でもテストを繰り返します。2 つのトンネルアドレスだけでなくサブネット全体をリンク経由でルーティングする場合は、転送経路に TCP MSS (maximum segment size) クランプを追加します。サーバーの背後にあるマシンは、トンネルの MTU を自動的に学習できないためです。

内部 DNS で 2 台のボックスが相互に名前解決できるようにする

アプリケーションの設定にオーバーレイアドレスを直接記述しないでください。マシンに名前を付けます。2 台であれば、各マシンの /etc/hosts に設定する方法が率直で、これ自体に障害要因はありません。

10.83.7.1 tokyo.internal tokyo
10.83.7.2 batch.internal batch

自分が所有するサフィックス、または明確にプライベートなサフィックスを使用してください。将来、実在するトップレベルドメインになる可能性があるサフィックスを勝手に作らないでください。そうなると、その日から内部名が他者のサーバーへ解決され始めます。マシンが 4 台または 5 台を超えたら、1 台で dnsmasq を実行し、そのマシンのオーバーレイアドレスにバインドします。他のマシンからは /etc/systemd/resolved.conf.d/ の drop-in を使用して、その DNS サーバーを参照させます。このリゾルバーは依存先になります。そのマシンが停止すると、他のマシンでの名前解決も停止するため、フォールバックとして /etc/hosts のエントリを残してください。リゾルバーやレコードタイプが初めての場合は、DNS の概要と名前解決の仕組みで要点を短く確認できます。

ハイパーバイザーを共有しなくなったため、時刻を同期する

同じプロバイダーの 2 台の VPS は、準仮想化クロックを通じて同じ物理ホストから時刻を取得することが多いため、特別な設定をしなくても相互に時刻が一致します。異なる 2 社のプロバイダーにある VPS は、何も共有しません。それぞれ独立して時刻がずれます。仮想マシンは、停止した vCPU がタイマー割り込みを取り逃すため、物理マシンより大きくずれます。

時刻のずれは、時計の問題に見えない障害として現れます。時計が遅れているマシンでは、TLS (transport layer security) の検証が「certificate is not yet valid」というエラーで失敗します。一方のマシンで発行した JWT (JSON web token) は、nbf クレームが未来の時刻を示すため、もう一方のマシンで拒否されます。2 台のマシンのログ行が誤った順序で混在し、インシデントの時系列が事実と異なります。両方に chrony をインストールします。

sudo apt install -y chrony
chronyc tracking
chronyc sources -v

chronyc tracking は、現在のオフセットを示す System time 行を出力します。1 ミリ秒未満なら正常です。1 秒を超える場合は、後回しにせず直ちに対処します。日本のマシンでは、近隣のソースを使うと経路を短縮できます。/etc/chrony/chrony.conf に server ntp.nict.jp iburst を追加します。ntp.nict.jp は、日本の国立研究開発法人情報通信研究機構が運用する公開サービスです。海外のマシンにも同じ理由で近隣のソースを指定し、その後 sudo systemctl restart chrony を実行します。続いて chronyc sources -v を再度確認し、^* が付いたソースがあることを確認します。

管理する鍵、または依存する調整サービス

上記の構成には、第三者は関与しません。2 つの秘密鍵を自分で管理し、両方のサーバーが稼働している限り接続は機能します。代わりに、管理作業が必要です。新しいマシンを追加するたびに、他のすべてのマシンの [Peer] ブロックを編集する必要があります。鍵のローテーションも、手動で実施する作業として覚えておかなければなりません。マシンが 2 台または 3 台なら問題ありません。しかし 15 台になると、重複するアドレスや古いピアが発生し始めます。

Tailscale と NetBird は、この管理作業を調整サーバーに移します。どちらもデータプレーンとして WireGuard を使用し、その上に鍵の配布、アドレス割り当て、NAT(ネットワークアドレス変換)トラバーサル、アクセスルールを追加します。Headscale は、Tailscale クライアント向けに自分でホストできるオープンソースの調整サーバーです。通信は引き続き 2 台のサーバー間を直接流れ、調整サーバーが通信を暗号化する鍵を保持することはありません。ただし、調整サーバーに到達できない間は、新しいピアを参加させることも、鍵をローテーションすることもできません。WireGuard を自分で運用するか、調整サーバーに任せるかの違いは、主に 1 年後に何台のマシンを運用しているかで決まります。海外のサーバーから国内のサーバーの背後にあるプライベートネットワーク全体へ、単一のアドレスではなく接続したい場合は、プライベートネットワークの範囲を広告するサブネットルーターが必要です。手動で構成する場合は、転送を行うサーバー上で AllowedIPs エントリと net.ipv4.ip_forward = 1 を一致させる必要があります。

プロバイダー間で分割すべきでないワークロード

リンクをまたぐと成立しなくなる処理があり、チューニングでは解決できません。プライマリが同期レプリカからの確認応答を待つデータベースでは、書き込みのたびに RTT 全体が追加されます。遠隔地のデータベースをアプリケーションが照会すると、照会ごとに 1 RTT が発生します。上のグラフでは、この遅延が秒単位で示されています。100 ms の経路上で NFS(network file system)のようなネットワークファイルシステムを使うと、実用になりません。メタデータ操作では小さな往復が多数発生し、そのすべてをユーザーが待つ必要があるためです。etcd のようなクラスタ調整サービスでは、ハートビートが欠落すると新しいリーダーの選出が始まります。経路が長い、または遅延が変動するだけで、この状態が発生します。

適切に分割できる処理には、非同期であるという共通点があります。一方が他方を待ち続けることがありません。バッチ処理、夜間バックアップ、CI(continuous integration)のビルドランナー、ログ転送、メディアのトランスコード、ジョブを取得するキューワーカーは、長いリンクにも耐えられます。各ワークアイテムに、ワーカーが必要とする情報がすべて含まれるためです。これは、ユーザー向けに Tokyo のサーバーを置き、重い処理用に海外の安価なサーバーを置く構成に適しています。海外の安価なサーバーは x86 ではなく ARM であることが多いため、購入前に バッチワークロードが ARM で適切に動作するか を確認する価値があります。依存するすべてのコンテナイメージが、そのアーキテクチャー向けに用意されている必要があるためです。

ユーザー向けサービスとそのデータベースは、リンクの同じ側に配置してください。処理をバッチ単位で反対側へ送り、完了したら遠隔側から結果を返させます。

FAQ

プロバイダーのプライベートネットワークを使って、別のプロバイダーにあるサーバーへ接続できますか?

いいえ。プロバイダーのプライベートネットワークは、そのプロバイダー自身のデータセンター内でのみルーティングされます。また、そのネットワーク上の 10.x.x.x アドレスは RFC 1918 のプライベートアドレスであり、インターネット上のルーターは転送しません。プロバイダーの外部からそのアドレスへ送信したパケットは、最初に受信したルーターで破棄されます。2 つのプロバイダーを接続するには、インターネット上に暗号化されたオーバーレイネットワークを自分で構築します。通常は、両方のサーバーで WireGuard を実行し、それぞれに相手を peer として登録します。

2 台の VPS 間で WireGuard トンネルを使用すると、どの程度の遅延が追加されますか?

WireGuard 自体による遅延は、ほとんどありません。現在の CPU であれば、パケットごとの暗号化と復号にかかる時間は 1 ミリ秒未満です。測定される遅延の大部分は、2 つのデータセンター間の距離と、プロバイダーが選択する経路によるものです。トンネル経由で ping -c 100 を実行して確認し、1 回の測定値ではなく平均値と偏差を読み取ってください。トンネル経由の RTT が 2 つのパブリックアドレス間の RTT より大幅に悪い場合は、WireGuard の設定ではなく、CPU 飽和やパケット損失を調べます。

ping は動作するのに、トンネル経由の大容量転送が停止するのはなぜですか?

経路に対してパケットが大きすぎるのに、送信元へ通知されないためです。WireGuard は IPv4 に 60 バイトを追加するため、1500 バイトの経路でトンネル内部に運べるデータは最大 1440 バイトです。2 つのプロバイダー間の経路にこれより小さい MTU の区間があると、サイズ超過のパケットは破棄されます。さらに、ICMP をブロックするネットワークでは、「fragmentation needed」メッセージが送信元に届かないため、送信元は永久に再送を続けます。ping -M do -s 1472 <peer public address> で正常に動作するサイズを見つけ、通過するまで小さくしてください。その後、両方のサーバーの [Interface] セクションで MTU を設定します。

トンネルのトラフィックについて、両方のプロバイダーで egress 料金が発生しますか?

通常は、はい。各プロバイダーは自社のサーバーから外部へ送信される通信量を計測し、受信トラフィックは通常無料とします。そのため、双方向の通信は各端で 1 回ずつ課金されます。WireGuard のパケットごとのオーバーヘッドも課金対象となります。多数の小さなパケットを送る場合は、少数の大きなパケットを送る場合より影響が大きくなります。毎晩の同期を計画する前に、両方のアカウントで含まれる転送量と超過料金を確認してください。2026 年 9 月時点では、これらの料金はホストによって大きく異なります。

アプリケーションを一方のプロバイダーで実行し、データベースを別のプロバイダーで実行すべきですか?

ユーザーが結果を待つ処理であれば、避けてください。クエリごとに 1 回のラウンドトリップが必要です。そのため、1 ページで 200 個のクエリを発行すると、各クエリが処理を開始する前に 200 回のラウンドトリップが発生します。大陸間のリンクでは、これだけで数秒かかります。アプリケーションとデータベースは同じ側に配置してください。もう一方には、待ち合わせが発生しない処理を送ります。バックアップ、バッチジョブ、ログ転送、ビルドランナーなどが該当します。