RustScan は Autumn "bee-san" Skerritt 率いる RustScan チームが開発した Rust 製の超高速ポートスキャナ。最大の特徴は 65535 個の TCP ポート全体を数秒で走査し、開いていたポートをそのまま nmap に自動で受け渡してサービス/バージョン/スクリプトスキャンへ繋ぐこと。設計思想はシンプルで、「速いポート発見は RustScan、深い調査は nmap」という分業。つまり RustScan は nmap を置き換えるのではなく補完するツールだ。「nmap で全ポートを撃つと遅い」という長年の悩みを、Rust の並列性で一気に潰しつつ、慣れ親しんだ nmap の解析力はそのまま活かす — それが RustScan のポジションになる。
RustScan とは — 速度と nmap 連携 #
RustScan を理解する鍵は 2 つ、圧倒的な走査速度とnmap への自動受け渡し。まず RustScan が高速に「どのポートが開いているか」だけを洗い出し、その結果を nmap に渡して「そのポートで何が動いているか」を深掘りする。役割がきれいに分かれている。
| 段階 | 担当 | やること |
|---|---|---|
| ポート発見 | RustScan | 65535 ポートを並列で叩き、開いているものを高速に特定 |
| サービス特定 | nmap | 開いたポートだけにバージョン検出・スクリプトを実行 |
この分業のおかげで、「全ポートを nmap で -p- するのは遅すぎる」という問題が解消される。RustScan が候補ポートを絞り込んでから nmap に渡すので、nmap は無駄な閉ポートを相手にせず、開いているポートだけに集中できる。
RustScan は ポート発見の速さに特化しているだけで、サービス特定・スクリプト実行は 内部で nmap を呼んでこなしている。だから RustScan を使うときも nmap がインストールされていることが前提であり、nmap の知識 (-sV / -sC / -A 等) はそのまま活きる。両者は競合ではなく、上流 (発見) と下流 (解析) の関係だ。
法的・倫理的な注意 #
ポートスキャンは「相手が何のサービスを開けているか」を無断で調べる行為であり、対象によっては明確な偵察・攻撃の前段階と見なされる。とりわけ RustScan は短時間に数万ポートへ大量のパケットを撃つため、技術的にも負荷が高い。許可なく他人のホストへ RustScan を撃つことは、日本の不正アクセス禁止法や業務妨害に問われ得る違法行為になりうる。
- 自分が所有・管理しているホスト — ローカルの検証環境、自分が契約している VPS、隔離した学習用ラボ
- 書面で明示的に許可された対象 — ペネトレーションテスト契約や脆弱性診断契約で、スコープ (対象ホスト・期間・レート制限) が文書化されているもの
- 正規の学習プラットフォーム — Hack The Box、TryHackMe など、運営がポートスキャンを許可している環境
高速なツールほど「軽い気持ちで他所に撃つ」ことが致命傷になる。バッチサイズ (-b) を上げて本番ネットワークへ撃てば、相手の機器や回線に過負荷をかけ、損害賠償・刑事責任という最悪の結末もあり得る。対象と許可を必ず先に確認すること。
基本の使い方とターゲット指定 #
RustScan の最小形は、ターゲットを -a (--addresses) で渡すだけ。これだけで全ポートを高速走査し、開いたポートを自動で nmap に渡す。-a はカンマ区切りの複数指定、CIDR 表記、ホスト名にも対応する。
| 指定方法 | 書き方 | 用途 |
|---|---|---|
| 単一ホスト | -a 10.0.0.1 |
1 台を全ポート走査 |
| 複数ホスト | -a 10.0.0.1,10.0.0.2 |
カンマ区切りで列挙 |
| CIDR | -a 192.168.1.0/24 |
サブネットを一括スイープ |
| ポート限定 | -p 80,443,8080 |
特定ポートだけ |
| ポート範囲 | --range 1-1000 |
範囲を区切って走査 |
$ rustscan -a 10.0.0.1
# -a でターゲットを指定(位置引数 rustscan 10.0.0.1 でも可)
# 65535 ポートを高速走査し、開いたポートを自動で nmap に渡す走査範囲を絞りたいときは --range (連続範囲) か -p (個別ポート列挙) を使う。「まず狭く速く、当たりがあれば広げる」という運用がしやすい。
$ rustscan -a 10.0.0.1 --range 1-1000
# 1〜1000 番ポートだけに限定して走査
$ rustscan -a 10.0.0.1 -p 80,443,8080
# -p で個別ポートをカンマ列挙
$ rustscan -a 192.168.1.0/24 -g
# CIDR で /24 を一括スイープ、-g で ip:ports だけの機械可読出力結果をスクリプトでパースしたいなら -g (--greppable) を使う。アスキーアートや装飾を省き、ip:ports だけを淡々と出力する。スクリーンリーダー利用者向けには -A (--accessible) があり、装飾を減らした読み上げやすい出力になる。バナーが邪魔なら --no-banner で消せる。
速度チューニングと "Too many open files" 対策 #
RustScan の速さは 大量のポートを並列に叩くことで成立している。その並列度を決めるのが バッチサイズ (-b) で、既定は 4500。一度にこれだけのポートを同時に試すため、システムのファイルディスクリプタ上限 (ulimit) を超えると "Too many open files" エラーで失敗する。これが RustScan で最も遭遇しやすい落とし穴だ。
| オプション | 役割 | 既定値 |
|---|---|---|
-b / --batch-size |
並列に試すポート数 | 4500 |
-u / --ulimit |
スキャン用にファイルディスクリプタ上限を引き上げる | — |
-t / --timeout |
ポートごとのタイムアウト (ミリ秒) | 1500 |
--tries |
ポートごとの再試行回数 | — |
--scan-order |
走査順 (serial / random) |
— |
バッチサイズが ulimit を超えると Too many open files で落ちる。対処は 2 通り — (A) -u で ulimit を引き上げる、または (B) -b でバッチサイズを下げる。低スペック環境や制限の厳しいホストでは -b 1000 程度まで落とすと安定する。逆に余裕のある環境では -u を上げて並列度を稼ぐと速くなる。
$ rustscan -a 10.0.0.1 -b 1000 -u 5000
# -b 1000 並列ポート数を下げて "Too many open files" を回避
# -u 5000 ファイルディスクリプタ上限を引き上げる
$ rustscan -a 10.0.0.1 -t 2000
# -t 2000 応答の遅い相手向けにタイムアウトを 2000ms に延長(既定 1500)走査順は --scan-order で serial (番号順) か random (ランダム) を選べる。よく使うターゲットがあるなら、設定ファイル ~/.rustscan.toml に ports や batch_size の既定値を書いておくと毎回の指定を省ける。逆に設定ファイルを無視して素の挙動で走らせたいときは --no-config を付ける。
nmap への受け渡しと実戦ワークフロー #
RustScan の真価は 「-- (ダブルダッシュ) 以降をそのまま nmap に渡す」仕組みにある。RustScan が開いたポートを特定したあと、-- の後ろに書いた引数を nmap にそっくり引き継いで実行する。つまり 「速い発見」と「nmap の深い解析」を 1 コマンドで連結できる。
$ rustscan -a 10.0.0.1 --range 1-1000 -- -sV
# 1〜1000 を高速走査 → 開いたポートを nmap に渡す
# -- 以降(-sV)は nmap にそのまま渡る = サービス/バージョン検出実戦では「全ポートを RustScan で発見し、開いたポートだけに nmap のアグレッシブスキャン (-A) とデフォルトスクリプト (-sC) を当てる」というワークフローが定番。速度チューニングと nmap 受け渡しは同時に使える。
$ rustscan -a 10.0.0.1 -b 1000 -u 5000 -- -A -sC
# -b/-u で安定化しつつ全ポートを発見
# -- 以降の -A -sC が nmap に渡る
# -A = OS/バージョン/traceroute、-sC = デフォルトスクリプト新しいマシンに着手するとき、まず rustscan -a TARGET -- -sV -sC -A を撃つのが鉄板。数秒で全ポートが分かり、そのまま nmap がサービスとスクリプト結果まで出してくれるので、「全ポート発見 + サービス特定」を 1 発で完了できる。-- の後ろは普段の nmap オプションをそのまま並べればよく、nmap の知識を新たに覚え直す必要はない。
Docker で手早く試したいときは公式イメージを使える。ローカルにバイナリを入れずに動かせる。
$ docker run -it --rm --name rustscan rustscan/rustscan:latest -a 127.0.0.1
# 公式イメージで RustScan を実行(バイナリのインストール不要)類似ツールとの位置づけ — いつ RustScan を選ぶか #
ポートスキャナは複数あり、RustScan の立ち位置は 「爆速のポート発見 + nmap へのシームレスな受け渡し」という一点に尽きる。速度そのものは masscan も負けないが、nmap 連携の手軽さで差をつける。
| ツール | 言語 | 特徴 |
|---|---|---|
RustScan | Rust | 爆速のポート発見に特化。開いたポートを -- 以降で nmap に自動受け渡しできるのが最大の武器 |
nmap | C | 定番。サービス特定・スクリプト・OS 検出まで多機能だが全ポート走査は遅い。RustScan の受け渡し先 |
masscan | C | 同じく超高速でインターネット規模の走査が得意。ただし nmap との統合は RustScan ほど手軽でない |
naabu | Go | ProjectDiscovery 製。パイプライン連携に向いた軽量ポートスキャナ |
| 観点 | RustScan | nmap 単体 |
|---|---|---|
| 全ポート走査の速さ | 数秒 | 分単位で遅い |
| サービス/バージョン特定 | nmap に委譲 | 本職 |
| 1 コマンドで発見→解析 | `-- -sV -sC` | `-p-` で全部 nmap |
「全ポートを速く洗い出したい」なら RustScan が最短。masscan も速いが、そのまま nmap に流して深掘りまで一気通貫にできる手軽さは RustScan ならではだ。RustScan は nmap の代替ではなく 前段の加速装置と捉えるのが正しい。まず rustscan -a TARGET -- <nmap オプション> を体に覚えさせ、"Too many open files" が出たら -u / -b で調整する — これが RustScan を使いこなす第一歩になる。