「curlでPOSTを送りたいのに、サーバーから400エラーが返ってくる」
Linuxサーバーの運用では、Webサービスの死活監視、APIの動作テスト、SSL証明書の確認など、HTTPリクエストをコマンドラインから送る場面が数多くあります。
この記事では、Linuxの
curl コマンドについて、基本的なGETリクエストから、POSTでのデータ送信、レスポンスヘッダーの確認、SSL証明書の検証、認証付きアクセス、トラブルシュートまでを解説します。wget との使い分けについても触れていますので、現場で迷わず使い分けられるようになるはずです。でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
curlとは?HTTP通信を行うコマンド
curl(カール)は、HTTP・HTTPS・FTP・SFTPなど、さまざまなプロトコルに対応したデータ転送コマンドです。URLを指定してリクエストを送り、レスポンスを標準出力やファイルに取得できます。wget がファイルのダウンロードに特化しているのに対し、curl はHTTPメソッド(GET・POST・PUT・DELETE)を自由に指定でき、ヘッダーの操作やJSON送信も得意です。API連携やWebサービスの動作確認には curl が適しています。# 基本書式 # curl [オプション] URL
curl がインストールされていない場合は、以下のコマンドでインストールしてください。# RHEL/CentOS/AlmaLinux # yum install curl # Ubuntu/Debian # apt install curl
基本的な使い方(GETリクエスト)
1. URLを指定してページを取得する
最もシンプルな使い方は、URLをそのまま引数に渡す方法です。サーバーからのレスポンスボディが標準出力に表示されます。# Webページの内容を取得する $ curl https://www.example.com/
2. レスポンスをファイルに保存する(-o / -O)
取得した内容をファイルに保存するには、-o(小文字)でファイル名を指定するか、-O(大文字)でURL末尾のファイル名をそのまま使います。# ファイル名を指定して保存する $ curl -o output.html https://www.example.com/ # URL末尾のファイル名で保存する $ curl -O https://www.example.com/archive.tar.gz
-O はURLの最後のスラッシュ以降をファイル名として使います。URLの末尾がスラッシュで終わっている場合はファイル名が空になるため、その場合は -o で明示的に指定してください。3. レスポンスヘッダーを確認する(-I / -i)
サーバーからのHTTPステータスコードやContent-Typeを確認したい場合は、-I(HEADリクエスト)または -i(レスポンスヘッダー付き表示)を使います。# HEADリクエストでヘッダーだけ取得する $ curl -I https://www.example.com/ # GETリクエストでヘッダー+ボディを取得する $ curl -i https://www.example.com/
-I の出力例は以下のようになります。HTTP/1.1 200 OK Content-Type: text/html; charset=UTF-8 Content-Length: 1256 Server: Apache/2.4.62
curl -I で確認」というのは、現場のエンジニアが日常的に行う操作です。4. HTTPステータスコードだけを取得する(-w / -s)
シェルスクリプトでの死活監視に使う場合は、ステータスコードだけを取得できると便利です。# ステータスコードだけを取得する $ curl -s -o /dev/null -w '%{http_code}' https://www.example.com/ 200
・-o /dev/null:レスポンスボディを捨てる
・-w '%{http_code}':HTTPステータスコードだけを出力する
この書き方はcronで定期的にWebサーバーの応答を確認するスクリプトでよく使われます。
POSTリクエストでデータを送信する
5. フォームデータを送信する(-d)
-d(data)オプションを使うと、POSTリクエストでデータを送信できます。Content-Typeは自動的に application/x-www-form-urlencoded に設定されます。# フォームデータをPOSTで送信する $ curl -d 'username=admin&password=secret' https://www.example.com/login
6. JSONデータを送信する(-H / -d)
REST APIにJSONを送る場合は、-H(Header)でContent-Typeを指定し、-d でJSONデータを渡します。# JSONデータをPOSTで送信する $ curl -X POST \ -H 'Content-Type: application/json' \ -d '{"name":"test","value":123}' \ https://api.example.com/data
・-H 'Content-Type: application/json':リクエストヘッダーを追加する
-d を使うと自動的にPOSTメソッドになるため、-X POST は省略しても動作します。ただし、可読性のために明示しておくことを推奨します。7. ファイルの内容をPOSTで送信する(@ファイル名)
JSONデータが長い場合は、ファイルに書いておいて@ で指定するのが便利です。# ファイルの内容をPOSTで送信する $ curl -X POST \ -H 'Content-Type: application/json' \ -d @request.json \ https://api.example.com/data
実務で役立つcurlの応用テクニック
8. リダイレクトを自動的にたどる(-L)
Webサーバーが301や302でリダイレクトを返す場合、デフォルトではcurl はリダイレクト先に移動しません。-L(Location)オプションを付けると、自動的にリダイレクト先をたどります。# リダイレクトを自動的にたどる $ curl -L https://www.example.com/old-page
-L を付けないと空のレスポンスが返ることがあります。9. タイムアウトを設定する(--connect-timeout / -m)
ネットワーク障害の調査やスクリプトでの利用時には、タイムアウトを設定しておかないと処理が止まったまま待ち続けることになります。# 接続タイムアウトを5秒、全体のタイムアウトを10秒に設定する $ curl --connect-timeout 5 -m 10 https://www.example.com/
・-m 10:リクエスト全体(接続+データ転送)を10秒でタイムアウトにする
監視スクリプトでは必ずタイムアウトを設定してください。設定しないと、サーバーが応答しない場合にスクリプト全体が止まります。
10. Basic認証付きでアクセスする(-u)
Basic認証が設定されたページにアクセスするには、-u(user)オプションでユーザー名とパスワードを指定します。# Basic認証付きでアクセスする $ curl -u admin:password https://www.example.com/admin/
history に残るため、実運用では -u admin のようにパスワードを省略して対話入力するか、-n オプションで ~/.netrc ファイルを参照する方法が安全です。11. SSL証明書を検証しない(-k)
開発環境やオレオレ証明書(自己署名証明書)を使っている環境では、SSL証明書の検証エラーが出ることがあります。# SSL証明書の検証をスキップする $ curl -k https://dev.example.com/
-k は本番環境では使わないでください。中間者攻撃(MITM)を検出できなくなります。あくまで開発環境やテスト用途に限定してください。12. SSL証明書の有効期限を確認する(-v)
SSL証明書の期限切れは障害の原因になります。curl -v(verbose)でサーバーに接続すると、証明書の情報が表示されます。# SSL証明書の情報を確認する $ curl -v https://www.example.com/ 2>&1 | grep -E 'expire|subject|issuer'
curlとwgetの使い分け
「結局、curlとwgetはどちらを使えばいいのか?」という質問は現場でもよく出ます。それぞれ得意分野が異なるので、目的に応じて使い分けてください。| 目的 | 推奨コマンド | 理由 |
|---|---|---|
| ファイルのダウンロード | wget |
再帰ダウンロードや中断再開が得意 |
| API連携・HTTPメソッド指定 | curl |
GET/POST/PUT/DELETEを自由に指定できる |
| レスポンスヘッダーの確認 | curl |
curl -I で簡単にヘッダーだけ取得できる |
| JSON送信 | curl |
curl -H でContent-Typeを指定できる |
| サイト全体のミラーリング | wget |
wget -r で再帰的に取得できる |
| シェルスクリプトでの死活監視 | curl |
curl -w でステータスコードだけ取得できる |
トラブルシュート・エラー対処
「curl: (6) Could not resolve host」が出た時の対処法
DNS解決に失敗しています。以下を順番に確認してください。・URLのホスト名にタイプミスがないか確認する
・
nslookup や dig でDNS解決ができるか確認する・
/etc/resolv.conf にDNSサーバーが正しく設定されているか確認する# DNSの名前解決を確認する $ nslookup www.example.com $ cat /etc/resolv.conf
「curl: (7) Failed to connect」が出た時の対処法
TCP接続に失敗しています。サーバーが起動していない、ファイアウォールでブロックされている、ポートが間違っているなどの原因が考えられます。# ポートが開いているか確認する $ ss -tlnp | grep :80 $ ss -tlnp | grep :443
「curl: (60) SSL certificate problem」が出た時の対処法
SSL証明書の検証に失敗しています。原因として多いのは以下の3つです。・証明書の有効期限が切れている
・自己署名証明書を使っている
・CA証明書バンドルが古い
# CA証明書バンドルを更新する(RHEL/CentOS/AlmaLinux) # yum update ca-certificates # Ubuntu/Debian # apt update && apt install --reinstall ca-certificates
curl -k で一時的に検証をスキップできますが、本番環境では正規の証明書を使ってください。「curl: (28) Operation timed out」が出た時の対処法
接続先のサーバーが応答しない、またはネットワーク経路に問題があります。# ネットワーク経路を確認する $ traceroute www.example.com # サーバーへの疎通を確認する $ ping -c 3 www.example.com
curl が通らない場合は、環境変数 http_proxy / https_proxy が正しく設定されているか確認してください。# プロキシ環境変数を設定する $ export http_proxy=http://proxy.example.com:8080 $ export https_proxy=http://proxy.example.com:8080
本記事のまとめ
curl コマンドの使い方を、基本のGETリクエストからPOST送信、SSL証明書の確認、トラブルシュートまで解説しました。| やりたいこと | コマンド |
|---|---|
| Webページを取得する | curl https://www.example.com/ |
| ファイルに保存する | curl -o output.html https://www.example.com/ |
| レスポンスヘッダーを確認する | curl -I https://www.example.com/ |
| ステータスコードだけ取得する | curl -s -o /dev/null -w '%{http_code}' URL |
| POSTでフォームデータを送信する | curl -d 'key=value' URL |
| POSTでJSONを送信する | curl -X POST -H 'Content-Type: application/json' -d '{"key":"value"}' URL |
| リダイレクトをたどる | curl -L URL |
| タイムアウトを設定する | curl --connect-timeout 5 -m 10 URL |
| Basic認証付きでアクセスする | curl -u user:pass URL |
| SSL検証をスキップする | curl -k URL |
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
※登録30秒/合わなければ解除3秒
