
2026/06/17 1:40
TIL:curl を使わずに/bash の/dev/tcp で HTTP リクエストを実行できます。
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
このテキストは、外部ツール(例:
curl)をインストールせずに内部 Docker ネットワークの接続性を検証するために /dev/tcp リダイレクトを使用した Bash 固有の Linux のトリックについて説明しています。この手法は、Bash が --enable-net-redirections オプションでコンパイルされた場合にのみ動作し、POSIX シェルまたはその機能が無効化された Bash ビルドでは利用できません。信頼性が高く迅速なリクエストを実現するためには、HTTP/1.1 の永続的な接続での待機が無限に続くことを防ぐために Connection: close ヘッダーを追加し、コマンドを timeout ユーティリティでラップする必要があります。この技術は明文化のみをサポートしており、安全な HTTPS トラフィックには openssl s_client など他のツールが必要です。軽量コンテナや依存関係の追加が禁止された制限環境などにおいて非常に有効ですが、パッケージのインストールが可能であれば、日常運用では curl が推奨されるツールです。本文
Docker 内コンテナ間の HTTP 接続確認:/dev/tcp
を使った方法
/dev/tcpDocker の共有ネットワーク上で、特定のサービス(例:
service)に GET /health リクエストを送信したい場合、最小限化されたコンテナ環境では curl や wget が利用できないことがあります。その際の代替手段として、bash 標準機能による TCP ソケット操作を紹介します。
基本的な接続方法
追加のツールをインストールせずに、既存のシェルだけで完結します。以下のコマンドを使用してアクセス先のホストとポートに接続し、リクエストを送信します。
exec 3<>/dev/tcp/service/8642 printf 'GET /health HTTP/1.1\r\nHost: service\r\nConnection: close\r\n\r\n' >&3 cat <&3
: アクセス先のホスト名(DNS で解決可能な名称)service
: ポート番号8642
このコマンドを実行すると、ステータス行・ヘッダー・レスポンス本文が含まれる完全な応答が返されます。
ヘッダーの追加方法
認証トークンなどの追加ヘッダーを送信する場合は、リクエスト文字列を調整します。空行(
\r\n\r\n)の直前に新しいヘッダー行を追加してください。
exec 3<>/dev/tcp/service/8642 printf 'GET /v1/models HTTP/1.1\r\nHost: service\r\nAuthorization: Bearer %s\r\nConnection: close\r\n\r\n' "$API_KEY" >&3 cat <&3
メカニズムについて
/dev/tcp/path はディスク上の実体ファイルではなく、bash 内部で処理されるリダイレクト機能です。
を実行すると何も表示されません。ls /dev/tcp- バージョン情報や使用方法は Bash マニュアル で確認できます:
– ホストが有効なホスト名またはインターネットアドレス、ポートが整数のポート番号またはサービス名のいずれかである場合、bash は対応する TCP ソケットを開こうとします。/dev/tcp/host/port
これは、既存の
/dev 階層と競合しないよう意図的に作成された仮想パスであり、DNS ルックアップや connect(2) の実装を bash が自動化しています。ファイル記述子(FD)3 に割り当てられたソケットを読み書きすることで通信が可能になります。
重要な注意点
⚠️ curl ではない(機能制限)
これは公式の HTTP クライアントではありません。以下の機能は実装されていません:
- HTTP パースの高度化処理
- リダイレクトの追跡
- チャンク付きレスポンスの扱い
- レスポンス圧縮の自動展開
- リトライロジック
- TLS/SSL 暗号化サポート
あくまで迅速な接続確認やデバッグ用のトリックとして利用してください。
⚠️ Connection: close
ヘッダーの必須性
Connection: closeHTTP/1.1 のデフォルトではサーバーが接続を維持します。これを強制しないと、
cat <&3 が EOF を検知できず無限待機します。
- 対策: リクエストに
を追加するか、全体をConnection: close
で囲むことで安全に実行できます。timeout 6 bash -c '...'
⚠️ TLS(HTTPS)は利用不可
/dev/tcp は生ソケット(プレーンテキスト)のみをサポートします。
- HTTPS の場合は
を使用してください。openssl s_client
⚠️ シェル依存とバイナリ構成
- bash 固有機能: POSIX sh(
)や zsh では動作しません。必ず#!/bin/sh
コマンドを直接呼び出してください。bash - ビルドオプション:
オプションで bash をコンパイルする必要がある場合があります。--enable-net-redirections- 最新の主要ディストリビューション(Debian など)ではデフォルトでオンですが、非常に最小限化されたシステムや古いバージョンではオフになっている可能性があります。事前に動作確認が必要です。
まとめ
パッケージ管理ツールを使用できない環境において、即座にネットワーク到達性を検証するための有効な手段です。日常業務では
curl が推奨されますが、設計上依存関係を排除したコンテナ内部でのデバッグには最適解となります。