AWSで理解するNmap
こんにちは、matsuです。
今回は担当している案件のセキュリティテストで利用したNmapについて、AWS上で色々検証してみたので紹介させていただきます!
1.Nmapとは
Nmap(Network Mapper)は、サーバのポート状態を確認する際によく利用されるポートスキャンツールです。サーバの公開前確認や不要ポートの洗い出し、疎通確認など、インフラやセキュリティの現場で広く利用されています。
Nmapリファレンスガイド
Nmapには複数のスキャン方式が存在し、スキャン方式によって通信の流れも変化します。
本記事では、AWS上に検証環境を構築し、Nmapによるポートスキャン結果の違い・スキャン方式の違いを確認していきます。
また、tcpdumpを利用し、実際にどのようなパケットが流れているのかもあわせて見ていきます。
※ポートスキャンは、ネットワークの挙動を理解する上で有用ですが、対象は自分が用意した環境に限定するのが安全です。本記事ではAWS上の検証用サーバだけを対象とし、他人のサーバへのポートスキャンは想定していません。
2.検証環境
2つのVPC間をAWS Transit Gatewayで接続したシンプルな構成になります。
各VPC内のEC2はいずれもAmazon Linux 2023になります。

3.EC2(Amazon Linux 2023)へNmapをインストールする方法
閉域環境でも、EC2(Amazon Linux 2023)からS3 Gateway Endpoint経由でAmazon S3に通信できる状態であれば、sudo dnf install -y nmapによりNmapをインストールできます。
各VPC内のEC2にNmapをインストールします。

4.Nmapの主なオプション
Nmapの代表的なオプションとして、以下があります。
- -sT:TCP Connect Scan
TCPの3ウェイハンドシェイクを実際に完了させるスキャン方式です。 - -sS:SYN Scan
TCP接続を確立せずにポート状態を確認するスキャン方式です。 - -sU:UDP Scan
UDPポートを確認するスキャン方式です。 - -Pn:Ping確認を行わずスキャン
ホストのPing確認を行わずにスキャンを実施します。 - -p:ポート指定
スキャン対象ポートを指定します。 - -p-:全ポートスキャン
1〜65535まで全ポートをスキャンします。
5.検証
-sTと-sSによる通信の違い
-sTオプション時の通信を確認するため、各EC2上で下記の作業を実施しました。
-
lab-connectivity-2にて、
sudo nc -l -k -p 80を実施し、80ポートでの接続を受け付ける。

-
lab-connectivity-2にて、
sudo tcpdump -i any -n 'tcp port 80' -vvを実施し、80ポート宛の通信をリアルタイムで詳細表示する。
※tcpdumpはLinux/Unix系OS上で動作するパケットキャプチャツールです。Nmapと同様にEC2(Amazon Linux 2023)からS3 Gateway Endpoint経由でAmazon S3に通信できる状態であれば、sudo dnf install -y tcpdumpでインストール可能です。

-
lab-connectivity-1にて、
sudo nmap -sT -p 80 10.30.0.236を実施し、80ポートがopenになっていることを確認する。(10.30.0.236は検証時のlab-connectivity-2のアドレスになります)

-
lab-connectivity-2にて、80ポート宛の通信を確認し、SYN・SYN+ACK・ACKでTCP接続が確立されていることを確認する。(Flags [S]がSYN、Flags [S.]がSYN+ACK、Flags [.]がACK、Flags [R.]が RST/ACK)

また、-sSオプション時の通信を確認するため、各EC2上で下記の作業を実施しました。(手順2までは、-sTオプション時と同じです。)
-
lab-connectivity-2にて、
sudo nc -l -k -p 80を実施し、80ポートでの接続を受け付ける状態にする。 -
lab-connectivity-2にて、
sudo tcpdump -i any -n 'tcp port 80' -vvを実施し、80ポート宛の通信をリアルタイムで詳細表示する。 -
lab-connectivity-1にて、
sudo nmap -sS -p 80 10.30.0.236を実施し、80ポートがopenになっていることを確認する。(10.30.0.236は検証時のlab-connectivity-2のアドレスになります)

-
lab-connectivity-2にて、80ポート宛の通信を確認し、SYN・SYN+ACK・RSTで通信が終了していることを確認する。(Flags [S]がSYN、Flags [S.]がSYN+ACK、Flags [R]が RST)

-sTはTCPの3ウェイハンドシェイクを完了させて実際に接続を確立するため、通常のTCP通信に近い動作となります。
一方、-sSはSYN+ACKを確認した後にRSTを返して接続を終了するため、TCP接続を完全には確立しません。
AWS設定によるスキャン結果の違い
AWS上で想定される下記パターン時のNmapスキャン結果をまとめました。
前節の通信確認では80ポートを使用していますが、本節では443/TCPを例に掲載しています。
対象サーバで当該ポートを受け付けていない
対象サーバで443ポートでの接続を受け付けていない場合のスキャン結果です。
Host is upかつ443/tcp closedは、ターゲットホストまでTCPが届き、該当ポートで応答があった(RST)ことを示しています。

対象サーバのSecurity Groupで通信が許可されていない
対象サーバのSecurity Groupで443ポートの接続を許可していない場合のスキャン結果です。
filteredはポートが閉じているというより、スキャンパケットがSecurity Group等で遮断され、RSTもSYN+ACKも得られなかった状態を示しています。

対象サーバへの経路がない
EC2間の経路がない場合のスキャン結果です。
宛先CIDR向けルートが無いためスキャンパケットが対象サーバに届きません。PORTやSTATEの情報も出てきません。

6.まとめ
今回はNmapを利用し、AWS環境上でスキャン方式の違い、スキャン結果の違いについて確認しました。
tcpdumpを利用して実際のパケットを確認することで、-sT は TCP 接続を確立するのに対し、-sS はSYN+ACK確認後にRSTを返して接続を終了していることを確認できました。
また、TCP(-sS / -sT)のスキャン結果であるopen/closed/filteredは単なる表示の違いではなく、
- openはスキャンパケットが対象サーバまで届き、SYN+ACKが返る状態(ポートで待ち受けがある)
- closedはスキャンパケットが対象サーバまで届き、RSTが返る状態(ポートは閉じているが、ホストには到達している)
- filteredはスキャンパケットが対象サーバまで届かず、SYN+ACKもRSTも得られない状態。(Security Group等で遮断され、パケットがホストに届いていない場合も含む)
であることを確認しました。(UDPスキャンは今回は対象外としました。挙動がTCPと異なるため、別の機会に検証したいと考えています。)
さらに、AWS環境でSecurity Group、ルート設定を変更することによってスキャン結果が変化することも確認できました。
Nmapは単なるポートスキャンツールではなく、実際のTCP/IP通信やAWSネットワークの動作を理解する上でも非常に有用なツールであると感じました。
皆さんもぜひ使ってみてください!
