⭐️curl: `--resolve`

https://curl.se/docs/manpage.html#--resolve

「このホスト:ポートは、この IP に繋げ」と curl に直接教えるオプション。コマンドラインから使える /etc/hosts の代わり。

curl --resolve example.com:443:127.0.0.1 https://example.com

DNS は引かず 127.0.0.1:443 に接続する。URL は example.com のままなので、Host ヘッダも SNI も証明書検証も example.com として行われる。ここが curl https://127.0.0.1 との違い。

使いどころ

  • DNS を切り替える前に、本番ドメインのまま移行先サーバーを検証する
  • hosts ファイルを汚さない(sudo 不要、戻し忘れもない)
  • ロードバランサ配下の特定の 1 台だけを狙って叩く

書式

--resolve <[+]host:port:addr[,addr]...>
  • ポートは必須。同じホストで複数ポートを見たいならその分エントリが要る
  • IPv6 は [] で囲む: --resolve example.com:443:[2001:db8::252f:efd6]
  • IP はカンマ区切りで複数可。--resolve 自体も複数回指定できる
  • ホスト名を * にすると、そのポートへの全ホストが対象。ただし具体的な指定が優先される
  • ホスト名の前に + を付けると 1 分で失効し、以後は通常の名前解決に戻る(長時間の並列転送向け)

注意

  • --ipv4 / --ipv6 を指定していても --resolve のアドレスが優先される
  • ポートを問わずホスト単位で向き先を変えたいなら --connect-to

複数 IP を渡したときの挙動

curl はこのリストを「DNS が返したアドレス一覧」と同じように扱う。

  • IPv4 だけ(または IPv6 だけ)なら、上から順に試して失敗したら次へ
  • IPv4 と IPv6 が混ざると Happy Eyeballs が働く。片方に繋ぎつつ 200ms 待って応答がなければ、もう一方にも並行して接続し、先に成功した方を使う
curl -v --resolve example.com:443:127.0.0.1,104.20.23.154 https://example.com
#   Trying 127.0.0.1:443...
# connect to 127.0.0.1 port 443 failed: Connection refused
#   Trying 104.20.23.154:443...
# Connected to example.com (104.20.23.154) port 443