ByteScope

3389

ポート 3389 · RDP

TCP/UDPIANA 割り当てありリモート接続

Windows のリモートデスクトップが待ち受けるポート。サービスが起動しないときは既に誰かに取られていて、クライアントが回り続けるときは黙って捨てられています。

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

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

外側から確かめる

`nmap -Pn -p 3389 host.example.com` は、クライアントが実際にいる場所からそのポートがどう見えるかを教えてくれます。`-Pn` はホスト探索を飛ばすので、ping を無視するホストもスキャンされます。三つの答えの意味は nmap がきっちり定義しています。`open` は対象上のアプリケーションが待ち受けている、`closed` はホストは答えたがそこで何も待ち受けていない、`filtered` はファイアウォールやフィルタ、その他のネットワーク上の障害物がプローブを塞いでいて nmap にはどちらか判断できない、です。RDP ではこの区別がそのまま診断になります。`closed` ならサーバー側(サービス停止、`fDenyTSConnections` が 1、`PortNumber` の変更)、`filtered` なら Windows ファイアウォールのルールかクラウドのセキュリティグループを見に行くことになります。`--reason` でリセットが返ってきたのか何も来なかったのかが分かり、`-sV` を付ければハンドシェイクを読ませられます。スキャンは自分が責任を持つホストにだけ。

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

出ているもの意味
The client spins, then shows the generic dialog listing three reasons: remote access is not enabled, the computer is turned off, or it is not available on the networkあのダイアログは何でも受けの表示で、三つのうちどれなのかは教えてくれません。代わりに順番に潰していってください。対象で `qwinsta` を実行して `rdp-tcp` の行が `Listen` か、`netstat -ano | findstr ":3389"` に LISTENING の行があるか、`fDenyTSConnections` が `0` か、そしてファイアウォール。一段ずつ、ダイアログが選べなかった理由を一つずつ消していけます。
The connection is refused immediately — the handshake gets an instant resetホストには届いていて、誰も待ち受けていません。`TermService` が停止しているか、リモートデスクトップが無効(`fDenyTSConnections` が `1`、設定画面のチェックボックスを上書きするグループポリシーがそこに固定している可能性もあります)か、`WinStations\RDP-Tcp` の `PortNumber` が変えられていてリスナーがまったく別の場所にいるかです。最後のケースは `qwinsta` が 1 行で見分けます。リスナーは存在するのに、あなたが叩いた番号にいない、という形で出ます。
The client waits many seconds and then reports a timeout何も答えていないので、拒否ではなく破棄です。Windows ファイアウォールのリモートデスクトップの受信規則、クラウドのセキュリティグループやネットワークセキュリティグループ、あるいは経路上のどこかのネットワーク ACL です。拒否は即座、破棄は遅いので、待ち時間そのものが証拠になります。`nmap --reason` が `closed` ではなく `filtered` を返せば確定です。
Only one usage of each socket address (protocol/network address/port) is normally permittedWindows のエラー 10048、`EADDRINUSE` の現地語版です。リモートデスクトップサービスが起動する前に、別の何かが 3389 を掴みました。Microsoft の手順に従ってください。`netstat -ano | findstr ":3389"` で PID を取り、`tasklist /svc | findstr "<pid>"` でその裏のサービスを見ます。持ち主が `TermService` でないなら、推奨される直し方は RDP を動かすことではなく、そのプログラムのほうを動かすことです。
netstat shows nothing on 3389 and the listener still cannot bind占有ではなく予約で、これは Windows における権限失敗の形です。探すべきプロセスが存在しません。`netsh interface ipv4 show excludedportrange protocol=tcp` が、Hyper-V・WSL2・Docker Desktop・Windows の NAT サービスが起動時に確保する動的ポートの帯を一覧します。3389 がそのどれかに入っていたら、確保したサービスを再起動してください。プロセスを kill しても何も起きません。そもそも存在しないからです。
The identity of the remote computer cannot be verified. Do you want to connect anyway?素の状態のマシンでは想定内で、ネットワークの障害ではありません。サービスが自分のために生成した RDP の自己署名証明書を提示されていて、どのクライアントもそれを検証できません。セッションは暗号化されているが認証されていない、つまり向こう側にいるのがどのホストなのかは何も証明できていない、ということです。それが重要ならリスナーに本物の証明書を発行してください。そして以前は信頼された証明書が入っていたホストでこの警告が出たなら、それは煩わしさではなく発見として扱ってください。
The session connects but is far laggier than the same link used to beTCP の 3389 は開いていて、UDP の 3389 が開いていません。Microsoft の UDP トランスポート拡張はグラフィックスとマルチメディアに同じ番号を使い、それが上がらないとセッションは黙って TCP だけにフォールバックします。ファイアウォールのルールが TCP だけでなく両方のプロトコルを覆っているか確認してください。

ポート 3389 で動いているもの

IANA は 3389 を `ms-wbt-server`(Microsoft の Windows-Based Terminal の略)として TCP・UDP 両方で登録していて、Windows は実際に両方を使います。セッションを運ぶのは TCP、グラフィックスとマルチメディアを UDP に載せるのが Microsoft の UDP Transport Extension で、その仕様書はターミナルサーバー側の受信 UDP 接続要求の既定ポートも 3389 だと記しています。TCP しか開けていないファイアウォールのせいで、接続はできるのに品質の悪い回線で目に見えて悪化する、という現象が起きるのはこのためです。Windows ではこのリスナーは普通のプログラムではありません。リモートデスクトップサービス、つまり `TermService` のもので、これは `svchost.exe` の中にホストされています。だから素の `tasklist` で PID を引いても `svchost.exe` としか出ず、何の役にも立ちません。`tasklist /svc` ならサービス名まで出ます。残りはレジストリの三つの事実で決まります。`HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server` の `fDenyTSConnections` は、リモートデスクトップが有効なら `0`、無効なら `1` で、設定画面のチェックボックスがどう見えていようとグループポリシーがこれを `1` に固定していることがあります。`...\Terminal Server\WinStations\RDP-Tcp` の `PortNumber` が、実際にポートを決めている値です。そして `qwinsta` は、`rdp-tcp` のリスナーが `Listen` 状態まで到達したかどうかを教えてくれます。これはサービスが動いているかどうかとは別の問いです。Windows の外では、xrdp のようなサードパーティのサーバーが同じ番号を使うので、3389 で応答する Linux ホストは Microsoft の何かではなく、そちらを動かしています。

ポート 3389 を外部に開けてよいか

3389 を公開インターネットに出さないでください。ここの歴史は理屈ではなく具体的です。CVE-2019-0708、通称 BlueKeep は、Windows 7・Server 2008・Server 2008 R2 のリモートデスクトップサービスにあった認証前のリモートコード実行の欠陥でした。認証情報もユーザー操作もソーシャルエンジニアリングも不要で、脆弱なリスナーに到達できさえすればよかったので、ワーム化しました。Microsoft はサポート終了済みのリリースにも修正を出し、脆弱なコードが動く前に認証を強制するという理由で、ネットワークレベル認証が部分的な緩和策になると注記しています。`PortNumber` でリスナーを別の番号に動かすのは防御になりません。Microsoft 自身のトラブルシューティング文書が RDP を別のポートで動かすことを推奨していませんし、サービスを指紋で判定するスキャナーは番号に関係なく見つけます。クリックして通り過ぎる TLS の警告も防御ではありません。あそこで出ているのは通常、サービスが自分で生成してコンピューター証明書ストアのリモートデスクトップの下に置いた自己署名証明書なので、それを受け入れても、これからドメインのパスワードを打ち込む相手が何者かは何一つ検証できていません。RDP は VPN か RD ゲートウェイ、踏み台の後ろに置き、送信元アドレスで絞り、ネットワークレベル認証を必須にし、相手が誰かが重要なら、自己署名証明書をクライアントが本当に検証できる発行済みの証明書に置き換えてください。

サービス
RDP
トランスポート
TCP/UDP
登録状況
IANA 割り当てあり
カテゴリ
リモート接続

このサイトのツール

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

関連するポート

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

よくある質問

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

ほぼ権限の問題です。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 なのに届かないなら、次に疑うのはホストのファイアウォールかクラウドのセキュリティグループです。

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

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

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