Android Emulator は仮想ネットワークを持っていて、 DNS は /etc/resolv.conf を参照する

在宅勤務でアプリ開発をしているんですが、デバッグ時に開発サーバと接続するために必要なのが各種 VPN ソフトウェアだと思います。

Android アプリ開発の場合、 PC で Android Emulator を起動し (あるいは実機に apk を転送し) 、アプリの挙動を見ると思うのですが、特定の VPN ソフトウェアとの組み合わせでは Android Emulator から VPN を経由して ACL のあるネットワークを見てくれないことがありました。

Android Emulator のネットワークまわりはかなりややこしいことをしているらしく、 DNS 設定は /etc/resolv.conf しか参照してもらえないようです。

developer.android.com

Linux および OS X の場合、エミュレータは /etc/resolv.conf ファイルを解析して DNS サーバーのアドレスを取得します。Windows の場合は、GetNetworkParams() API を呼び出してアドレスを取得します。このプロセスでは通常、エミュレータが「hosts」ファイル(Linux/OS X では /etc/hosts、Windows では %WINDOWS%/system32/HOSTS)の内容を無視する点に注意する必要があります。

resolver まわりを少しでも触ったことがあれば知ってるかもしれませんが、 MacLinux では DNS の設定に /etc/resolv.conf 以外にも /etc/resolver/ 配下のディレクトリ内にファイルを記述することができます。

Akamai EAA と言う VPN ソフトウェアでは、 /etc/resolver/ 配下に VPN 経路での DNS 情報を記述するため、 Android Emulator からは参照されず VPN 外の経路を通ってネットワークに接続しようとするため、 Android Emulator からは開発サーバが見えないといった問題がおきてしました。

恐らく DNS だけの問題なので、接続先の開発サーバをドメイン名ではなく IP アドレスで記述すれば接続できるような気がします (未検証) 。

今回は、別用途で用意していた Forward Proxy サーバがあったので、そこを経由するようにして無事開発サーバに接続できるようになりました。

ちなみに iPhone Simulator は仮想マシンではなく、またネットワークも PC のデバイスを直接使うように振る舞うため、 Akamai EAA を利用していても問題なく通信することができます。