6379
Redis が RESP を待ち受けるポート。クライアントが「届かない」と言ってくる番号であり、外に出したキャッシュが数時間で見つけられる番号でもあります。
自分の環境の行をそのまま実行してください。ポートを掴んでいるプロセス名と、バインドしているアドレスが出ます。たいていはそれだけで答えが分かります。
sudo lsof -nP -iTCP:6379 -sTCP:LISTEN`-n` は逆引き DNS を、`-P` はポート名の解決を飛ばすので、アドレスは数値のままです。`-iTCP:6379` でそのポートに、`-sTCP:LISTEN` で待ち受け状態に絞ります——この組み合わせは lsof のマニュアル自身が例として挙げているものです。列は COMMAND、PID、USER、FD、TYPE、DEVICE、SIZE/OFF、NODE、NAME。二番目が止めることになるプロセスで、最後がバインドアドレス、`127.0.0.1:6379 (LISTEN)` か `*:6379 (LISTEN)` と出ます。ループバックならこのマシンからしか接続できず、コンテナや別のホストが永遠につながらない理由がそれです。`*` は全インターフェイス。行が一つもなく lsof が終了コード 1 で終われば、ポートは本当に空いています。`sudo` なしでは自分のプロセスしか見えないので、launch daemon や Docker が起動した `redis-server` は何もないのと同じに見えます。
sudo ss -tlnp 'sport = :6379'ss(8) のマニュアルが各フラグを定義しています。`-t` は TCP ソケットを表示、`-l` は待ち受けソケットのみを表示、`-n` はサービス名を解決しない、`-p` はソケットを使っているプロセスを表示、そして `sport = :6379` はドキュメント化された `{dport|sport} [OP] [FAMILY:]:PORT` のフィルタ形式です。Local Address:Port の列を読んでください。`0.0.0.0:6379` は全 IPv4 アドレス、`127.0.0.1:6379` はループバックのみ、`[::]:6379` は IPv6 のワイルドカードで、既定の Linux ホストでは IPv4 の接続も受けます。持ち主は `users:(("redis-server",pid=1234,fd=6))` と出ます。`ss` のないホストでは古い `netstat -tlnp` が同じ三つの事実を出しますが、netstat のマニュアルは自分の所有でないソケットのプログラム名を見るには特権が必要だと警告していて、それは `ss` にも当てはまります。
redis-cli -h 127.0.0.1 -p 6379 ping同じ問いのアプリケーション層版で、「ソケットが開いている」と「Redis が答えている」を分けてくれるのがこれです。`PONG` なら健康なサーバー。`NOAUTH Authentication required.` も健康です——ポートもネットワークも問題なく、足りないのは認証情報だけ。`Could not connect to Redis at 127.0.0.1:6379: Connection refused` なら誰も待ち受けていません。`-h localhost` ではなくアドレスを直接書いてください。デュアルスタックのホストではその名前が `::1` に解決される一方でサーバーは IPv4 にしか bind していないことがあり、そうなると停止しているサーバーとまったく同じ症状に見えます。
netstat -ano | findstr :6379フラグについての Microsoft のリファレンス。`-a` は「すべてのアクティブな TCP 接続と、コンピューターが待ち受けている TCP・UDP ポート」を表示し、`-n` はアドレスとポート番号を数値で表現し、`-o` は「各接続のプロセス ID(PID)を含める」。列は Proto、Local Address、Foreign Address、State、PID なので、二列目がバインドアドレスで最後がプロセスです。PID を名前にするには `tasklist /fi "PID eq 1234"`——`PID` は文書化されたフィルタ名で、`eq` はその演算子です。ただし一致には注意してください。`findstr` は行のどこにあっても部分文字列を探すので、Foreign Address が `:6379` で終わる行、つまり外向きのクライアント接続も引っかかります。何かを止める前に State の列が LISTENING と言っているか確認してください。
Get-NetTCPConnection -LocalPort 6379 | Select-Object LocalAddress,LocalPort,State,OwningProcessPowerShell 版はポートを文字列ではなく数値として一致させるので、部分文字列に騙されることがなく、`-LocalPort` は 6379 が相手側であるような接続を拾いません。`OwningProcess` の値を `Get-Process -Id` に渡せばイメージ名が分かります。結果が空なのに bind が失敗し続けるなら、それは予約された範囲のケースです。`netsh interface ipv4 show excludedportrange protocol=tcp` が Hyper-V・WSL2・Docker Desktop が起動時に確保する動的ポートの帯を一覧し、その中に入った bind は責めるべきプロセスなしに失敗します。
`nmap -Pn -p 6379 cache.example.com` は、ホストの外から見て本当に大事な一点に答えます。`-Pn` はホストをオンライン扱いして探索を飛ばすので、ping を無視するマシンもスキャンされ、`-p` は気にしているポートだけにスキャンを限定します。`open` は TCP ハンドシェイクが成立したということ。何かが待ち受けていて到達できます。`closed` はホストがリセットを返したということで、生きていて経路もあるが誰もポートを持っていません。`filtered` は何も返ってこなかったということで、ファイアウォールかクラウドのセキュリティグループが拒否ではなく破棄していて、この違いがそのまま診断になります。実際にどれが起きたかは `--reason` で分かり、nmap は open のポートには `syn-ack`、closed のポートには `conn-refused` を並べます。`-sV` はさらに踏み込んでサービスとバージョンを特定しにいき、Redis ではたいていバージョン文字列が返ってきます——保護されていないインスタンスを全世界スキャンが見つける手口そのものです。スキャンは自分が責任を持つホストにだけ。
| 出ているもの | 意味 |
|---|---|
Could not connect to Redis at 127.0.0.1:6379: Connection refused | `ECONNREFUSED` に対する redis-cli の言い方です。パケットはホストに届き、そのポートを持つプロセスがないのでカーネルがリセットを返しました。Redis が停止しているか、起動の途中で死んだか、あなたが叩いたアドレスを含まない場所にバインドしています。そもそも起動したのかを決めつける前にログを読んでください。ポートを取れなかったサーバーは `Failed listening on port 6379 (tcp), aborting.` と書いて終了します。 |
Warning: Could not create server TCP listening socket 127.0.0.1:6379: bind: Address already in use | ポートが取られているときの Redis 自身の起動時の行で、この後に `Failed listening on port 6379 (tcp), aborting.` が続いて終了します。十中八九、停止ではなくデタッチされただけの前の `redis-server` か、まだポートを公開しているコンテナです。推測せず、自分の環境のコマンドを実行して PID を読んでください。 |
(error) DENIED Redis is running in protected mode because protected mode is enabled and no password is set for the default user. | ネットワークは正常で、Redis も動いています。あなたを拒んでいるのは、パスワードも明示的な bind もないサーバーに、ループバック以外のアドレスから来たからです。エラー文には抜け道が四つ並んでいますが、選ぶべきはパスワードか ACL ユーザーを設定するものです。届く状態のサーバーで protected mode を切るのが、インスタンスが空にされる典型的な経路です。 |
(error) NOAUTH Authentication required. | ポートの問題ではまったくありません。接続は成功していて、`requirepass` か ACL が効いています。何よりも先に `AUTH <password>`、ACL ユーザーなら `AUTH <user> <password>` を送るか、接続 URL に認証情報を入れてください。平文のポートでは、そのパスワードも平文でネットワークを渡ります。 |
The client blocks for tens of seconds and then reports a connect timeout | `ETIMEDOUT` です。誰も答えていません。パケットフィルタが SYN を拒否せず黙って捨てています——セキュリティグループ、ホスト上のファイアウォール、あるいは経路上のネットワーク ACL。拒否は即座、破棄は遅いので、待ち時間そのものがどちらを見ているかを教えてくれます。 |
(error) MISCONF Redis is configured to save RDB snapshots, but it's currently unable to persist to disk. | これも 6379 とは関係ありません。接続は成功していて、バックグラウンドの保存が失敗したので Redis が書き込みを拒んでいます。たいていはディスクが満杯か、書き込めないディレクトリです。その間も読み取りは動き続けます。ディスクを直すか、スナップショットを失うことを受け入れるなら `stop-writes-on-bgsave-error` を変えてください。 |
IANA は 6379 を TCP で `redis` として登録しています。同じ番号の UDP の行にはサービス名がなく Reserved とだけ書かれていますし、Redis には UDP を話す部分がないので、6379 のページは TCP だけのページです。この番号はサーバーに同梱される `redis.conf` の `port 6379` の行そのもので、`redis-cli` も同じ値を既定にしているため、ローカルにインストールした環境では `redis-cli ping` が引数なしで通ります。混乱の大半は近隣の三つの番号から来ます。Redis Sentinel は別の設定ファイルを持っていて、その `port` は 26379 なので、6379 にいるものが Sentinel であることはありません。クラスタモードのノードはクラスタバスのための二つ目の待ち受けソケットを開き、`redis.conf` は `cluster-port` を既定の 0 のままにするとバスがコマンドポート + 10000 に bind すると説明しています。既定のノードなら 16379 で、つまりクラスタのメンバーは 1 つではなく 2 つのポートを持ちます。そして Redis 6 で入った TLS は別の `tls-port` で設定します。素の `port` は、意図的に 0 にするまでその隣で暗号化なしの RESP を話し続けます。この最後の点は二度書く価値があります。誰かが平文のポートを切っていない限り、6379 への接続は平文です。
6379 をインターネットに向けては絶対にいけません。Redis は自分のセキュリティのページで設計上の前提をはっきり書いています——「信頼された環境の中の、信頼されたクライアントからアクセスされることを想定して設計されている」。そして帰結も二つ明示しています。ポートに届く誰かが `FLUSHALL` を一度打てばデータセットは消えます。さらに悪いのは `CONFIG` コマンドで、クライアントは作業ディレクトリとダンプファイル名を変更できます。同じページはこれを、「システムを侵害し、Redis と同じユーザーで信頼できないコードを実行できるようになる可能性がある」セキュリティ上の問題だと呼んでいます。大量に踏み荒らされた Redis の背後にあるのは常にこの仕組みです——OS があとで読み戻すパスにダンプファイルを書き込む、というものです。protected mode は助けにはなりますが、思われているより適用範囲が狭いです。3.2.0 以降、Redis はループバック以外のクライアントに `-DENIED` エラーを返しますが、ドキュメントはその条件を正確に書いています。サーバーが既定の設定のまま、全インターフェイスに bind し、パスワードが設定されていないときだけです。サーバーを外から届くようにするために `bind 0.0.0.0` を明示的に足すと、その守りも一緒に外れます。そしてそれこそ、事故の直前に運用者が行う編集そのものです。同梱の `redis.conf` は `127.0.0.1 -::1` に bind しています。そのままにして、前段にパスワードか ACL ユーザーを置き、リモートのインスタンスへは VPN か SSH トンネル越しに届かせ、平文のポートでは `AUTH` 自体も平文で流れることを忘れないでください。
どれもブラウザ内で完結します。アップロードは発生しません。
6379 を調べているとき、ついでに確認することになりがちなポートです。
ほぼ権限の問題です。lsof や ss はソケット自体は出しますが、他ユーザーのプロセスは所有者の列を伏せるので、システムアカウントやコンテナランタイム、launchd が起動したサーバーは sudo を付け直すまで持ち主不明のリスナーに見えます。Windows は逆で、netstat には何も出ないのに bind だけ失敗します。これは Hyper-V や WSL2、Docker Desktop が起動時に予約したポート帯に当たっている状態です。
何なのかを先に見てください。取り残された開発サーバーなら問題ありませんが、書き込み中のデータベースは別ですし、他が依存しているシステムサービスも同様です。持ち主がコンテナならコンテナごと停止してください。ホストから見えるプロセスを kill してもランタイムが再起動するだけです。どうしても止められないものなら、自分のサービスを別のポートへ移すほうが早く片付きます。
0.0.0.0 ではなく 127.0.0.1 にバインドしているからです。各ページのコマンドがプロセス名と並べてバインド先アドレスを出しているのはこのためで、ループバックにバインドしたものはファイアウォールの設定に関係なく自分のマシンからしか届きません。最近は意図的にそれを既定にしているフレームワークも多いので、たいていはバグではなくフラグの問題です。すでに 0.0.0.0 なのに届かないなら、次に疑うのはホストのファイアウォールかクラウドのセキュリティグループです。
ほとんどなりません。インターネット全体を舐めるスキャナーはポート範囲を丸ごと走査し続けているので、稼げるのは数時間であって安全ではなく、代わりに関係者全員がその番号を覚える羽目になります。既定ポートを狙う無差別スキャンのログが減るという効果は確かにありますが、それだけです。結果を変えるのは認証と、送信元アドレスを絞ったファイアウォールと、そもそも外に出さないことです。
ポート 6379 でまだ詰まっていますか。ポート一覧をすべて見る。あるいは上に戻って、実際に出たエラー文から追ってください。