# ポートスキャンとは？攻撃の前触れかの見分け方・ログの確かめ方・防ぎ方と、脆弱性診断との違い

> ポートスキャンとは何かを、サーバーやAWSを運営する人向けに解説。公開アドレスが常に調べられている観測データ、スキャン・パスワード試行・侵入の兆候の見分け方、ss・ufw・VPCフローログ・GuardDutyでの確かめ方、公開範囲の絞り方、脆弱性診断との違いまで。

- 公開日: 2026-10-26
- 著者: 友田 陽大
- タグ: セキュリティ, 脆弱性診断, AWS, インフラ, ネットワーク, ポートスキャン
- URL: https://tomodahinata.com/blog/port-scan-detection-prevention-vulnerability-assessment-guide
- カテゴリ: 実践ネットワーク攻撃と防御
- 総合ガイド: https://tomodahinata.com/blog/network-penetration-testing-methodology-attack-defense-guide

## 要点

- ポートスキャンは、どのポートが開いていて何のサービスが動いているかを外から調べる行為。公開されたアドレスは常に調べられていて、NICTER の2025年の観測では、観測用のIPアドレス1つあたり年間約250万パケットが届いた
- スキャンされたこと自体は侵入ではない。見るべきは何が応答しているかと、知らない送信元からのログイン成功、/.env への 200 応答、自分のサーバーが外をスキャンしているといった侵入の兆候
- GuardDuty の Recon:EC2/PortProbeUnprotectedPort は「自分の開いたポートが探られている」、Recon:EC2/Portscan は「自分のインスタンスが外をスキャンしている」。後者は侵入を疑う
- スキャンは止められないが、応答する範囲は絞れる。受信は既定で拒否し、DB・キャッシュを0.0.0.0/0に開けず、SSHは鍵認証と送信元の制限か Session Manager に。ポート番号の変更はノイズを減らすだけで、WAF は HTTP(S) しか見ない
- ポートスキャンは「何が開いているか」、脆弱性スキャンは「既知の脆弱性があるか」、脆弱性診断は「知見のある人が調べて脆弱性がないか」、ペネトレーションテストは「実際に目的を達成できるか」に答える

---

**ポートスキャンとは、サーバーのどのポート（通信を受け付ける入口の番号）が開いていて、そこで何のサービスが動いているかを、外から調べる行為です。** インターネットに公開された IP アドレスは、毎日のように調べられています。情報通信研究機構（NICT）の観測では、2025年に観測用の IP アドレス1つあたり年間約250万のパケットが届き、観測開始以来の最多でした。**スキャンされたこと自体は侵入ではありません。** 大事なのは、何が応答していて、それがどう守られているかです。

今すぐやることは3つです。

1. **何が応答しているかを確かめる。** サーバーで `sudo ss -tulpn` を実行し、クラウドの設定で `0.0.0.0/0` に開いているルールを一覧します（手順は[自分の公開範囲を外から確かめる](#自分の公開範囲を外から確かめる)）。
2. **公開しなくてよいものを閉じる。** データベース、キャッシュ、管理画面は外に開けません。SSH は鍵認証にして、送信元を絞ります。
3. **侵入の兆候だけは確かめる。** 知らない送信元からの SSH ログイン成功（`Accepted` の行）や、`/.env` へのリクエストに 200 が返っていないかを見ます。GuardDuty を有効にしているなら、`Recon:EC2/Portscan`（自分のサーバーが外をスキャンしている）も侵入を疑うサインです。

この記事はサーバー・VPS・AWS・Web サービスを運営する人向けです。nmap がポートの状態をどう判定しているかは [ポートスキャン（nmap）の仕組みの記事](/blog/network-reconnaissance-port-scanning-nmap-service-detection-defense-guide)で扱っています。

---

## ポートスキャンとは — 何を調べられているのか

NIST（米国国立標準技術研究所）の試験の手引き [SP 800-115](https://csrc.nist.gov/pubs/sp/800/115/final) は、ポートスキャンを「ネットワークポートとサービスの識別」と呼びます。開いているポートと、HTTP などのサービス、それを動かすアプリケーションを特定する作業です。接続したときにサービスが返す文字列（バナー）から、アプリケーションの版や OS まで分かることがあります。

### TCPスキャンとは

**TCPスキャンとは、TCP の接続手順に対する相手の応答から、ポートが開いている（open）か、閉じている（closed）か、遮られて判定できない（filtered）かを調べる方法です。** 代表的なのは、接続を確立する手前でやめる SYN スキャン（nmap の `-sS`。Unix では root 権限が要る）と、OS に接続を完了させる connect スキャン（`-sT`。root 権限は要らないが、相手のログに残りやすい）です（[nmap の公式リファレンス](https://nmap.org/book/man-port-scanning-techniques.html)）。応答の読み方は [nmap の仕組みの記事](/blog/network-reconnaissance-port-scanning-nmap-service-detection-defense-guide)へ。

UDP（DNS の 53、SNMP の 161/162 など）は `-sU` で調べます。ポートの状態は調べる場所で変わり、同じネットワーク内からは `open`、インターネット越しには `filtered` と見えることがあります。**外から何が見えるかは、外から調べないと分かりません。**

## なぜ毎日スキャンされるのか — 観測データで見る「常時探索」

**公開された機器は、特定の誰かに狙われていなくても、常に調べられています。**

| 観測 | 数値 | 出典 |
|---|---|---|
| NICTER のダークネット観測（2025年） | 1 IP アドレスあたり年間 2,504,680 パケット。観測開始以降で最多（2024年は 2,427,977） | [NICTER観測レポート2025](https://csl.nict.go.jp/report/NICTER_report_2025.pdf) |
| 同、調査目的のスキャンの割合 | 全パケットの約 55.0%（2024年は約 60.2%） | 同上 |
| 警察庁のセンサー（2025年） | 1日・1 IP アドレスあたり 9,605.7 件の不審なアクセス（前年比 0.9%増） | [警察庁 令和７年の情勢](https://www.npa.go.jp/publications/statistics/cybersecurity/data/R7/R07_cyber_jousei.pdf) |
| 警察庁のセンサー（2026年1〜6月） | 1日・1 IP アドレスあたり 1万3,687 件（前年比 50.7%増） | [警察庁 令和８年上半期の情勢](https://www.npa.go.jp/publications/statistics/cybersecurity/data/R8kami/R08_kami_cyber_jousei.pdf) |

ダークネットとは、到達できるのに使われていない IP アドレスのことです。本来は何も届かないはずの宛先なので、届くのはスキャンや、DDoS 攻撃の跳ね返りなどです。NICTER はこの総数が日本全体への攻撃件数ではないと注記しており、約 55.0% は調査目的のスキャンでした。警察庁は、不特定多数を対象にしたアクセスが半数以上を占めることから、公開された機器やサービスは「常時第三者に探索される前提で運用されている」と述べています。

送信元の国や IP も、踏み台などの理由で送信者の所在と一致しない場合があります（警察庁）。**スキャン元を追いかけるより、自分の側で応答する範囲を絞る方が確実です。**

## ログに出ているのは何？ スキャン・パスワード試行・侵入の兆候の見分け方

**「怪しいアクセス」の多くはスキャンかパスワード試行で、急いで対応すべきなのは侵入の兆候です。**

| 見えているもの | ログでの見え方 | 意味 | まずやること |
|---|---|---|---|
| ポートスキャン | 同じ送信元から短時間に多くの宛先ポート（ブロックログの `DPT=`、フローログの `REJECT`） | 何が開いているかを調べている | 開いているポートを確かめ、要らないものを閉じる |
| SSH・RDP へのパスワード試行 | SSH なら `Failed password for invalid user …` や `Invalid user …` が大量に並ぶ | ありがちな ID とパスワードを試している | 鍵認証にし、送信元を絞る |
| Web の探索 | アクセスログに `/wp-login.php` や `/.env` へのリクエスト | 隠れた管理画面や置き忘れたファイルを探している | そのリクエストのステータスコードを見る。404 か 403 なら渡していない。管理画面を誰でも開けないかも確かめる |
| 侵入の兆候 | 知らない送信元からの `Accepted …`（ログイン成功）、`/.env` や `/.git/` へのリクエストに 200、自分のサーバーが外を攻撃しているという GuardDuty の検出 | すでに入られたか、秘密情報が漏れた可能性がある | 調査と隔離を優先する。そのファイルのキーやパスワードは漏れたものとして発行し直し、ファイルを公開される場所から外す |

Web の探索は MITRE ATT&CK の「Wordlist Scanning（T1595.003）」に当たり、ポートスキャンとは別物です。URL を記録しない VPC フローログには出ないので、Web サーバーや ALB のアクセスログで見ます（ALB なら `elb_status_code` と `target_status_code` の項目）。外から自分のドメインを確かめるなら次のとおりです。

```bash
# example.com は自分のドメインに置き換える。ステータスコードと本文のバイト数を表示する
curl -s -o /dev/null -w '%{http_code} %{size_download}\n' https://example.com/.env
```

404 か 403 なら渡していません。200 でもトップページと同じ大きさなら、どの URL にも同じページを返す作りのことがあるので、中身を開いて確かめます。

### GuardDuty の検出名の読み方

[GuardDuty](https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_finding-types-ec2.html) では、自分のインスタンスが「狙われた側」か「やっている側」かで、重要度と意味が変わります。

| 検出名 | 意味 | 既定の重要度 | 対応 |
|---|---|---|---|
| `Recon:EC2/PortProbeUnprotectedPort` | セキュリティグループ・ACL・ホストのファイアウォールのどれにも遮られていないポートが、既知のスキャナーに探られている | Low（9200 / 9300 なら High）。80 と 443 では出ない | 公開が必要か見直す。22 や 3389 なら社内の IP に絞る |
| `UnauthorizedAccess:EC2/SSHBruteForce`（RDP 版もある） | 総当たり | 狙われた側は Low、やっている側は High | やっている側なら侵入されたと見なす |
| `Recon:EC2/Portscan` | **自分のインスタンスが**外にポートスキャンをしている | Medium | 自分のスキャナーでなければ、侵入された可能性が高い |
| `Impact:EC2/PortSweep` | **自分のインスタンスが**多数の IP の同じポートを探っている | High | 想定外なら侵入を疑う |

フローログを情報源にする EC2 の検出は IPv6 の通信に対応せず、SSH の総当たりの検出は 22 番ポートしか見ません。自分のスキャナーが出す検出の抑え方は [GuardDuty の抑制ルールの記事](/blog/aws-guardduty-suppression-rules-trusted-ip-threat-lists-tuning-guide)にあります。

侵入を疑うときの [AWS の手順](https://docs.aws.amazon.com/guardduty/latest/ug/compromised-ec2.html)は、マルウェアの有無を調べ、`0.0.0.0/0` を許可しない隔離用のセキュリティグループに付け替えることです（すでに追跡中の接続はこれでは切れません）。止められなければインスタンスを作り直します。全体は [インシデント対応の記事](/blog/incident-response-nist-800-61r3-csirt-runbook-playbook-production-guide)へ。

## ポートスキャンのログの確かめ方

### Linux サーバー: 何が待ち受けているか

```bash
# -t TCP / -u UDP / -l 待ち受け中だけ / -p プロセス / -n 名前を解決しない
sudo ss -tulpn
```

見るのは待ち受けアドレスです。`0.0.0.0`（全 IPv4）、`::`（全 IPv6）、`*`（全インターフェース）は、ファイアウォールが無ければ外から届きます。`127.0.0.1` や `::1` はサーバーの中からしか届きません。PostgreSQL は既定で localhost だけ、Redis も既定の設定は `bind 127.0.0.1 -::1` なので、`0.0.0.0` になっていたら意図した変更かを確かめます。

Docker を使っているなら要注意です。[公式ドキュメント](https://docs.docker.com/engine/network/packet-filtering-firewalls/)によると、公開したコンテナのポートへの通信は ufw より前に振り分けられ、ufw のルールが効きません。ホストの中だけで使うなら、localhost のアドレスを付けて公開します（[ポート公開の公式ドキュメント](https://docs.docker.com/engine/network/port-publishing/)の例）。

```bash
# Docker のホストからだけ届くように公開する（IPv4 と IPv6 の localhost）
docker run -p 127.0.0.1:8080:80 -p '[::1]:8080:80' nginx
```

ただし同じページは、Docker 28.0.0 より前の版では、同じ L2 セグメントの機器（同じスイッチにつながる機器など）から localhost に公開したポートに届くと警告しています。

### ファイアウォールのブロックログ（ufw）

Ubuntu の ufw は**初期状態では無効**で、そのままではブロックログも出ません。有効にすると今の SSH 接続が切れることがあるので、SSH で接続中なら先に SSH を許可します。

```bash
sudo ufw status verbose     # 「Status: inactive」なら無効
# 先に SSH を許可する（198.51.100.7 は自分の接続元 IP の例）
sudo ufw allow proto tcp from 198.51.100.7 to any port 22
# 接続元の IP が変わるなら、代わりに回数制限つきで開ける
# sudo ufw limit 22/tcp
sudo ufw enable
sudo ufw status verbose     # 許可したルールが並んでいるか確かめる
```

ログを有効にすると、既定のレベル low で、ブロックしたパケットが件数を制限しつつ `[UFW BLOCK]` 付きで記録されます。

```bash
sudo ufw logging on
# 今日のブロックログ（カーネルのログとして記録される）
sudo journalctl -k --since today --grep "UFW BLOCK"
# rsyslog を使う環境では専用のファイルにも書かれる
sudo grep "UFW BLOCK" /var/log/ufw.log
```

1行はこのような形です（値は説明用の例で、一部の項目を省いています）。

```text
[UFW BLOCK] IN=eth0 OUT= SRC=198.51.100.23 DST=203.0.113.10 PROTO=TCP SPT=40213 DPT=3389 SYN
```

同じ `SRC`（送信元）から `DPT`（宛先ポート）の違う行が短時間に並べば、スキャンです。ブロックの行は「届いたが入れなかった」記録で、それ自体は防げている証拠です。

### SSH のログ: 試行と、成功したログイン

SSH の認証ログは、ファイルに書き出す設定なら Debian・Ubuntu 系は `/var/log/auth.log`、RHEL・Fedora 系は `/var/log/secure` です。Debian 12 以降は rsyslog が既定で入らないので、ファイルが無ければ systemd のジャーナルを見ます（Ubuntu のユニット名は `ssh.service`）。

```bash
# 失敗した試行（多くはパスワードの総当たり）
sudo grep -E "Failed|Invalid user" /var/log/auth.log | tail -n 20
# 成功したログイン。知らない送信元が無いかを確かめる
sudo grep "Accepted" /var/log/auth.log
# ファイルが無い環境（Ubuntu）
sudo journalctl -u ssh.service --since yesterday --grep "Accepted"
```

OpenSSH は成功したログインを `Accepted publickey for deploy from 192.0.2.50 port 50022 ssh2` で始まる行で記録します（ユーザー名と IP は例）。`Failed` がいくら並んでも失敗の記録です。**注意すべきは、心当たりのない送信元からの `Accepted` です。**

### AWS: VPC フローログの REJECT と GuardDuty

[VPC フローログ](https://docs.aws.amazon.com/vpc/latest/userguide/flow-log-records.html)は、ネットワークインターフェースを出入りする IP 通信の記録で、**自分で作成しないと残りません**。通信の経路の外で集めるので、速度には影響しません。既定の形式の項目と、[AWS の公式例](https://docs.aws.amazon.com/vpc/latest/userguide/flow-logs-records-examples.html)（RDP の 3389 番への通信が拒否された記録）は次のとおりです。

```text
version account-id interface-id srcaddr dstaddr srcport dstport protocol packets bytes start end action log-status
2 123456789010 eni-1235b8ca123456789 172.31.9.69 172.31.9.12 49761 3389 6 20 4249 1418530010 1418530070 REJECT OK
```

`REJECT` は、セキュリティグループやネットワーク ACL に許可されなかった通信などです（`6` は TCP）。CloudWatch Logs に送っているなら、Logs Insights で「拒否された宛先ポートの種類が多い送信元」を出せます。次のクエリは公式ドキュメントの構文から組み立てたもので、実際のロググループでは実行していません。

```text
filter action = "REJECT"
| stats count(*) as attempts, countDistinct(dstPort) as ports by srcAddr
| sort ports desc
| limit 20
```

記録は既定で最大10分単位にまとめられ（Nitro ベースのインスタンスでは常に1分以内）、CloudWatch Logs への配信は通常およそ5分のベストエフォートです。即時の監視には向きません。

GuardDuty は独立した経路でフローログのデータを分析するので、GuardDuty のためにフローログを作る必要はありません。ただしそのログは見せてくれません（導入は [GuardDuty の導入記事](/blog/aws-guardduty-threat-detection-multi-account-terraform-eventbridge-guide)、費用は [コストの記事](/blog/aws-guardduty-cost-optimization-pricing-finops-guide)へ）。`/wp-login.php` のような Web の探索は ALB のアクセスログで見ますが、これは既定で無効です。

## ポートスキャンは防げる？ 防げるのは「応答する範囲」

**スキャンが届くこと自体は止められません。** 止められるのは、届いたスキャンに何が応答するかです。

- [ ] **受信は既定で拒否にする。** AWS のセキュリティグループは作った直後は受信のルールが無いので、必要なポートだけを足します。ただし Lightsail はインスタンスごとのファイアウォールで管理し、Ubuntu などの OS だけのイメージでも、作成直後から SSH（22）と HTTP（80）が全ての IP アドレスに開いています。ufw は初期状態で無効なので、上の手順で有効にします。GCP の default ネットワークには SSH（22）と RDP（3389）を `0.0.0.0/0` から許可するルールが最初からあるので、削除するか絞ります。
- [ ] **データベースとキャッシュを `0.0.0.0/0` に開けない。** PostgreSQL（5432）、MySQL（3306）、Redis（6379）、MongoDB（27017）、Elasticsearch・OpenSearch（9200 / 9300）は、アプリのサーバーから届けば十分です。Redis の公式ドキュメントは、外の攻撃者が `FLUSHALL` の1コマンドで全データを消せると警告しています。RDS なら `PubliclyAccessible` を無効にします。
- [ ] **SSH・RDP を全世界に開けない。** 鍵認証だけにして送信元を絞るか、受信ポートを開けずに済む [Session Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html)（GCP なら IAP の TCP 転送）に替えます。
- [ ] **管理画面を誰でも開ける場所に置かない。** WordPress の公式ハンドブックも、`wp-login.php` を特定の IP だけに許可する例を載せています。
- [ ] **IPv6 を忘れない。** `::/0` からの許可も同じように見直します。Lightsail では IPv4 と IPv6 のファイアウォールを別々に設定します。
- [ ] **開けておくものは更新を続ける。** バナーから版が分かれば、その版の既知の脆弱性を探されます。
- [ ] **パスワード試行には回数の制限を。** ufw の `limit` ルールは、同じ IP が30秒以内に6回以上接続しようとすると拒否します。fail2ban は失敗の多い IP を一定時間ブロックしますが、弱い認証の危険はなくせないと自ら書いています。OpenSSH 9.8 以降は、失敗を続ける送信元を一時的に拒否する機能（PerSourcePenalties）が既定で有効です。

SSH の設定は、実際に効いている値を確かめてから変えます。OpenSSH 本体の既定は `PasswordAuthentication yes` で、配布元やクラウドのイメージによって違う値が入っていることがあります。Ubuntu では `/etc/ssh/sshd_config.d/*.conf` が本体の設定より先に、ファイル名の辞書順で読まれます。OpenSSH は多くの項目で最初に読んだ値を使うので、**同じ項目を書いたファイルが名前の順で先にあると、自分の設定は無視されます。** クラウドのイメージでは、cloud-init がパスワード認証を許す設定のとき `50-cloud-init.conf` に `PasswordAuthentication yes` を書きます。

```bash
# 今効いている値と、置かれているファイルを確かめる
sudo sshd -T | grep -i -E "passwordauthentication|kbdinteractiveauthentication|permitrootlogin"
ls /etc/ssh/sshd_config.d/
```

```text
# /etc/ssh/sshd_config.d/00-disable-password.conf（既存のファイルより名前の順で先に来る名前にする）
PasswordAuthentication no
KbdInteractiveAuthentication no
```

```bash
# -t は構文だけを確かめる
sudo sshd -t
# -T で効く値を確かめる。どちらも no と出ること
sudo sshd -T | grep -i -E "passwordauthentication|kbdinteractiveauthentication"
# 再起動（Ubuntu の場合）
sudo systemctl restart ssh.service
```

設定を誤ると締め出されるので、今のセッションを閉じずに、別の端末から鍵でログインできることを確かめてください。

### よくある誤解: ポート番号の変更、WAF、IP のブロック

| 対策 | 効果 | 限界 |
|---|---|---|
| SSH を 22 以外に移す | ログのノイズが減る | 代わりの番号も調べられる（2222/TCP は NICTER の2025年の観測で、調査目的のスキャンを除いた攻撃関連パケットの宛先ポートの10番目）。GuardDuty の SSH 総当たりの検出も出なくなる |
| WAF を置く | 指定した条件（ルール）に合う HTTP(S) のリクエストを遮断できる | AWS WAF が見るのは CloudFront・ALB などに届いた HTTP(S) のリクエスト。SSH やデータベースのポートへの接続は対象外で、そこはセキュリティグループやファイアウォールの役目になる。ルールで見分けられない攻撃も通る |
| スキャン元の IP をブロック | その IP からは届かなくなる | 送信元は膨大で（NICTER が既知の調査組織と判定したものだけで 17,348 の IP アドレス）、踏み台のこともある |

詳しくは [WAF の多層防御の記事](/blog/waf-defense-in-depth-aws-waf-cloud-armor-owasp-guide)と [認証の脆弱性の記事](/blog/authentication-vulnerabilities-brute-force-2fa-bypass-attack-guide)で扱っています。

## 自分の公開範囲を外から確かめる

### 先に範囲を決める: 調べてよいのは自分の資産だけ

**ポートスキャンをしてよいのは、自分が管理する資産か、書面で許可を得た範囲だけです。** [nmap の公式ガイド](https://nmap.org/book/legal-issues.html)は事前に書面の許可を得ることを勧め、無許可のスキャンはプロバイダーの利用規約に反する場合があるとしています。

[AWS のポリシー](https://aws.amazon.com/security/penetration-testing/)では、EC2、RDS、CloudFront、Lambda、Lightsail などの許可されたサービスなら、事前の承認なしにポートスキャンを含むセキュリティ評価ができます。ただし DoS（模擬を含む）や、ポート・プロトコル・リクエストを大量に送りつける行為は禁止です。ほかの VPS なら事業者の規約を確かめます。

日本の[不正アクセス禁止法](https://laws.e-gov.go.jp/law/411AC0000000128)第2条第4項は、不正アクセス行為を、他人の ID・パスワードや、アクセス制御をすり抜ける情報・指令を入力して、制限された機能を使える状態にする行為と定めています。定義は狭いのですが、他人のシステムを調べてよいことにはなりません（[ホワイトハッカーと法律の記事](/blog/ethical-hacker-law-japan-unauthorized-access-act-active-cyber-defense-disclosure-guide)）。

### 外のネットワークから nmap で調べる

サーバーの中から調べると、外からは届かないポートまで開いて見えます。自宅の回線など**サーバーの外から**、自分の IP だけを調べます。

```bash
# 自分のサーバーの IP（203.0.113.10 は例）。root が使えるなら SYN スキャンで全ポート
sudo nmap -Pn -sS -p- 203.0.113.10 -oN outside-tcp.txt
# root が使えない端末なら connect スキャン
nmap -Pn -sT -p- 203.0.113.10 -oN outside-tcp.txt
# UDP は root が要る。よく使われる上位 100 ポートだけ
sudo nmap -Pn -sU --top-ports 100 203.0.113.10
# IPv6 アドレスを持つなら別に調べる（2001:db8::10 は例）
sudo nmap -6 -Pn -sS -p- 2001:db8::10
```

本番のサーバーには SYN スキャンを勧めます。nmap の公式ガイドは、壊れやすい機器への影響を減らしたいなら connect スキャンより SYN スキャンを使うよう勧めています。connect スキャンは接続を完了させるので、まれにサービスが落ちることがあるからです。

`-Pn` は生きているかの確認を省き、指定した IP を必ず調べます。nmap は指定しないとよく使われる 1,000 ポートしか調べないので、全ポートを見るなら `-p-` を付けます。`open` のポートは1つずつ公開の必要を確かめ、公開しないポートは `filtered` になっているのが望ましい姿です。

パケットを送らずに確かめるなら Shodan です。インターネットにつながった機器の検索エンジンで、`ip:203.0.113.10` のように指定すると、Shodan が見つけたサービスが分かります。ただし過去に調べた時点の結果なので、今の状態は nmap で確かめます。

### クラウドの設定から一覧する: AWS CLI

```bash
# 0.0.0.0/0 または ::/0 を許可している受信ルール（リージョンごとに実行）
aws ec2 describe-security-group-rules \
  --query 'SecurityGroupRules[?IsEgress==`false` && (CidrIpv4==`"0.0.0.0/0"` || CidrIpv6==`"::/0"`)].[GroupId,IpProtocol,FromPort,ToPort,CidrIpv4,CidrIpv6]' \
  --output table
# Lightsail はインスタンスごとに確かめる（my-instance は例）
aws lightsail get-instance-port-states --instance-name my-instance
```

セキュリティグループのクエリは公式の出力例と同じ形のサンプルデータで確かめたもので、実際のアカウントでは実行していません。`IpProtocol` が `-1` の行は全プロトコルを開けています。Lightsail の結果では、`cidrs`（IPv4）と `ipv6Cidrs`（IPv6）に接続を許す送信元が出ます。継続して見張るなら、Amazon Inspector が EC2 に届くポートを12時間ごとに調べ、[Security Hub CSPM](https://docs.aws.amazon.com/securityhub/latest/userguide/ec2-controls.html) が 22番（EC2.13）・3389番（EC2.14）の全開放や、リスクの高いポートの無制限な開放（EC2.19）を検出します。

## ポートスキャン・脆弱性スキャン・脆弱性診断・ペネトレーションテストの違い

**ポートスキャンは「何が開いているか」に答えるだけで、そこに弱点があるか、アプリの中に欠陥があるかには答えません。** NIST SP 800-115 と、経済産業省「情報セキュリティサービス基準」の定義（IPA の適合サービスリストの[脆弱性診断サービス](https://www.ipa.go.jp/security/ug65p90000019fc0-att/20261009_2.pdf)と[ペネトレーションテストサービス](https://www.ipa.go.jp/security/ug65p90000019fc0-att/20261009_6.pdf)に掲載）に沿って並べます。

| 種類 | 答える問い | 見えないもの・注意点 |
|---|---|---|
| ポートスキャン | どのポートが開き、何のサービスが動いているか | そのサービスに弱点があるか。アプリの中の欠陥 |
| 脆弱性スキャン | 古い版、パッチの漏れ、設定の誤りなど既知の脆弱性があるか | 誤検知が多い。攻撃を組み合わせて初めて現れる弱点 |
| 脆弱性診断 | 脆弱性に関する一定の知見を持つ人が、Web アプリ・プラットフォーム・スマホアプリの脆弱性を調べる | 決めた範囲の外 |
| ペネトレーションテスト | 攻撃者と同じ手法で、セキュリティ機能を回避して目的を達成できるか | 選んだシナリオの外。試験中にシステムを壊すことがある |

- **ポートスキャンは脆弱性スキャンの一部です。** 脆弱性スキャンも、ホストや開いているポートを特定したうえで脆弱性を判定します。
- **ペネトレーションテストは脆弱性診断の上乗せです。** IPA のリストでは、脆弱性診断サービスのオプションという位置づけです。
- **内側からも調べる。** 外からのスキャンは境界の機器に止められ、通過を許されたポートしか見えません。NIST SP 800-115 は、内部からの方が多くの脆弱性が見つかることが多く、両方の視点が大切だとしています。

ここからは筆者の見方です。人が手で行う Web アプリの診断なら、ツールだけでは判定しにくい認可（誰がどのデータを見てよいか）まで確かめられます。ただしツールだけの診断も同じ「脆弱性診断」の名前で売られているので、認可の試験が含まれるかを見積りで確かめてください。Web アプリの診断の中身は [脆弱性診断の手法の記事](/blog/web-application-vulnerability-assessment-owasp-zap-sast-dast-guide)、ネットワークの侵入試験は [ネットワークペンテストの記事](/blog/network-penetration-testing-methodology-attack-defense-guide)で扱っています。

## 専門家に頼むべきタイミングと、監査で確かめること

| 状況 | 頼むこと |
|---|---|
| 自分のインスタンスが「やっている側」の検出が出た、知らない `Accepted` がある | 診断より先にインシデント対応 |
| 何が公開されているか、セキュリティグループを自分で読み切れない | クラウド設定のレビュー |
| 個人情報・決済・複数の顧客企業のデータを扱う | 認可の試験を含む Web アプリの脆弱性診断（認可の欠陥はポートスキャンでは見えない） |
| 本番環境しかない | 本番に触れない手法から始める（[本番しかない場合の記事](/blog/security-audit-production-only-no-staging-guide)） |

このサイトの[セキュリティ監査](/security-audit)は、Web サービスのソースコードと、AWS・GCP・Vercel の設定を読んで確かめるレビューです。認証と認可、入力とデータの扱い、秘密情報、依存パッケージの既知の脆弱性、デプロイとクラウドの設定を見ます。対象と深さは最初の相談で決めて書面に残し、設定は閲覧専用の権限で確認して何も変更しません。「完全に安全」の保証はせず、決めた範囲の既知の重大なリスクを対象にします。経済産業省の基準でいう「情報セキュリティ監査サービス」（管理の整備・運用状況を独立した立場から基準に沿って検証するもの）とは別物です。

筆者は木材流通の B2B SaaS（経済産業大臣賞）で、ペネトレーションテストを含む自主監査を4ラウンド行い、実在する15のロールで全221エンドポイントの認証欠落0件を確かめました。これはアプリケーション層の試験で、ポートスキャンで見えるのは入口までです。

費用の相場と見積りの読み方は [脆弱性診断の費用の記事](/blog/web-application-vulnerability-assessment-cost-pricing-guide)を参照してください。
