🙌

VPN接続時にWebサイトがうまく表示されない

2025/01/10に公開

VPN接続時にWebサイトがうまく表示されない

背景

先日Webアプリを自宅ネットワーク内のサーバにデプロイしました。
公開せずに自宅や外出先にかかわらずWebアプリが利用できるといいなと思ったのですが、VPNを介したアクセスで躓いたので記事にしようと思いました。

事象詳細

自宅ネットワークからは接続できました。
次に、モバイル回線を利用して自宅ネットワーク内のルータとVPN接続を確立した状態でアクセスを試みましたが、正常に表示されませんでした。
VPNはOpenVPNを利用しています。

alt text


考察

スマートフォンでは、Developerモードや診断ツール(pingやdigなど)が標準搭載されていないため、実際のアクセス状況から問題を推測しました。

現象の観察結果

  • VPNを介してインターネットには正常に接続できている。
  • 他の既製アプリは問題なく利用できている。
  • 表示が遅く、ロードアイコンが回り続ける → 通信遅延の可能性。
  • HTTPS/HTTPに関係なく、ページの一部は表示されるが、JSやCSSの読み込みが失敗 → ネットワークには部分的に到達している。
  • ドメインではなくIPアドレスを直接指定しても同様の問題 → 名前解決の問題ではない。

仮説

問題を整理し、以下の可能性を検討しました:

  1. モバイル回線のポート制限
    → 調査した結果、ポート制限は行われていないと判断。
  2. VPN接続の問題
    → 既製アプリが利用できるため、VPN接続には問題なし。
  3. ファイアウォールやネットワーク制限
    → ルータやサーバの設定を確認した結果、制限はなし。
  4. DNS設定の問題
    → IPアドレスでも同様のため、DNSは問題ない。
  5. ブラウザキャッシュの影響
    → キャッシュを削除しても変化なし。
  6. MTUサイズの問題
    → MTUサイズの問題が最も可能性が高い。

解決策

1. MTU値の特定

  • スマートフォンに「a-shell」というアプリをインストールし、pingコマンドを利用できるようにします。
  • 次に、以下のコマンドでMTU値を特定します。-sオプションで送信サイズを10ずつ減らし、成功するサイズを確認します。

失敗する例

ping -D -v -s 1500 -c 1 8.8.8.8

PING 8.8.8.8: 1500 data bytes
ping: sendto: Message too long

--- 8.8.8.8 ping statistics ---
1 packets transmitted, 0 packets received, 100.0% packet loss

成功する例

ping -D -v -s 1420 -c 1 8.8.8.8

PING 8.8.8.8: 1420 data bytes
1428 bytes from 8.8.8.8: icmp_seq=0 ttl=57 time=112.735 ms

--- 8.8.8.8 ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 112.735/112.735/112.735/0.000 ms

2. MSSの計算

MTUから40を引いてMSSを算出します(TCP/UDPヘッダー20バイト + IPヘッダー20バイトを除外)。

MSS = MTU - 40
MSS = 1340 - 40
MSS = 1300

3. OpenVPN設定の変更

OpenVPNの設定ファイル(.ovpnファイル)を開き、以下を追加します。

mssfix 1300

4. OpenVPNサーバの再起動

設定変更を反映させるため、OpenVPNサーバを再起動します。


原因の詳細

そもそもMTUとは

  • **MTU(Maximum Transmission Unit)**は、1度に送信可能なパケットの最大サイズを指します。イーサネットでは通常1500バイトが最大値です。
  • **MSS(Maximum Segment Size)**は、MTUからTCP/UDPヘッダーとIPヘッダーを除いたデータ部分のサイズです。
項目 MTU MSS
定義 ネットワーク層(IPレベル)で送信可能な最大パケットサイズ トランスポート層(TCPレベル)で送信可能な最大データサイズ
適用範囲 パケット全体(IPヘッダー + TCP/UDPヘッダー + ペイロード) TCPセグメントのペイロード部分(データのみ)

根本原因

  • この問題の原因は、**Path MTU Discovery (PMTUD)**が正しく動作しないことにあります。
    • VPN環境では、暗号化やNATの影響で「ICMP Destination Unreachable」メッセージがブロックされ、PMTUDが期待通りに機能しません。
    • 結果として、送信元が大きなパケットを送り続けることでパケットロスが発生し、通信がタイムアウトする状況が生じていました。

まとめ

VPN接続時にWebアプリが正しく表示されない問題は、通信におけるMTUサイズの不一致が原因でした。
VPN環境では、暗号化や追加ヘッダーの影響により、PMTUDが正しく機能せず、大きなパケットが送信され続けることで通信が妨げられることがあります。

本記事では、問題を特定するための調査手順、MTU値の特定方法、MSSの計算方法、そしてOpenVPN設定の変更による解決策を詳しく解説しました。
これらの手順を適用することで、同様の問題を解決し、VPN経由でもWebアプリが正常に表示されるようになる可能性があります。

ぜひ参考にしてみてください。

Discussion