Nginx には HTTP(L7)プロキシとは別に、TCP や UDP をそのままバイパスする stream モジュール があります。データベース接続のロードバランシング、DNS のプロキシ、SSH ポート転送など、プロトコルを問わない透過的な中継が必要な場面で使います。
この記事では Ubuntu 24.04 LTS を前提に、libnginx-mod-stream のインストールから nginx -t による設定確認まで、実際に Docker コンテナで動かした結果を載せます。Ubuntu 22.04 との違いについても後半でまとめます。
この記事のポイント
- Ubuntu 24.04 では
apt install nginxだけでは stream は使えない。libnginx-mod-streamの追加インストールが必要 - インストール後は
/etc/nginx/modules-enabled/50-mod-stream.confが自動生成され、load_module行が書き込まれる stream {}ブロックはhttp {}の外側(nginx.conf のトップレベル)に書く- UDP プロキシは
listen 5353 udp;のようにudpを付けるだけ。TCP との設定差はほぼない nginx -tで構文チェックしてからsudo nginx -s reloadで反映する
前提環境
この記事で使った環境は次のとおりです。
| 項目 | 値 |
|---|---|
| OS | Ubuntu 24.04 LTS(Noble Numbat) |
| 実行環境 | Docker 公式イメージ ubuntu:24.04 |
| nginx バージョン | 1.24.0-2ubuntu7.12 |
| stream モジュール | libnginx-mod-stream 1.24.0-2ubuntu7.12 |
| 検証日 | 2026-06-21 |
注意
コマンドは Ubuntu 24.04 LTS で検証しています。Ubuntu 22.04 との違いは「Ubuntu 22.04 との違い」セクションにまとめています。VPS で実行する場合は sudo が必要です。
STEP 1. nginx と libnginx-mod-stream をインストールする
最初に気をつけてほしいのが、apt install nginx だけでは stream モジュールが使えないという点です。nginx -V の出力に --with-stream=dynamic と書いてあっても、対応する .so ファイルが入っていないので stream ディレクティブを書くと次のエラーが出ます。
[emerg] 295#295: unknown directive “stream” in /etc/nginx/nginx.conf:XX
nginx: configuration file /etc/nginx/nginx.conf test failed
$ sudo apt install -y nginx libnginx-mod-stream
Setting up nginx-common (1.24.0-2ubuntu7.12) …
Setting up nginx (1.24.0-2ubuntu7.12) …
Setting up libnginx-mod-stream (1.24.0-2ubuntu7.12) …
nginx と libnginx-mod-stream を一度に入れてしまうのが一番楽です。パッケージは同じバージョン(1.24.0-2ubuntu7.12)で提供されているので、依存関係の不整合は起きません。

STEP 2. stream モジュールが有効になったか確認する
libnginx-mod-stream をインストールすると、次の2つが自動で用意されます。
/usr/lib/nginx/modules/ngx_stream_module.so(モジュール本体)/etc/nginx/modules-enabled/50-mod-stream.conf(load_module行を含む設定ファイル)
ngx_stream_module.so
$ cat /etc/nginx/modules-enabled/50-mod-stream.conf
load_module modules/ngx_stream_module.so;
Ubuntu の nginx パッケージのデフォルト nginx.conf には先頭に include /etc/nginx/modules-enabled/*.conf; が書かれているので、50-mod-stream.conf が存在するだけでモジュールが自動的にロードされます。自分で load_module を書き足す必要はありません。

STEP 3. TCP プロキシの設定を書く
stream {} ブロックは http {} とは別の、nginx.conf のトップレベルに書きます。http ブロックの中に stream を書くとエラーになるので注意してください。
最もシンプルな TCP プロキシ(例:MySQL を 3307 番ポートで受けて 3306 番に転送)の構成です。
# — nginx.conf の末尾に追記(http {} ブロックの外側)—
stream {
upstream backend_db {
server 127.0.0.1:3306;
}
server {
listen 3307;
proxy_pass backend_db;
proxy_connect_timeout 10s;
proxy_timeout 60s;
}
}
主要ディレクティブの説明
| ディレクティブ | 説明 | デフォルト値 |
|---|---|---|
listen |
受け付けるポート(TCP は番号のみ、UDP は udp を付ける) |
— |
proxy_pass |
転送先のアップストリーム名またはアドレス | — |
proxy_connect_timeout |
バックエンドへの接続タイムアウト | 60s |
proxy_timeout |
データ転送がない場合の切断タイムアウト | 10m |
設定を書いたら必ず構文チェックします。まず設定ファイルを /tmp/nginx_stream_tcp.conf として用意し nginx -t を通してから、問題なければ /etc/nginx/nginx.conf に統合して reload します。
nginx: the configuration file /tmp/nginx_stream_tcp.conf syntax is ok
nginx: configuration file /tmp/nginx_stream_tcp.conf test is successful
$ sudo nginx -s reload

STEP 4. UDP プロキシの設定を書く
UDP プロキシは listen に udp を追加するだけで、それ以外の書き方は TCP とほぼ同じです。以下は DNS(ポート 53)を受けて外部に転送する例です。
stream {
upstream dns_backend {
server 8.8.8.8:53;
server 8.8.4.4:53;
}
server {
listen 5353 udp;
proxy_pass dns_backend;
proxy_timeout 5s;
proxy_responses 1;
}
}
proxy_responses 1 は「1リクエストに対し1レスポンスで接続を閉じる」という意味で、DNS のような1往復で完結するプロトコルに指定します。nginx -t -c /tmp/nginx_stream_udp.conf で構文チェックし、test is successful を確認しました(Ubuntu 24.04 + nginx 1.24.0 + libnginx-mod-stream 1.24.0-2ubuntu7.12)。

STEP 5. ロードバランシングの追加設定
upstream ブロックには複数のサーバーを並べることができます。stream モジュールのデフォルトはラウンドロビンです。
upstream db_cluster {
server 10.0.0.1:5432; # Primary
server 10.0.0.2:5432; # Replica
server 10.0.0.3:5432 backup; # フェイルオーバー用
}
server {
listen 5432;
proxy_pass db_cluster;
proxy_connect_timeout 5s;
proxy_timeout 120s;
}
}
backup を付けたサーバーは、他のサーバーが全て落ちたときだけ使われます。PostgreSQL クラスターのプライマリ/レプリカ分散やフェイルオーバー構成でよく使うパターンです。
Ubuntu 22.04 との違い
Ubuntu 22.04 でも手順はほぼ同じですが、インストールされる nginx のバージョンが違います。

Ubuntu 22.04 では nginx 1.18.0、Ubuntu 24.04 では nginx 1.24.0 がインストールされます。どちらも libnginx-mod-stream を別途インストールする手順は変わりません。
気になったのが nginx -V の出力の違いです。Ubuntu 22.04 パッケージの仕様として、configure arguments に --with-stream の記述がありません。一方 Ubuntu 24.04 の nginx -V 2>&1 出力には --with-stream=dynamic が含まれています(24.04 で実測確認済み)。内部の動的ロード方式に差はありませんが、バージョン確認コマンドで stream の字が見えないと不安になるかもしれないので頭に入れておいてください。

よくあるエラーと解決策
①unknown directive "stream" が出る
libnginx-mod-stream が入っていないか、load_module が nginx.conf に読み込まれていない状態です。まず dpkg -l libnginx-mod-stream でインストール済みか確認します。入っているのにエラーが出る場合は、カスタムの nginx.conf を使っていて include /etc/nginx/modules-enabled/*.conf; 行が抜けていないか確認してください。
②stream ブロックを http の中に書いてしまった
stream {} は http {} ブロックの外側、nginx.conf のトップレベルに書く必要があります。エディタで http { を探し、その外側(前か後ろ)に stream {} を移動させてください。
③proxy_connect_timeout でタイムアウトが頻発する
デフォルトは 60s と長めですが、バックエンドが起動していない場合は即座に接続失敗します。ログは /var/log/nginx/error.log に出るので、tail -f /var/log/nginx/error.log でリアルタイムに確認するのが早いです。
注意
stream モジュールはデフォルトでアクセスログを書き出しません。ログが必要な場合は access_log /var/log/nginx/stream_access.log; を stream ブロック内に追記してください。
まとめ
Ubuntu 24.04 での Nginx stream セットアップをまとめます。
apt install nginx libnginx-mod-streamの2パッケージで準備完了- インストール後は
/etc/nginx/modules-enabled/50-mod-stream.confが自動生成される(手動設定不要) stream {}ブロックは nginx.conf のトップレベル(http {}の外)に書く- TCP は
listen 3307;、UDP はlisten 5353 udp;の形式 - 設定後は
sudo nginx -t→sudo nginx -s reloadの流れ
L4 プロキシは HTTP の中身を見ないので、暗号化された TLS トラフィックもそのまま転送できます。逆に、SSL ターミネーションや Host ヘッダーによる振り分けがしたい場合は http {} の proxy_pass か、stream の ssl_preread(SNI ベースの振り分け)を検討してください。VPS で自宅サーバーを公開する場合は、stream を使ってポート変換をかけると外部からのポートスキャンに対する間口を絞れます。


コメント