ローカル環境やテスト環境にホスト名やドメイン名でアクセスしたい場合、hosts
ファイルに設定を書き加えることがよくありますが、curlでちょっと確認したいだけといった場合は、いちいちhosts
ファイルを書き換えなくても、--resolve
オプションで指定できます。
hosts
ファイルを書き換える例:
# ローカルホストをmyapp.example.comでアクセスできるようにする
127.0.0.1 localhost myapp.example.com
# 開発用のVMをfoobar.example.comでアクセスできるようにする
192.168.56.123 foobar.example.com
--resolve
オプション
curlの--resolve
オプションを使用すると、その場限りでマッピングを指定できます。
--resolve ホスト名:ポート番号:IPアドレス
例えばローカルホストにhttp://myapp.example.com
でアクセスしたい場合、次のようにします。
$ curl -v --resolve myapp.example.com:80:127.0.0.1 http://myapp.example.com
今回は-v
オプションを指定したので、どのような処理が行われているのか確認してみましょう。
* Added myapp.example.com:80:127.0.0.1 to DNS cache
* Hostname myapp.example.com was found in DNS cache
* Trying 127.0.0.1:80...
* Connected to myapp.example.com (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: myapp.example.com
> User-Agent: curl/7.79.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Server: SimpleHTTP/0.6 Python/3.9.6
< Date: Thu, 30 Mar 2023 06:50:49 GMT
< Content-type: text/html; charset=utf-8
< Content-Length: 1304
<
以下レスポンスボディ
myapp.example.com
として処理しつつも127.0.0.1
に接続していることがわかると思います。
先頭2行を見た感じ、curlの持つDNSキャッシュにエントリを追加する、みたいな仕組みなんですかね(詳しい実装内容は知りません)。
どのような場合に使うのか
例に挙げたような開発環境の場合は、ブラウザでアクセスしたいことも多いと思うので、結局hosts
ファイルを書き換えることになるのですが、例えば次のようなケースで有用だったりします。
- テスト環境のサーバーに本番環境のドメイン名でアクセスする
- サーバー移転やドメイン切り替え時に、(DNSを実際に切り替える前に)切り替え後の場合のアクセスを確認する
- CDNやProxy等を経由せずに直接アクセスして検証する
- TLSのSNI(Server Name Indication)の動作確認
Hostヘッダではダメなこともある
ところで、こんな難しいオプションを使わなくても、次のようにHost
ヘッダを指定すればいいのでは? と思うかもしれません。
$ curl --header 'Host: myapp.example.com' http://127.0.0.1/
HTTPの場合は実はこれでも大丈夫なことが多いです。
ですが、HTTPSでSNI(Server Name Indication)を使用している場合は、TLSハンドシェイクの時点でホスト名を指定する必要があるため、HTTPヘッダではダメなのです(HTTPヘッダはTLS接続後の話なので)。