2026年5月28日

2026年5月28日

ポートスキャン対策とnmapの使い方:自分のサーバーを外から点検して不要なポートを閉じる

インターネットに公開したサーバーは、ポートスキャンそのものを止めることはできません。対策の中心は「外から見えるポートを必要最小限にし、残したポートは認証と回数制限で守り、変化に気づける状態にする」ことです。この記事では、WordPress を動かす VPS を例に、サーバー内部と外部の両方から開いているポートを確認し、nmap の結果の読み方、ファイアウォールでの閉じ方、閉じたあとの再確認までを順に説明します。

始める前に:スキャンしてよい対象

nmap は自分が管理しているサーバー、または管理者から書面などで許可を得た対象にだけ使います。許可のない他人のサーバーへのスキャンは、相手の監視に攻撃として記録されたり、プロバイダーやクラウド事業者の利用規約に反したりするおそれがあります。

クラウドの VPS を点検する場合も、事業者ごとに侵入テストやスキャンに関する方針があります。多くの事業者は自分のインスタンスへの点検を認めていますが、条件は事業者によって異なり変わることもあるため、利用中のサービスの規約を確認してから実施してください(2026年10月現在)。

ポートスキャン対策の考え方

ポートスキャンは「どのポートで何が待ち受けているか」を調べる行為で、攻撃の下調べとして毎日のように自動で行われています。止められない前提で、次の4点を積み重ねます。

  • 待ち受けを減らす:使っていないサービスを止め、内部だけで使うサービス(MySQL、Redis など)は 127.0.0.1 だけで待ち受ける
  • ファイアウォールで閉じる:既定で受信を拒否し、Web(80/443)と管理用の SSH など必要なものだけ許可する
  • 残したポートを守る:SSH は鍵認証にし、ログイン試行の回数を制限する
  • 気づける状態にする:ファイアウォールのログや fail2ban で異常な試行を把握し、定期的に外からの見え方を点検する

SSH のポート番号を 22 から変えると自動スキャンのログは減りますが、ポートを全範囲で調べられれば見つかります。ログを静かにする効果はあっても、防御の本体ではない点を押さえておきます。

ステップ1:サーバーの内側で待ち受けを確認する

最初に、サーバー上でどのプロセスがどのアドレスとポートで待ち受けているかを確認します。nmap より先にこちらを見るのは、「なぜそのポートが開いているのか」をプロセス名で特定できるからです。

# TCP/UDP の待ち受けをプロセス名つきで表示
sudo ss -tulpn

見るべきは「Local Address」の列です。0.0.0.0:3306 や [::]:3306 のように全アドレスで待ち受けていれば外部からも到達しうる状態、127.0.0.1:3306 ならサーバー内部だけです。WordPress とデータベースが同じサーバーにあるなら、MySQL/MariaDB を外に公開する理由は通常ありません。

MySQL/MariaDB を内部だけにする例です。設定ファイルの場所はディストリビューションとバージョンで異なるため、mysqld --help --verbose | grep -A1 "Default options" などで読み込まれる場所を確認してから編集します。

# 例: /etc/mysql/mysql.conf.d/mysqld.cnf(Ubuntu の MySQL)
# MariaDB では /etc/mysql/mariadb.conf.d/50-server.cnf など
[mysqld]
bind-address = 127.0.0.1

編集前に設定ファイルのバックアップを取り、再起動後に sudo ss -tlnp | grep 3306 で待ち受けが 127.0.0.1 に変わったことを確認します。

ステップ2:外部から nmap でスキャンする

サーバー自身から自分をスキャンすると、ファイアウォールを通らない経路になり、外からの見え方と一致しません。手元の PC や別のサーバーなど、外部のネットワークから実行します。

# Ubuntu / Debian の手元環境にインストール
sudo apt install nmap

# よく使われる上位1000ポートを確認(ICMP に応答しない環境も考慮して -Pn)
nmap -Pn example.com

# 全 TCP ポート(1〜65535)を確認。時間がかかる
nmap -Pn -p- --open example.com

# 開いているポートのサービスとバージョンを推定
nmap -Pn -sV -p 22,80,443 example.com

root 権限で実行すると既定で SYN スキャン(-sS)、一般ユーザーでは接続スキャン(-sT)になります。どちらも点検には十分です。UDP は sudo nmap -Pn -sU --top-ports 50 example.com のように範囲を絞らないと非常に時間がかかります。

結果の読み方

nmap はポートの状態を主に3つで表示します。

  • open:そのポートでサービスが応答している。意図したものか、ステップ1のプロセスと照合する
  • closed:パケットは届いたが待ち受けがない。ファイアウォールでは許可されている可能性がある
  • filtered:応答がない、またはファイアウォールで遮断されている。外部に見せたくないポートの望ましい状態

公開 Web サーバーで期待される結果は、80 と 443、管理用の SSH だけが open で、それ以外が filtered という形です。3306 や 6379、8080 などが open なら、意図しない公開を疑います。-sV でバージョンまで表示される場合、その情報は攻撃者にも見えているため、次のステップでサーバー名の表示を絞ります。

ステップ3:ファイアウォールで不要なポートを閉じる

Ubuntu では ufw を使うと設定を簡潔に書けます。SSH を許可する前に有効化すると自分自身が締め出されるため、順番に注意します。VPS のコンソール機能(ブラウザから使える管理コンソールなど)にログインできることを先に確認しておくと、万一のときに戻せます。

sudo ufw default deny incoming
sudo ufw default allow outgoing

# SSH は回数制限つきで許可(短時間に接続が続くと拒否)
sudo ufw limit 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

sudo ufw enable
sudo ufw status verbose

ufw limit は同じ送信元から短時間に多数の接続があると拒否する機能です。SSH を特定の IP からだけ許可できるなら、sudo ufw allow from 203.0.113.10 to any port 22 proto tcp のように送信元を絞るほうがより強い対策になります。

クラウドの VPS では、OS のファイアウォールとは別に事業者のセキュリティグループやパケットフィルターがあります。両方で同じ方針にしておくと、片方の設定ミスがあってももう片方で防げます。

Docker を使っている場合の落とし穴

Docker でポートを公開(-p 8080:80 や compose の ports:)すると、Docker が iptables のルールを直接追加するため、ufw の拒否設定より先に通ってしまうことがあります。ufw で閉じたつもりのポートが nmap で open になる典型的な原因です。内部だけで使うコンテナは 127.0.0.1:8080:80 のようにループバックに限定して公開し、それ以上の制御が必要なら Docker が用意している DOCKER-USER チェーンにルールを追加します。

ステップ4:残したポートの情報と入口を絞る

開けておくポートについては、余計な情報を出さず、入口を守ります。

# nginx: エラーページやヘッダーにバージョン番号を出さない
server_tokens off;

SSH はパスワード認証を無効にして鍵認証だけにし、root での直接ログインを禁止します。設定を変えたら、今のセッションを閉じずに別の端末から新しい接続ができることを確認してから切断します。

# /etc/ssh/sshd_config(または /etc/ssh/sshd_config.d/ 配下)
PasswordAuthentication no
PermitRootLogin no

sudo sshd -t で構文を確認してから sudo systemctl reload ssh(RHEL 系では sshd)で反映します。

ステップ5:スキャンや試行に気づける状態にする

ファイアウォールのログを有効にすると、拒否した通信が記録され、どのポートが狙われているかの傾向が分かります。

sudo ufw logging low
# Ubuntu では /var/log/ufw.log などに記録される
sudo grep "UFW BLOCK" /var/log/ufw.log | tail -n 20

ポートスキャン自体は多すぎてすべてに対応する意味は薄く、実際に対処すべきなのは SSH や WordPress のログイン画面への繰り返しの試行です。fail2ban を使うと、認証ログに失敗が一定回数出た送信元を一定時間ブロックできます。

最後に、ステップ2と同じ nmap コマンドを外部から再実行し、意図したポートだけが open になっていることを確認します。設定変更やパッケージの追加でポートが開くことがあるため、月1回など定期的に同じコマンドで点検し、結果を -oN scan-2026-10.txt のようにファイルに残して前回と比べると変化に気づけます。

まとめ

  • ポートスキャンは止められない前提で、待ち受けの削減、ファイアウォール、認証の強化、検知を組み合わせます
  • まず ss -tulpn で内側の待ち受けを確認し、内部用サービスは 127.0.0.1 に限定します
  • nmap は外部から、自分が管理する対象にだけ実行し、open/closed/filtered の意味を踏まえて結果を照合します
  • ufw は SSH の許可を先に入れてから有効化し、Docker の公開ポートは ufw を通らない場合がある点に注意します
  • 変更後と定期的に同じスキャンを繰り返し、結果を記録して差分を見ます

お気軽にご相談ください

お見積りへ お問い合わせへ
▲