ByteScope

27017

ポート 27017 · MongoDB

TCPIANA 割り当てありデータベース

mongod と mongos が既定で待ち受けるポート。ドライバがサーバー選択に 30 秒黙って失敗し続けるのもここです。

ポート 27017 を使っているプロセスを特定する

自分の環境の行をそのまま実行してください。ポートを掴んでいるプロセス名と、バインドしているアドレスが出ます。たいていはそれだけで答えが分かります。

外側から確かめる

`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` はポートを探ってサービスとバージョンを判定しますが、これは認証のないデータベースを探す全世界スキャンが取るのとまったく同じ読みです。スキャンは自分が責任を持つホストにだけ。

27017 につながらないときの読み方

出ているもの意味
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 にいないことが頻繁にあります。

ポート 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 を外部に開けてよいか

27017 はインターネットから届いてはいけません。認可は自分でオンにするものなので、それなしで起動したデータベースは、ソケットを開ける相手からのあらゆるコマンドを受け入れます。スキャナーがこのポートを舐め始めた途端に大量の露出したデプロイが空にされ、身代金を要求されたのは、まさにこの経路です。localhost の既定は本物の改善ですが、守ってくれるのは誰も設定を変えていないサーバーだけ。アプリケーションのホストが接続できるように `bindIp` を広げた瞬間、そのデータベースはネットワークが許すかぎり届く存在になります。MongoDB のガイダンスはインスタンスを「信頼されたネットワークからのみアクセス可能」に保つこと、そしてネットワークインターフェイスが複数あるマシンでは全部ではなくプライベートまたは内部のインターフェイスに bind することを勧めています。まずそれをやってください。そのうえで管理用のユーザーを作って認可を有効にし、各アプリケーションには root ではなくロールを絞った専用ユーザーを与えて、認証情報が漏れても被害が限定されるようにしてください。ネットワークの外からデータベースに届く必要があるなら、ファイアウォールでポートを開けるのではなく VPN、ピアリングしたプライベートサブネット、SSH トンネルを使ってください。どうしても経路が必要なら送信元アドレスで絞り、TLS を必須にすること。なければ認証情報もクエリも返ってくるドキュメントも、全部読める形でネットワークを渡ります。

サービス
MongoDB
トランスポート
TCP
登録状況
IANA 割り当てあり
カテゴリ
データベース

このサイトのツール

どれもブラウザ内で完結します。アップロードは発生しません。

関連するポート

27017 を調べているとき、ついでに確認することになりがちなポートです。

よくある質問

明らかに使用中なのに、コマンドが何も表示しないのはなぜ?

ほぼ権限の問題です。lsofss はソケット自体は出しますが、他ユーザーのプロセスは所有者の列を伏せるので、システムアカウントやコンテナランタイム、launchd が起動したサーバーは sudo を付け直すまで持ち主不明のリスナーに見えます。Windows は逆で、netstat には何も出ないのに bind だけ失敗します。これは Hyper-V や WSL2、Docker Desktop が起動時に予約したポート帯に当たっている状態です。

ポートを掴んでいるプロセスは kill してよい?

何なのかを先に見てください。取り残された開発サーバーなら問題ありませんが、書き込み中のデータベースは別ですし、他が依存しているシステムサービスも同様です。持ち主がコンテナならコンテナごと停止してください。ホストから見えるプロセスを kill してもランタイムが再起動するだけです。どうしても止められないものなら、自分のサービスを別のポートへ移すほうが早く片付きます。

ローカルからは届くのに、別のマシンからは届かないのはなぜ?

0.0.0.0 ではなく 127.0.0.1 にバインドしているからです。各ページのコマンドがプロセス名と並べてバインド先アドレスを出しているのはこのためで、ループバックにバインドしたものはファイアウォールの設定に関係なく自分のマシンからしか届きません。最近は意図的にそれを既定にしているフレームワークも多いので、たいていはバグではなくフラグの問題です。すでに 0.0.0.0 なのに届かないなら、次に疑うのはホストのファイアウォールかクラウドのセキュリティグループです。

珍しいポート番号に移すと安全になる?

ほとんどなりません。インターネット全体を舐めるスキャナーはポート範囲を丸ごと走査し続けているので、稼げるのは数時間であって安全ではなく、代わりに関係者全員がその番号を覚える羽目になります。既定ポートを狙う無差別スキャンのログが減るという効果は確かにありますが、それだけです。結果を変えるのは認証と、送信元アドレスを絞ったファイアウォールと、そもそも外に出さないことです。

ポート 27017 でまだ詰まっていますか。ポート一覧をすべて見る。あるいは上に戻って、実際に出たエラー文から追ってください。