27017
mongod と mongos が既定で待ち受けるポート。ドライバがサーバー選択に 30 秒黙って失敗し続けるのもここです。
自分の環境の行をそのまま実行してください。ポートを掴んでいるプロセス名と、バインドしているアドレスが出ます。たいていはそれだけで答えが分かります。
sudo lsof -nP -iTCP:27017 -sTCP:LISTEN`-n` で逆引き DNS を、`-P` でポート名の解決を飛ばし、`-iTCP:27017` でポートを、`-sTCP:LISTEN` で待ち受け状態を選びます——lsof のマニュアルが例として挙げている組み合わせです。PID は二列目、バインドアドレスは最後の列で、`127.0.0.1:27017 (LISTEN)` や `*:27017 (LISTEN)` と出ます。ループバックへの bind は既定であり、「アプリからデータベースが見えない」系の質問のほとんどへの答えでもあります。COMMAND が `com.docker.backend` ならコンテナの公開ポートなので、そのプロセスではなくコンテナを止めてください。`sudo` を付けないと、他のユーザーが所有する `mongod` は見えません。誰も待ち受けていなければ lsof は何も出さずに終了コード 1 で終わります。
sudo ss -tlnp 'sport = :27017'ss(8) のマニュアルがここで使うフラグを定義しています。`-t` は TCP ソケットを表示、`-l` は待ち受けソケットのみを表示、`-n` はサービス名を解決しない、`-p` はソケットを使っているプロセスを表示、そして `sport = :27017` は文書化されたポートフィルタです。Local Address:Port の列がそのまま診断結果になります。`127.0.0.1:27017` は localhost の既定で他のホストからは到達できず、`0.0.0.0:27017` は全 IPv4 アドレス、`[::]:27017` は IPv6 のワイルドカードです。持ち主は `users:(("mongod",pid=980,fd=12))` と読めます。`ss` のない古いホストは `netstat -tlnp` が使えますが、どちらも自分の所有でないプロセスを名指しするには特権が必要です。
netstat -ano | findstr :27017Microsoft のリファレンスより。`-a` はすべてのアクティブな TCP 接続とコンピューターが待ち受けているポートを表示し、`-n` はアドレスとポートを数値で表現し、`-o` は各接続のプロセス ID を含めます。列は Proto、Local Address、Foreign Address、State、PID の順です。PID を名前にするには `tasklist /fi "PID eq 980"`——`PID` は文書化されたフィルタ、`eq` は文書化された演算子です。`findstr` は行のどこにあっても部分文字列に一致するので、このマシンから別のデータベースの 27017 へ出ているドライバの接続も同じ出力に出てきます。どの行がリスナーかは State の列が教えてくれます。
Get-NetTCPConnection -LocalPort 27017 | Select-Object LocalAddress,LocalPort,State,OwningProcessPowerShell 版はポートを数値として一致させるので、たまたま一致した部分文字列を拾うことがなく、`-LocalPort` は 27017 が相手側であるような接続を除外します。`OwningProcess` に `Get-Process -Id` をかければ実行ファイル名が分かり、Windows では自分で起動したシェルではなく MongoDB のサービスであることがほとんどです。結果が空なのに bind が失敗し続けるなら、占有ではなく予約を疑ってください。`netsh interface ipv4 show excludedportrange protocol=tcp` が Hyper-V・WSL2・Docker Desktop が起動時に確保する帯を一覧します。
mongosh --host 127.0.0.1 --port 27017 --eval 'db.runCommand({ ping: 1 })'アプリケーション層のチェックで、待ち受けているソケットと、実際に応じてくれるデータベースを分けてくれます。`{ ok: 1 }` なら健康。認証エラーもまた健康です——ポートもバインドアドレスもネットワークも正常で、足りないのは認証情報だけ。エラーが出るまでに 30 秒の間があればサーバー選択がタイムアウトしたということで、拒否ではなくパケットの破棄です。既定に頼らずアドレスを明示的に書いて、答えが意図したホストについてのものになるようにしてください。
`nmap -Pn -p 27017 db.example.com` は、マシンの外から見たそのポートの姿を報告します。`-Pn` は対象をオンライン扱いして探索を飛ばしますが、データベースのホストは ping を落とすことが多いので、ここは効いてきます。`-p` はスキャンをその 1 ポートに限定します。`open` は TCP ハンドシェイクが成立して何かが待ち受けているということ。`closed` はホストがリセットを返した、つまり生きていて経路もあるが誰もポートを持っていないということで、`mongod` が停止しているときの定番の姿です。`filtered` は何も返ってこなかったということで、ファイアウォールかセキュリティグループがパケットを捨てています——あなたのドライバが 30 秒待たされていたのもこれです。`--reason` は実際に起きたのがどれかを、open のポートには `syn-ack`、closed のポートには `conn-refused` として出します。`-sV` はポートを探ってサービスとバージョンを判定しますが、これは認証のないデータベースを探す全世界スキャンが取るのとまったく同じ読みです。スキャンは自分が責任を持つホストにだけ。
| 出ているもの | 意味 |
|---|---|
MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017 | ソケット層がはっきり拒否した形です。ホストがリセットを返したのは、誰もそのポートを持っていないから。`mongod` が動いていないか、コンテナの中にいて `127.0.0.1` がデータベースではなくそのコンテナ自身を指しているかのどちらかです。データベースはサービス名かホストの実アドレスで呼び、動かしているマシンの上で自分の環境のコマンドを実行して確認してください。 |
MongoServerSelectionError: Server selection timed out after 30000 ms | `serverSelectionTimeoutMS` が尽きたときのドライバ自身の言い方で、その既定はちょうど 30000 ミリ秒なので、約 30 秒のフリーズが目印になります。これは原因ではなく包み紙です。本当のソケットエラーは、一緒に出力される `reason` かトポロジの説明の中にいます。そちらを読んでください。タイムアウトはパケットの破棄、拒否は停止したサーバーです。 |
MongoServerError: Authentication failed. | エラーコード 18、`AuthenticationFailed` です。ネットワークもポートもバインドアドレスもすべて正しく、接続はハンドシェイクまで到達して認証情報が拒否されました。ユーザー名、パスワード、そして最も多いのが `authSource` です。`admin` で作ったユーザーは、明示しない限りアプリケーションのデータベースに対しては認証されません。 |
MongoServerError: not authorized on appdb to execute command | エラーコード 13、`Unauthorized`。これも 27017 とは関係ありません。認証は成功していて、そのユーザーに付いたロールが、実行したコマンドの権限を持っていないだけです。root ユーザーに手を伸ばすのではなく、正しいデータベースでロールを付与してください。 |
listen EADDRINUSE: address already in use 0.0.0.0:27017 | 既に誰かがポートを持っています。たいていは、いま立ち上げたコンテナの隣で起動時から動いていたインストール済みの MongoDB サービスか、終了しそこねた前の `mongod` です。まず持ち主を見つけてください。サービスを止めるより、コンテナを別のポートで公開するほうが早いことも多いです。 |
mongod logs 'Waiting for connections' with a port you did not expect | あの起動行には実際に取ったポートが書かれているので、設定ファイルに上書きされていることに気づく最短経路になります。`--shardsvr` を渡された `mongod` の既定は 27018、`--configsvr` なら 27019 なので、シャードクラスタのメンバーは、接続文字列がどう書かれていようと 27017 にいないことが頻繁にあります。 |
IANA は 27017 を TCP で `mongodb`、説明は「Mongo database system」として登録しています。UDP の行は Reserved でサービス名はありません。MongoDB 自身のリファレンスが兄弟の番号を並べていて、知っておくと当てずっぽうがかなり減ります。27017 は `mongod` と `mongos` 両方の既定、27018 は `--shardsvr` か `clusterRole: shardsvr` で起動した `mongod` の既定、27019 は `--configsvr` の既定、27020 は `mongocryptd` が待ち受ける番号です。この兄弟たちは IANA のレジストリには一つも載っていません。載っているのは 27017 だけです。現行の MongoDB のバイナリは既定で localhost に bind します。マニュアルにそう明記されていて、広げ方も示されています——全 IPv4 アドレスなら `0.0.0.0`、両方のファミリーなら `::,0.0.0.0`、あるいは `net.bindIpAll` の設定です。サーバー上のシェルからは完璧に応答するデータベースが、アプリケーションのホストからは届かない——その最もありふれた原因が、この既定値です。もう一つ知っておく価値があるのは、ここでの失敗がソケットではなくサーバー選択を通じて報告されることが多い点です。ドライバはトポロジ内の各ノードを `serverSelectionTimeoutMS` が尽きるまで再試行し続け、その既定は 30000 ミリ秒。だから間違ったポートや塞がれたポートは、即座のエラーではなく 30 秒のフリーズとして現れます。
27017 はインターネットから届いてはいけません。認可は自分でオンにするものなので、それなしで起動したデータベースは、ソケットを開ける相手からのあらゆるコマンドを受け入れます。スキャナーがこのポートを舐め始めた途端に大量の露出したデプロイが空にされ、身代金を要求されたのは、まさにこの経路です。localhost の既定は本物の改善ですが、守ってくれるのは誰も設定を変えていないサーバーだけ。アプリケーションのホストが接続できるように `bindIp` を広げた瞬間、そのデータベースはネットワークが許すかぎり届く存在になります。MongoDB のガイダンスはインスタンスを「信頼されたネットワークからのみアクセス可能」に保つこと、そしてネットワークインターフェイスが複数あるマシンでは全部ではなくプライベートまたは内部のインターフェイスに bind することを勧めています。まずそれをやってください。そのうえで管理用のユーザーを作って認可を有効にし、各アプリケーションには root ではなくロールを絞った専用ユーザーを与えて、認証情報が漏れても被害が限定されるようにしてください。ネットワークの外からデータベースに届く必要があるなら、ファイアウォールでポートを開けるのではなく VPN、ピアリングしたプライベートサブネット、SSH トンネルを使ってください。どうしても経路が必要なら送信元アドレスで絞り、TLS を必須にすること。なければ認証情報もクエリも返ってくるドキュメントも、全部読める形でネットワークを渡ります。
どれもブラウザ内で完結します。アップロードは発生しません。
27017 を調べているとき、ついでに確認することになりがちなポートです。
ほぼ権限の問題です。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 なのに届かないなら、次に疑うのはホストのファイアウォールかクラウドのセキュリティグループです。
ほとんどなりません。インターネット全体を舐めるスキャナーはポート範囲を丸ごと走査し続けているので、稼げるのは数時間であって安全ではなく、代わりに関係者全員がその番号を覚える羽目になります。既定ポートを狙う無差別スキャンのログが減るという効果は確かにありますが、それだけです。結果を変えるのは認証と、送信元アドレスを絞ったファイアウォールと、そもそも外に出さないことです。
ポート 27017 でまだ詰まっていますか。ポート一覧をすべて見る。あるいは上に戻って、実際に出たエラー文から追ってください。