access internal server with domain

LAN内部からサーバーに接続できない原因と解決方法

一番近いところは逆に接続できない?

事務所や自宅でサーバーを立ち上げたら、ネットワーク設定によって、外から正常にアクセスできたのに、LAN内部のPCからサーバーに接続できないという謎現象が発生する場合があります。
その動作を説明するために、以下の状況を仮定します。

PC 192.168.0.10
サーバー 192.168.0.11
外部IP 1.1.1.1

原因

ブラウザーでドメインネームを入力したら、まずDNSからそのドメインのIPアドレスを取得します。ここは1.1.1.1とし、PCから以下のようなパケットが生成されます。

from 192.168.0.10
to 1.1.1.1
port 80

このパケット自体は問題なくスイッチ、ルーターに送信できますが、1.1.1.1であるルーターの外部ポートに到達したら、NAT変換によってパケットヘッダーが書き換えられて、本当のサーバーに送信されます。

from 192.168.0.10
to 192.168.0.11
port 80

次はサーバーがパケットの内容を処理して、送信元であるPCのアドレス宛に返信をします。

from 192.168.0.11
to 192.168.0.10
port 80

ここが問題。

ルーターが送信元と送信先が同じLANのアドレスであることを認識して、外部ポートを経由せずに、スイッチハブ部分だけの処理でパケットを捌いてしまいます。

つまりこのパケットはそのままPCに転送されることです。この場合、PCがパケットを受け取って、自分が1.1.1.1に送信したのに、なんか知らないアドレスから返信が来たので、無効なパケットだと判断して、このパケットを捨ててしまいます。
もちろんその後1.1.1.1からの返信はいつまでも来ないので、接続がタイムアウトになります。

対処方法

原因が分かったら、対処は簡単です。

LANのIPアドレスでアクセスする

同じLANにあるなら、当然LANのアドレスで直接サーバーにアクセスすることができます。
ただし,ウェブサイトがHTTPS化している場合、SSL証明書はドメインにバインドしているため、直接IPでアクセスするとブラウザーに安全ではないと怒られるので、ストレスが溜まるしかない。

内部DNS

次の考えはドメインネームを内部IPにバンドする方法。もちろん外のDNSにローカルIPを設定するわけがないので、LAN内部でDNSサーバーを立ち上げて、LAN内のPCはそれを利用するようにする必要があります。

また、OSがこの「よくある問題」を解決するためにすでに似たような機能を提供しています。それはhostsファイル。ブラウザーにドメインネームを入力したら、外部DNSまでIPを探しに行く前に、先にhostsファイルにIPの記録があるか調べて、存在するなら外部DNSに頼らずそこのIPを利用します。
Windowsを例に言うと、(C:\Windows\System32\drivers\etc\hosts)に
ドメインネーム サーバーのローカルIP
を登録すればドメインネームから接続できるようになります。

ルーターに両方向NAT変換を設定する

何かの理由でいちいちPCのhostsファイルを弄りたくない場合、ルーターが返信を転送するとき、外部ポートを経由しない問題を何とかする方法もあります。
それはルーターのVlan設定にこのようなNATルールを追加して

nat server protocol tcp global 1.1.1.1 80 inside 192.168.0.11 80

サーバーからのパケットが必ず外部ポートにNAT変換するように設定します。これでルーターが外部ポートの1.1.1.1をソースとしてPCにパケットを送るので、外部からと同じく正常に接続できます。