nmapを定期的に使うようになった理由
50人規模のオフィスと小規模なデータセンターのネットワーク管理を担当し始めた頃、サーバーに「謎の」ポートが突然現れることがよくあった。あるとき、開発チームが社内サービスをテストデプロイしたまま停止を忘れてしまい、そのサービスが0.0.0.0にバインドされてインターネットに露出した状態になっていた。問題が起きる前に早期発見できたのは幸いだった。
それ以来、nmapは週次チェックリストの定番ツールになった。ハッキングのためではなく、自分のサーバーが外部に何を公開しているかを正確に把握するためだ。サービスを一つひとつ手動で確認する代わりに、nmapのコマンド一つでサブネット全体を数分でスキャンできる。
LinuxへのNmapのインストール
主要なディストリビューションでは、nmapは公式リポジトリから入手できる:
# Ubuntu / Debian
sudo apt update && sudo apt install nmap -y
# CentOS / RHEL / Rocky Linux
sudo dnf install nmap -y
# Arch Linux
sudo pacman -S nmap
インストール後にバージョンを確認する:
nmap --version
# Nmap version 7.94 ( https://nmap.org )
重要な注意点:自分自身のシステムでnmapを実行することは完全に合法だ。しかし、許可なく他者のIPをスキャンすることは違法行為に当たる――米国ではComputer Fraud and Abuse Actに基づいて起訴される可能性があり、日本でも不正アクセス禁止法などで同様の規制がある。nmapは自分が管理権限を持つインフラのセキュリティ診断にのみ使用している。
詳細なスキャン設定とテクニック
1. 基本的なポートスキャン — サーバーの公開ポートを即座に把握
まずはシンプルに — サーバーがどのポートでリッスンしているかを確認する:
# 最も一般的な1000ポートをスキャン(デフォルト)
nmap 192.168.1.100
# 全65535ポートをスキャン — 低速だが網羅的
nmap -p- 192.168.1.100
# 特定のポート範囲をスキャン
nmap -p 22,80,443,3306,6379 192.168.1.100
出力例:
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
443/tcp open https
3306/tcp open mysql
MySQL(3306番)がopenになっているのが見える?このサーバーが公開されているなら、深刻な問題だ。実際にこのケースを経験したことがある――開発者がテスト時にデフォルトの0.0.0.0バインドのまま放置し、後で変更するのを忘れたのだ。
2. サービスバージョンの検出 — 脆弱性評価に不可欠
ポートが開いているだけでは表面的な情報に過ぎない。より重要なのはバージョン情報だ――CVEデータベースと照合するために:
# -sV: detect service version
nmap -sV 192.168.1.100
# -sC(デフォルトスクリプト)と組み合わせてより多くの情報を取得
nmap -sV -sC 192.168.1.100
より詳細な結果が得られる:
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.6 (Ubuntu Linux; protocol 2.0)
80/tcp open http nginx 1.24.0 (Ubuntu)
443/tcp open ssl/http nginx 1.24.0
OpenSSH 8.9、nginx 1.24 ― NVD(nvd.nist.gov)ですぐに検索して、アクティブなCVEがないか確認しよう。この作業は2分もかからないが、誰かに悪用される前に深刻な脆弱性を発見できることが多い。
3. サブネット全体のスキャン — 社内ネットワーク監査
このコマンドを毎週月曜の朝に実行して、ネットワークに変化がないか確認している:
# Pingスキャン — サブネット内のオンラインホストをリスト
nmap -sn 192.168.1.0/24
# 高速ポートスキャンと組み合わせる
nmap -sn -oG - 192.168.1.0/24 | grep 'Status: Up' | awk '{print $2}' > live_hosts.txt
nmap -iL live_hosts.txt -p 22,80,443,3306,5432,6379,27017 -oN scan_result.txt
結果をファイルに保存して、前週の結果とdiffで比較する。新しいIPや見覚えのないポートが突然出現したら――たいてい誰かが事前報告なしにデプロイしたサービスだ。
4. OS検出とフィンガープリンティング
# -O: OS検出(root権限が必要)
sudo nmap -O 192.168.1.100
# アグレッシブスキャン — 複数のテクニックを組み合わせ
sudo nmap -A 192.168.1.100
-Aオプションは4つの機能を一度に実行する:OS検出、バージョン検出、スクリプトスキャン、そしてtraceroute。特定のホストを詳しく監査する際に使用する。ただし本番環境での頻繁な実行は避けること――かなりのトラフィックを生成し、ログに明確な痕跡を残す。
5. ステルススキャン — ノイズを最小限に
# SYNスキャン(ハーフオープン)— 高速で対象のログに残りにくい
sudo nmap -sS 192.168.1.100
# UDPスキャン — 重要なサービスの多くがUDPを使用(DNS、SNMP、NTP)
sudo nmap -sU -p 53,123,161 192.168.1.100
UDPスキャンはTCPより低速なためよく見落とされる。しかし無視してはいけない。以前、ネットワーク機器でSNMP(UDP 161番ポート)がデフォルトのcommunity string「public」で有効になっているのを発見したことがある――これにより、認証なしで社内ネットワーク内のスイッチやルーターの設定情報を誰でも読み取れる状態だった。
6. NSEスクリプトの活用 — 高度なセキュリティ診断
NSE(Nmap Scripting Engine)には600以上のスクリプトが付属している――脆弱性チェックから詳細情報の列挙まで:
# 一般的な脆弱性をチェック
nmap --script vuln 192.168.1.100
# SSHの確認:ブルートフォース対策、暗号化アルゴリズム
nmap --script ssh-auth-methods,ssh2-enum-algos -p 22 192.168.1.100
# セキュリティHTTPヘッダーの確認
nmap --script http-security-headers -p 80,443 192.168.1.100
# SSL/TLS設定の確認
nmap --script ssl-enum-ciphers -p 443 192.168.1.100
ssl-enum-ciphersスクリプトは特に便利だ――サポートされているcipher suiteをリストアップし、各cipherを評価してくれる(A/B/C/F)。nginxのTLS設定を更新するたびに、このスクリプトで確認している。
スキャン結果の確認と定期モニタリングの設定
経時比較のためのスキャン結果保存
Nmapは複数の出力フォーマットに対応している。XMLはスクリプトでパースするために、プレーンテキストは直接読むために使用する:
# XML出力 — スクリプトでのパースや他ツールへのインポートに使用
nmap -sV -oX scan_$(date +%Y%m%d).xml 192.168.1.0/24
# すべてのフォーマットを同時に出力
nmap -sV -oA scan_$(date +%Y%m%d) 192.168.1.0/24
# 生成ファイル:scan_YYYYMMDD.nmap、scan_YYYYMMDD.xml、scan_YYYYMMDD.gnmap
# 2回のスキャンを比較して変更点を検出
diff scan_20240101.nmap scan_20240108.nmap
週次監査のためのシンプルな自動化スクリプト
#!/bin/bash
# /opt/scripts/weekly_nmap_audit.sh
SUBNET="192.168.1.0/24"
OUTDIR="/var/log/nmap-audit"
DATE=$(date +%Y%m%d_%H%M)
mkdir -p $OUTDIR
# サブネット全体の重要なポートをスキャン
nmap -sV -p 22,23,80,443,3306,5432,6379,27017,11211,9200 \
--open -oN "$OUTDIR/scan_$DATE.txt" $SUBNET
# 危険なポートが見つかった場合にアラートを送信(23=telnet、11211=memcached)
if grep -E '^[0-9]+.*23/tcp|11211/tcp' "$OUTDIR/scan_$DATE.txt"; then
echo "警告:危険なポートを検出しました!" | mail -s "[ALERT] nmap audit" [email protected]
fi
crontabに追加して自動実行する:
crontab -e
# 毎週月曜日の午前7時に実行
0 7 * * 1 /opt/scripts/weekly_nmap_audit.sh
スキャン結果で注目すべきポイント
- ポート23(Telnet) ― これを見つけたらすぐに無効化すること。Telnetはパスワードを含むすべての通信を暗号化せずに送信する
- ポート3306/5432(MySQL/PostgreSQL)がインターネットに公開されている ― データベースは絶対に直接公開すべきではない
- ポート6379(Redis)が認証なしで公開されている ― 以前、Redisにクリプトマイナーを仕込まれたケースを対処したことがある。原因を突き止めるまでの1週間、サーバーのCPUが100%で稼働し続けた
- ポート9200(Elasticsearch)が認証なしで公開されている ― この理由で数千件ものデータ漏洩が発生しており、大規模な顧客情報流出事件も多数起きている
- ポート11211(Memcached) ― DDoS増幅攻撃に悪用されやすく、増幅率は最大51,000倍にもなる
約3年間nmapでシステム監査を行ってきて気づいたのは、真の価値は最初のスキャンにあるのではないということだ。定期的に実行して結果を比較することにある。インフラは常に変化する――新しいサービスのデプロイ、アップデートで追加されるポート、再起動後にリセットされるファイアウォールルール。定期スキャンにより、他の誰かに発見される前に早期検出することができる。

