モバイル回線からは応答するのに、リビングからは失敗するVPNサーバーは、たいてい証明書の問題ではありません。LANの内側のクライアントは、宛先がルータ自身の公的なアドレスであるパケットの変換をルータに求めているので、パケットはいったん外に出て、そのまま戻ってこなければなりません。この動作をヘアピンと呼び、多くのルータはそれを実装していないか、チェックボックスを有効にしたときだけ実装しています。外からのテストが通ることが混乱のもとで、それは待ち受けと転送のルールが正しいことを示しているからです。

パケットは外に出て戻ってくる

パケットを追ってみましょう。クライアントは公的な名前を解決し、公的なアドレスに接続し、ルータの宛先NATが宛先を内部のサーバーに書き換えます。サーバーの応答はクライアントのLANアドレス宛てなので、送信元を戻すはずのNATルールを一度も通らずに、ルータのLANインターフェースから戻っていきます。

するとクライアントは、何も送っていないアドレスからパケットを受け取り、それを破棄します。この非対称性が障害のすべてです。

RFC 4787は、この場合にNATへ期待される振る舞いを記述しており、短く言えば、理論上規定されている場所でも実際には任意だということです。ルータによってはこの設定をNATループバックと呼び、別のものはヘアピンNATやNATリフレクションと呼び、何も公開していないものもあります。この機能がないルータは設定ミスではなく、ごく普通のことをしているだけで、対処は別の場所にあります。内部でのテストが失敗したからといって、公的な転送ルールが間違っていると結論づけないでください。

確認1:二つの経路を別々に試す

LANの外から、実際の利用者が使うのと同じプロファイルで接続し、セッションが確立することを確認します。内側からは、同じプロファイルで公的なアドレスに接続し、正確なエラーと時刻を記録します。

正確な内部テストはホスト名を保ち、アドレスだけを差し替えます:curl -v --resolve vpn.example.com:443:203.0.113.10 https://vpn.example.com/ は、正しいサーバー名を示したまま、リクエストを公的なアドレスへ送ります。これにより、名前解決の問題と変換の問題を切り分けられます。同じ名前が喫茶店から通るとき両者は混同しやすいので、クライアントがTCP接続で失敗するのか、それとも後のTLSで失敗するのかを記録してください。

確認2:サーバーに見えているものを読む

もっとも有用な観察は、サーバー側の見え方です。VPNホストで、クライアントのLANアドレスとルータのLANアドレスに絞ったキャプチャを実行し、そのうえで内部からの試行を繰り返します。何も届かなければ、パケットは変換を生き延びていません。

クライアントのアドレスではなくルータのLANアドレスから接続が届くなら、ヘアピンが起きて送信元が書き換えられています。それは動作している構成であって、故障ではありません。

確認3:外側の経路に触れずに直す

対応策は三つあり、影響の範囲が広い順に並べます。もっとも狭いのは分割DNSで、内部のレコードを公開して、同じサーバー名がLANのクライアントには内部アドレスに解決されるようにすれば、公的な経路を完全に避けられます。次は、ルータの文書化されたループバックまたはリフレクションのオプションがあれば有効にし、このサービスだけに適用する方法です。もっとも広いのは、ルータにsource-NATのルールを置き、LANからの通信をサーバー向けに書き換えて応答がルータを通って戻るようにする方法で、Linuxのルータなら、サーバーのアドレスとポートに一致する MASQUERADE の POSTROUTING に置くルールになります。三つとも外側の経路はそのままに保ち、守るべき性質はそこにあります。

無関係なポート転送を広げて内部の経路を外側に似せることも、問題を避けるためにサービスを別のポートへ移すこともやめてください。どちらも、内側だけが見ている問題を直すために、外の世界が届く範囲を変えてしまいます。

分割DNSには、名指ししておく価値のある落とし穴が一つあります。ホスト名を任意のIPに置き換えると、クライアントが検証する対象が変わるので、内部のレコードは証明書の名前と一致したままでなければなりません。

確認4:あとで両方の経路を検証する

LANの外から外側の試行を繰り返し、同じプロファイルで内側の試行を繰り返し、サーバーのログに「一つの成功と一つの沈黙」ではなく、別々の成功したセッションが二つ記録されていることを確認します。そのうえで、ほかのクライアントが今も待ち受けに届くこと、プライベート資源への経路が変わっていないことを確認します。

記録には、どのクライアントがどのアドレスを使ったか、サーバーに何が見えたか、三つの対処のどれを適用したかを短くまとめます。RFC 4787のヘアピン要件 は、ここでNATに何が期待されるかの参照であり、この機能のないルータが正常に振る舞う理由を説明しています。外の世界が再現できない内部の失敗は、そうでないと証明されるまでは変換の問題なので、その前提でテストしてください。

関連記事