curl はHTTPの「何でも屋」。ブラウザやGUIツールを開かなくても、コマンド1行でAPIの応答・ステータス・ヘッダ・TLSの中身まで確認できます。この記事は「やりたいこと→コマンド→注意点」のユースケース逆引きで、疎通確認・認証・ヘルスチェック・CDN確認の実務断片をまとめました。最後に1画面で引ける逆引き早見表も付けています。

01なぜcurlか — HTTPの「何でも屋」

curl(カール)は、HTTPリクエストをコマンド1本で送れるツールです。ブラウザやPostmanのようなGUIを開かなくても、API・Webサーバ・ロードバランサが返す「生の応答」をその場で確認できます。

「つながらない」「500が返る」「なぜか遅い」——こうしたときの疎通確認の第一手がcurlです。名前解決(DNS)・TCP接続・TLSハンドシェイク・HTTPステータスのどこで詰まっているのかを、1コマンドずつ切り分けられます。

現場のコツ:まず curl -I URL でステータスとヘッダだけ見るのが定番です。本文をダラダラ流さずに「生きているか」を確認できます。
HTTPやTLSそのものの仕組みがあいまいなら、先に クラウドエンジニアの基礎(TCP/IP・HTTP・TLS) を通しておくと、curlの各オプションが「何を確かめているのか」まで腑に落ちます。

02基本オプション — まずこれだけ

最初に覚えるのはこの7つで十分です。組み合わせるだけで大半の確認ができます。

# ヘッダ+本文を表示(-i)
curl -i https://api.example.com/health

# ヘッダだけ=HEAD(-I)。生死とリダイレクト先の確認に
curl -I https://example.com/

# 詳細(-v):接続・TLS・送受信ヘッダまで全部見える
curl -v https://api.example.com/health

# 静かに本文だけ(-s は進捗バーを消す)
curl -s https://api.example.com/health

# 保存:-o は指定名で、-O はURL末尾のファイル名で保存
curl -s -o result.json https://api.example.com/data
curl -O https://example.com/archive.tar.gz

# リダイレクト(3xx)を自動で追う(-L)
curl -L https://example.com/
現場のコツ:スクリプトで使うなら -s(進捗を消す)と -S(エラーは出す)をセットに。curl -sS URL なら、普段は静かでエラー時だけ理由が出ます。

03ユースケース:APIを叩く

REST APIの疎通確認は、メソッド(-X)・ヘッダ(-H)・ボディ(-d)の3点セットで組み立てます。

# POST(JSONボディ)
curl -X POST https://api.example.com/v1/items \
  -H 'Content-Type: application/json' \
  -d '{"name":"widget","qty":3}'

# 大きい/厳密なボディはファイルから(改行や空白をそのまま送る)
curl -X POST https://api.example.com/v1/items \
  -H 'Content-Type: application/json' \
  --data-binary @body.json

# GET(クエリ付き。&を含むのでURL全体をクォートで囲う)
curl -s 'https://api.example.com/v1/items?limit=10&sort=desc'

# PUT / DELETE
curl -X PUT https://api.example.com/v1/items/42 \
  -H 'Content-Type: application/json' -d '{"qty":5}'
curl -X DELETE https://api.example.com/v1/items/42
-d--data)は改行を除去してから送ります(フォーム的な挙動)。JSONの改行・空白を厳密に保ちたいときは --data-binary @file を使ってください。
現場のコツ:レスポンスJSONの整形・抽出は jq と組むのが定番です。curl -s URL | jq '.items[].id' のように繋げます。jq側は jq 実践リファレンス にまとめています。

04ユースケース:認証を付ける

多くのAPIはトークンやBasic認証を要求します。認証情報はヘッダ(-H)かユーザ指定(-u)で渡します。

# Bearer トークン(一番よく使う)
curl -H 'Authorization: Bearer YOUR_TOKEN' https://api.example.com/v1/me

# トークンは環境変数に置いてコマンド履歴に残さない
export TOKEN="YOUR_TOKEN"
curl -H "Authorization: Bearer $TOKEN" https://api.example.com/v1/me

# Basic 認証(user:pass)。パスワードを省略すると対話入力にできる
curl -u alice:YOUR_PASSWORD https://api.example.com/private
curl -u alice https://api.example.com/private

# APIキーを独自ヘッダで
curl -H 'X-API-Key: YOUR_KEY' https://api.example.com/v1/data

AWSのAPIを直接叩きたい場合、curlには --aws-sigv4 によるSigV4署名オプションがあります。ただしリージョン・サービス名・認証情報の指定が細かく、鍵の取り回しも自前になります。AWS APIを叩くなら、署名と一時認証情報の更新を自動でやってくれる AWS CLI を推奨します。curlのSigV4は「CLIが入れられない最小環境での確認」など限定用途に留めるのが安全です。

現場のコツ:トークン・鍵・パスワードは、コマンド履歴・スクリプト・Gitに残さないこと。環境変数や認証情報ファイル、AWSなら一時認証情報(STS)を使います。記事中の YOUR_TOKEN などは、必ず自分の値に置き換えるプレースホルダです。

05ユースケース:疎通とデバッグ

「どこで詰まっているか」を切り分けるのがcurlの真骨頂です。ステータス・所要時間・DNS・TLSを一つずつ確認します。

# ステータスと所要時間だけ知りたい(本文は捨てる)
curl -w '%{http_code} %{time_total}\n' -o /dev/null -s https://example.com/

# DNSを上書きして特定サーバに直接当てる(LB配下の1台を検証)
curl --resolve api.example.com:443:10.0.1.23 https://api.example.com/health

# タイムアウトを付けてハングを防ぐ
curl --connect-timeout 3 --max-time 10 https://api.example.com/health

# TLSの中身(証明書・プロトコル)を確認
curl -v https://example.com/ 2>&1 | grep -Ei 'SSL|TLS|subject|issuer|expire'
-w で使える主な変数:%{http_code}(ステータス)/%{time_namelookup}(名前解決まで)/%{time_connect}(TCP接続まで)/%{time_appconnect}(TLSまで)/%{time_total}(合計)。段階ごとの秒数を並べると「DNSが遅い」「TLSが遅い」の切り分けができます。
現場のコツ:--resolve host:port:IP/etc/hosts を汚さずにDNSだけ差し替えられます。ALBの背後にある特定AZ・特定インスタンスを名指しで確認したいときに便利です。

06ユースケース:運用(ヘルスチェック・メタデータ)

AWS運用では、ロードバランサや監視スクリプトからの疎通確認にcurlが活躍します。

ヘルスチェックの確認:ALB経由の応答と、ターゲット(EC2)を直接叩いた応答を見比べると、問題がLBとアプリのどちらにあるか切り分けられます。

# ターゲット(アプリ)を直接叩いて 200 を返すか確認
curl -i http://10.0.2.15:8080/healthz

# ALB経由の応答(ステータス行だけ)
curl -sI https://app.example.com/ | head -n 1

IMDSv2でメタデータ取得:EC2ではトークン必須の IMDSv2 が既定・推奨です。まず PUT でトークンを取得し、次にそのトークンをヘッダに付けて GET する2段階が現行の正しい手順です。

# 1) PUTでトークンを取得(TTL付き、最大21600秒)
TOKEN=$(curl -sX PUT "http://169.254.169.254/latest/api/token" \
  -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")

# 2) トークンをヘッダに付けてGET
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
  http://169.254.169.254/latest/meta-data/instance-id
トークン無しの旧 IMDSv1 の直GETは、IMDSv2必須に設定されたインスタンスでは弾かれます(応答が返りません)。PUT でトークンを取ってから X-aws-ec2-metadata-token ヘッダ付きの GET、という順を守ってください。

スクリプトでの失敗検知:監視やデプロイ後チェックでは、HTTPエラーを終了コードに反映させます。

# 4xx/5xx を「失敗」として終了コードに反映(-f)
if curl -fsS https://api.example.com/health > /dev/null; then
  echo "healthy"
else
  echo "unhealthy (exit=$?)"; exit 1
fi
現場のコツ:監視・CI・デプロイ後チェックでcurlを使うなら -f(失敗時は終了コード22で落ちる)+ -sS が基本形です。-f を付けないと 500 でも終了コード0で「成功」扱いになり、障害を見逃します。シェル側の書き方は Linux実践コマンド逆引き も参考にどうぞ。

07ユースケース:CDN・キャッシュ確認

CDNが効いているか、キャッシュがHIT/MISSのどちらかは、レスポンスヘッダを見れば分かります。本体をダウンロードせずHEADで確認するのがコツです。

# キャッシュ関連ヘッダだけ抜き出す
curl -sI https://cdn.example.com/assets/app.js | grep -iE 'cache|age|etag|x-cache|cf-'

# 部分取得(Range):先頭1KBだけ取得して確認
curl -r 0-1023 -o head.bin https://cdn.example.com/large.bin
判断材料になる主なヘッダ:CloudFrontは X-CacheHit from cloudfront / Miss from cloudfront)と Age、Cloudflareは CF-Cache-StatusHITMISSEXPIRED)。加えて多くのCDNで Cache-ControlETagAge が効きます。ヒット率が上がらないときは、まずこれらのヘッダを突き合わせます。CDNごとの違いは CDN比較(CloudFront/Cloudflare/Akamai) にまとめています。
現場のコツ:-I(HEAD)ならオブジェクト本体を落とさずにヘッダだけ確認できます。大きなアセットのキャッシュ状態確認はHEADで十分なことが多いです。

08つまずきポイント

スペースや記号を含むクエリは、自前で組み立てず --data-urlencode にエンコードさせます。

# フォーム値を安全にURLエンコードして送る
curl -G https://api.example.com/search \
  --data-urlencode 'q=hello world & more' \
  --data-urlencode 'lang=ja'
# -G を付けると --data-* をボディではなくクエリ文字列に回す(GETになる)
現場のコツ:-d の自動POST化と Content-Type の既定は「ハマりの二大巨頭」です。JSON APIでは -X POST(または -d に任せる)+ -H 'Content-Type: application/json' をセットで書く癖をつけると事故りません。

09逆引き早見表(1画面チートシート)

「やりたいこと」から引けるようにまとめました。ブックマークして、そのままコピペで使えます。

やりたいことcurlコマンド
ステータス+ヘッダを見るcurl -i URL
ヘッダだけ(HEAD)curl -I URL
詳細(TLS・接続)を見るcurl -v URL
静かに本文だけ取得curl -s URL
ファイルに保存curl -o out.json URLcurl -O URL
リダイレクトを追うcurl -L URL
JSONをPOSTcurl -X POST -H 'Content-Type: application/json' -d '{...}' URL
Bearer認証を付けるcurl -H 'Authorization: Bearer YOUR_TOKEN' URL
ステータス+所要時間だけcurl -w '%{http_code} %{time_total}\n' -o /dev/null -s URL
DNSを上書きして当てるcurl --resolve host:443:IP https://host/
タイムアウトを付けるcurl --connect-timeout 3 --max-time 10 URL
失敗を終了コードに反映curl -fsS URL
キャッシュ状態を確認curl -sI URL | grep -i x-cache
IMDSv2でメタデータ取得PUTでトークン取得 → X-aws-ec2-metadata-token 付きGET
curlは「HTTPのどこで詰まったか」を最短で切り分ける道具です。EMWでは、こうした基礎ツールを手に馴染ませながらAWSの設計・運用を学べます。採用情報・カジュアル面談はこちら

10よくある質問(FAQ)

curlとwget、どちらを使えばいい?

単発のAPI疎通・ヘッダ確認・デバッグは curl が得意です(HTTPメソッド指定やヘッダ操作が柔軟)。大きなファイルのダウンロードやサイトのミラーリングは wget が向きます。運用の切り分けでは、まず curl を1つ手に馴染ませておくと応用が利きます。

-k を使わないと証明書エラーで確認できません。

-k(検証無効化)は原因を隠すだけで、本番運用では危険です。多くは中間CA証明書の不足・時刻ずれ・SNI不一致が原因です。まず curl -v でどの証明書のどこで失敗しているかを確認し、--cacert で正しいCAを指定するか、サーバ側の証明書チェーン設定を直すのが本筋です。

JSONをPOSTしているのにサーバが受け取れません。

-d だけだと Content-Type がフォーム扱い(application/x-www-form-urlencoded)になります。-H 'Content-Type: application/json' を必ず付けてください。改行や構造を厳密に保ちたい場合は --data-binary @body.json を使うと安全です。

シェルスクリプトの監視でHTTPエラーを検知したい。

-f(--fail)を付けると 4xx/5xx で終了コードが非0(22)になり、if 文やCIで失敗として扱えます。進捗を消しつつエラーは表示する -sS と合わせて curl -fsS URL が定番です。-f なしだと 500 でも終了コード0になり見逃します。

curlのような基礎ツールを「なぜ・いつ使うか」まで含めて身につけたい方へ。EMWは札幌からAWSの設計・運用・移行を支援しています。基礎から積み上げたいエンジニアのカジュアル面談も歓迎です。

相談する
← ブログ一覧へ戻る