curl --resolveで任意のホスト名をIPに固定する

  • curl
  • DNS
  • CentOS
  • SNI

この記事は、構成と文章の整理にAIを使っています。
あくまで読みやすくするための補助で、内容そのものをAIにすべて任せて書いているわけではありませんが、ところどころ相談しながら整えています。

サーバ移行の動作確認で、example.com宛のリクエストを新サーバのIPにだけ向けたいことがある。DNSはまだ切り替えたくないが、新サーバの設定(バーチャルホストやSNI)が正しいかは先に確認したい、というケース。

–resolveを使う

curl 7.21.3以降なら--resolveが使える。

curl --resolve www.example.com:80:10.0.1.2 http://www.example.com/

ホスト名:ポート:IPの形式で指定すると、curlの内部の名前解決だけをそのIPに固定してくれる。ポイントは、送信されるHTTPリクエストのHostヘッダーやTLSのSNIはwww.example.comのまま保たれること。名前解決だけをすり替えているので、バーチャルホストやHTTPS証明書のホスト名チェックも実際の運用に近い形でテストできる。

HTTPSの場合も同様に使える。

curl --resolve www.example.com:443:10.0.1.2 https://www.example.com/

7.21.2以前だと使えない

--resolveは7.21.3(2010年12月リリース)で追加されたオプションで、それより前のcurlには存在しない。その場合はHostヘッダーを直接書き換えて代用する。

curl --header "Host: www.example.com" http://10.0.1.2/

ただしこの方法だとURLの方はIPを直書きすることになるので、HTTPSでSNIまで検証したい場合は挙動が変わる(SNIにIPが乗ってしまう)点に注意。あくまでHostヘッダーだけの検証になる。

wgetにも同じ考え方のオプションがある。

wget --header="Host: www.example.com" http://10.0.1.2/

CentOS6だと地味に困る

自分の観測範囲だとCentOS6の標準curlはずっと7.19.7固定だった。RedHat/CentOSはセキュリティ修正だけをバックポートしてバージョン番号自体は上げない運用なので、リリースから何年経っても7.19.7のまま。--resolveは7.21.3以降の機能なので、CentOS6のyum標準curlでは原理的に使えない。

なのでCentOS6のサーバで検証する場合は、素直に--header "Host: ..."側で代用するしかない。ソースからビルドしたcurlを別途入れれば話は別だが、動作確認程度でそこまでやることはあまりない。

CentOS7は標準がcurl-7.29.0なので、こちらは--resolveがそのまま使える。