curlでIPアドレス指定時にドメインを偽装して検証する方法
Webサーバーの構築時やDNSの切り替え前、あるいはサイトアクセス不通時の障害調査において、「DNS上のIPアドレスではなく、特定のIPアドレスを指定して特定のドメインとしてアクセスしたい」という場面は頻繁に発生します。
通常、ローカルPCの hosts ファイル(/etc/hosts 等)を編集してドメインとIPアドレスの対応を一時的に変更する手法が用いられますが、編集の手間がかかる上、ブラウザのDNSキャッシュやTLSキャッシュによって誤った検証結果を引き起こすリスクが存在します。
本記事では、hosts ファイルを一切書き換えることなく、コマンドラインツールの curl を使用してIPアドレスへ直接アクセスしながらドメイン名を指定(偽装)して通信を検証する手法を解説します。作業時間を1回あたり数分から10秒以内へ短縮し、キャッシュの影響を受けない厳密な検証環境を構築することを目的とします。
IPアドレス直接指定で発生する通信上の問題
DNSの浸透を待たずにIPアドレスを直接指定してHTTP/HTTPSアクセスを行うと、意図したWebサイトのレスポンスが得られないケースが2パターン存在します。
1つ目は、Webサーバー側でバーチャルホスト(1つのIPアドレスで複数のドメインを運用する仕組み)が設定されている場合です。IPアドレス(例: 192.168.232.33)をそのまま指定すると、WebサーバーはどのWebサイトの要求か判断できず、デフォルトのバーチャルホスト(404 Not Foundなど)を返却します。
2つ目は、HTTPS通信(TLSハンドシェイク)におけるSSL/TLS証明書の検証エラーです。IPアドレスに対して直接HTTPS接続を試みると、サーバーから返却された証明書のドメイン名(CN/SAN)とアクセス先のIPアドレスが一致しないため、証明書エラーが発生して通信が切断されます。
curl -v https://192.168.232.33:443
SSL: no alternative certificate subject name matches target host name '192.168.232.33' Closing connection 0 curl: (60) SSL: no alternative certificate subject name matches target host name '192.168.232.33'
これらの問題を解決し、正しいドメインの応答を得るためには、curl のコマンドラインオプションを活用してリクエスト情報や名前解決を上書きする必要があります。
curlでドメインを指定・偽装する2つのアプローチ
curl でIPアドレスに接続しつつドメイン名を偽装するには、-H(Hostヘッダー指定)を使用する方法と、–resolve(名前解決の上書き)を使用する方法の2種類が存在します。用途に応じて適切に使い分けることが重要です。
Hostヘッダーを指定する方法(-H オプション)
HTTPリクエストのヘッダー情報に含まれる Host フィールドを強制的に書き換える最もシンプルな方法です。
curl -kv -H "Host: donguri3.net" https://192.168.232.33/
メリット: コマンドが簡潔であり、HTTP通信(80番ポート)のバーチャルホスト動作確認や、SSL証明書の検証をスキップ(-k オプション付与)してレスポンスボディのみを確認したい場合に適しています。
デメリット: TLSハンドシェイク時のSNI(Server Name Indication)には送信先IPアドレスまたはURLのホスト名が使われるため、-k オプションで証明書検証を無効化しない場合、SSLエラーを回避できません。
名前解決を上書きする方法(–resolve オプション)※推奨
curl 内部のDNSキャッシュを上書きし、指定した「ドメイン:ポート」の組み合わせに対する接続先IPアドレスを静的にマッピングする方法です。
curl -v --resolve donguri3.net:443:192.168.232.33 https://donguri3.net/
メリット: TLSハンドシェイク時に正しいドメイン名(donguri3.net)がSNIとして送信され、サーバー証明書の検証も正常に行われます。-k オプションを使用せず、本番環境と完全に同一のHTTPS通信手順を模倣できるため、最も信頼性の高い検証手法です。
デメリット: ポート番号とIPアドレスの指定形式(ドメイン:ポート:IP)を正しく記述する必要があります。
【実践例】curlのドメイン偽装による障害切り分け
実際にアクセス不能となったWordPressサイト(https://donguri3.net/)の障害対応において、この curl テクニックを用いて問題箇所を特定した実例を紹介します。
対象サーバーのIPアドレス(192.168.232.33)に対し、まずはIPアドレス直接指定で接続テストを行います。
curl -kv https://192.168.232.33:443
HTTP/2 404 server: LiteSpeed
レスポンスとして HTTP/2 404 が返却されたため、Webサーバー(OpenLiteSpeed)自体は起動しており、ネットワーク疎通も問題ないことが確認できました。
続いて、-H “Host: …" オプションを付与して対象ドメインの応答を要求します。
curl -kv -H "Host: donguri3.net" https://192.168.232.33/
HTTP/2 500 content-type: text/html; charset=UTF-8 ...
レスポンスとして HTTP/2 500 Internal Server Error と共に「データベース接続確立エラー」のHTMLが出力されました。この検証により、WebサーバーやTLS設定の問題ではなく、アプリケーション(WordPress)からデータベース(MariaDB)への接続不調が原因であることが一瞬で判明しました。 また、–resolve オプションを使用して正常な名前解決上書きの挙動も確認します。
curl -kv --resolve donguri3.net:443:192.168.232.33 https://donguri3.net/
同等に500エラーとデータベース接続エラーのレスポンスが確認でき、TLS検証を含めた通信経路全体に異常がないことが裏付けられました
効率的な調査による迅速な復旧効果
curl コマンドによる精細な切り分けを行った結果、hosts ファイルの変更やブラウザのキャッシュクリア作業に時間を費やすことなく、障害の原因がデータベースサービス(ols-db コンテナ)の停止にあると直ちに結論付けることができました。
無駄なWebサーバーの再起動や設定ファイルの変更を行うことなく、該当データベースコンテナの再起動コマンドを実行することで、短い作業時間でサイトの復旧を完了させました。
docker-compose restart ols-db
まとめ
Webサーバーの動作検証や障害切り分けにおいて、curl コマンドによるドメイン指定は非常に強力です。手軽なバーチャルホスト確認には -H “Host: ドメイン名" を使用し、証明書検証を含む厳密なHTTPS通信のテストには –resolve ドメイン:ポート:IP を使用することで、hosts ファイルを変更せずにキャッシュの影響を受けない検証が可能となります。実際のトラブル対応においても、IP直接アクセスとHost指定を組み合わせることで、Web層とデータベース層のエラーを10秒以内に切り分け、迅速なサイト復旧に成功しました。
