RDPを「狙い撃ち」させない。ポート3389を公開する前に知るべき防御の極意
ネットワークの最前線でインフラを支えている諸君、お疲れ様。
夜中にアラートが鳴り響き、ログを確認すれば海外からの3389/tcpへの接続試行が山のように積み上がっている……そんな悪夢のような光景に遭遇したことはないだろうか。ランサムウェアグループにとって、RDP(リモートデスクトッププロトコル)の脆弱性や貧弱な認証は「開けっ放しの玄関」に等しい。
今日は、教科書的な「RDPを閉じる」という正論を一歩進め、現場で泥臭く生き抜くための「RDP防御の技術」について、パケットの裏側まで掘り下げて解説する。
—
1. なぜ「ポート3389」はここまで狙われるのか
RDPは非常に利便性が高いプロトコルだが、その設計思想は「信頼できるネットワーク内での利用」を前提としている。インターネットという広大な無法地帯に、認証前の暗号化が不完全なままパケットを放り出せば、ブルートフォース(総当たり)攻撃の格好の餌食になるのは必然だ。
攻撃者はまず、SYNパケットを送りつけ、SYN-ACKが返ってくるIPを探す。そこからCredSSPやNLAによる認証プロセスへ無理やり突入し、辞書攻撃でパスワードを割り出そうとする。彼らが狙うのは、脆弱なパスワード一つだけだ。
2. 「NLA(ネットワークレベル認証)」こそが最後の砦
我々エンジニアが真っ先に強制すべきは、NLA (Network Level Authentication)だ。
NLAが有効な場合、RDPセッションが完全に確立される前に、ユーザー認証が完了していなければならない。つまり、攻撃者はログイン画面すら拝むことができず、認証前の暗号化されたやり取りだけで接続が遮断される。これにより、RDPサービスそのものに対する脆弱性攻撃(BlueKeepのようなRCE)を大幅に無効化できる。
設定の強制(レジストリ操作)
Windows ServerでNLAを強制するには、以下のレジストリを設定するのが最も確実だ。
# NLAを強制するレジストリ設定
# UserAuthenticationが「1」でNLAが有効になる
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -Name 'UserAuthentication' -Value 1
3. 実践:ブルートフォース攻撃を検知・遮断する
単に設定を変えるだけでは、パケットの雨を止めることはできない。実務レベルでは、攻撃者のIPを動的にファイアウォールでブロックする仕組みが必要だ。
Pythonによる失敗ログ監視の自動化
Windowsのイベントログ(イベントID 4625:ログオン失敗)を監視し、一定回数失敗したらファイアウォールでブロックするスクリプトの概念例を紹介しよう。
import subprocess
import time
# ログ監視用の簡単なロジック(実際にはELKやSIEM連携を推奨)
def monitor_rdp_failures():
# PowerShellでイベントログから直近の失敗を抽出
cmd = "Get-EventLog Security -InstanceId 4625 -Newest 10"
result = subprocess.run(['powershell', '-Command', cmd], capture_output=True, text=True)
# 失敗ログからIPアドレスを解析し、ブラックリスト化する処理をここに記述
# 例: netsh advfirewall firewall add rule name="Block_Attacker" dir=in action=block remoteip=1.2.3.4
print("ログ監視中: 異常な試行回数を検出したら自動遮断へ移行")
if __name__ == "__main__":
while True:
monitor_rdp_failures()
time.sleep(60) # 1分おきにチェック
—
4. ゼロトラスト的アプローチ:RDPを「公開」しない
ここまで防御策を語ってきたが、シニアエンジニアとしてあえて言わせてもらおう。「インターネットに直接RDPを公開するな」。これが結論だ。
現代のインフラ運用において、3389をグローバルIPにマッピングするのは、火薬庫にマッチを持ち込むようなものだ。もしリモートアクセスが必要なら、以下の代替案を検討せよ。
- VPNの導入: 接続元をIPで制限し、多要素認証(MFA)を必須にする。
- RD Gatewayの利用: Webベースで認証をラップし、HTTPS(443)経由でRDPを通す。
- ゼロトラストアクセス(ZTA):
Cloudflare AccessやTailscaleなどを使い、そもそもポートを外部公開せずにエンドポイントを接続する。
curlで確認するポートの挙動(疎通確認)
万が一、テスト環境でポートを開放せざるを得ない場合でも、curlを使って外部からどう見えているかを確認しておくことは重要だ。
# 対象サーバーのRDPポートが空いているか確認
curl -v telnet://your-server-ip:3389
# もしレスポンスが「Connected」なら即座にセキュリティグループを見直せ
—
最後に:防御は「多層」で戦うもの
ネットワークセキュリティに「これさえやれば完璧」という銀の弾丸はない。
1. NLAの強制(認証を先に済ませる)
2. イベントログ監視と自動遮断(泥臭い防御)
3. VPN/ZTAによる隠蔽(そもそも攻撃対象にしない)
これらを組み合わせることで初めて、諸君のネットワークは強固な城壁となる。ポートを閉じることは、単なる設定変更ではない。それは、君が守るべきデータと、信頼を寄せるユーザーを守るための「意思表示」だ。
今日のパケットの流れが、平穏であることを祈っている。何かトラブルがあれば、またいつでもここへ来るといい。エンジニア同士、知見を共有していこう。
コメント