Linuxサーバーをインターネットに公開すると、開いているポートはそのまま攻撃の入り口になります。使っていないサービスがポートを開けたままになっていないか、そしてそれを正しく閉じられるかは、サーバー運用の基本にして最重要の作業です。
かつては「開いているポートを調べ、そのプロセスを強制終了する」というやり方がよく紹介されていました。しかしプロセスを終了させただけでは、サーバーを再起動すると同じサービスが起動してポートが再び開いてしまいます。この記事では、再起動しても閉じたままになる正しい手順を、背景・手順・検証・切り戻しの順で解説します。
まず前提:ポートを「閉じる」とは何を指すのか
ポートを閉じる方法は、大きく2つに分けて考えると整理しやすくなります。目的によって使い分けます。
| 閉じ方 | やること | 向いている場面 |
|---|---|---|
| サービスを止める | ポートを開けている常駐サービス自体を停止・無効化する(systemctl) |
そのサービスをもう使わない場合(不要サービスの棚卸し) |
| ファイアウォールで遮断する | サービスは動かしたまま、外部からの通信だけを遮断する(firewalld / ufw) | サービスは内部で使うが外部には見せたくない場合 |
ポイントは、プロセスを kill するのは「閉じる」ではないということです。kill は一時的にプロセスを止めるだけで、サービスの自動起動設定はそのまま残ります。再起動すればポートは元通り開きます。恒久的に閉じるには、この2つのどちらか(あるいは両方)を使います。
手順①:不要なサービスを止めてポートを閉じる
そのサービス自体をもう使わないのであれば、サービスを停止して自動起動を無効化するのが一番すっきりした閉じ方です。まず、どのサービスがポートを開けているかを確認します。
# 開いているポートと、それを開けているプロセスを確認する
sudo ss -tulnp
# 出力例(LISTEN しているポートがサーバーで待ち受けているポート)
# Netid State Local Address:Port Process
# tcp LISTEN 0.0.0.0:22 users:(("sshd",pid=812,fd=3))
# tcp LISTEN 0.0.0.0:80 users:(("httpd",pid=1240,fd=4))
# tcp LISTEN 0.0.0.0:25 users:(("master",pid=980,fd=13))
たとえば 25 番(SMTP)の postfix をこのサーバーでは使わない、と決めたとします。その場合は次のように停止・無効化します。
# サービスを停止し、同時に自動起動も無効化する
sudo systemctl disable --now postfix
# 本当に止まったか、ポートが消えたかを確認
sudo ss -tulnp | grep ':25' || echo "25番ポートは閉じました"
disable --now は「今すぐ停止(stop)」と「次回以降も起動しない(disable)」を一度に行うオプションです。これで再起動後もポートは開きません。どのサービスが何のために動いているか分からないまま止めると必要な機能まで落ちるため、名前が分からないサービスは止める前に役割を調べてから判断してください。
手順②:ファイアウォールで外部からの通信を遮断する
サービスは動かしておきたいが外部からは見せたくない、という場合はファイアウォールで遮断します。ディストリビューションによって標準ツールが異なります。
RHEL系(AlmaLinux / Rocky Linux など)— firewalld
# 現在許可されているサービス・ポートを確認
sudo firewall-cmd --list-all
# 例:http(80番)の許可を取り消して閉じる
sudo firewall-cmd --permanent --remove-service=http
sudo firewall-cmd --reload
# ポート番号で閉じたい場合
sudo firewall-cmd --permanent --remove-port=8080/tcp
sudo firewall-cmd --reload
--permanent を付けた変更は設定ファイルに保存され、--reload で反映されます。--permanent を付け忘れると再起動で設定が消えるため、恒久的に閉じたいときは必ず付けてください。
Ubuntu / Debian系 — ufw
# 現在のルールを確認
sudo ufw status verbose
# 例:以前に許可した80番の許可を削除して閉じる
sudo ufw delete allow 80/tcp
# 特定ポートを明示的に拒否する場合
sudo ufw deny 8080/tcp
ufw は許可(allow)ルールを削除すれば、既定の「外部からの着信は拒否」に戻ります。明示的に deny を入れる必要があるのは、いったん広く開けているポートを個別に塞ぎたいときです。
閉じたことを検証する
設定を変えたら、必ず「本当に閉じたか」を確認します。サーバー自身での確認と、外から見た確認の両方を行うのが運用の作法です。
# サーバー自身で、対象ポートが LISTEN していないか確認
sudo ss -tulnp | grep ':80' || echo "80番は待ち受けていません"
# ファイアウォールで遮断した場合、サービスは動いているので
# LISTEN は残る。外部から届くかどうかは別ホストから確認する
# (別のマシンから実行)
nc -vz サーバーのIPアドレス 80
手順①(サービス停止)で閉じた場合は ss の一覧からポートが消えます。手順②(ファイアウォール遮断)で閉じた場合はサービス自体は動いているため ss には LISTEN が残り、外部からの到達だけが遮断されます。この違いを理解しておくと「閉じたはずなのにポートが見える」という混乱を避けられます。
元に戻す・事故を防ぐ
ポートを閉じる作業で最も多い事故は、自分がログインしている SSH(22番)を締め出してしまうことです。リモート作業中に SSH を遮断すると、その瞬間に操作できなくなり、コンソールに物理アクセスできなければ復旧手段を失います。次の点を必ず守ってください。
- 22番(SSH)は、意図して閉じる場合を除き触らない
- firewalld を大きく変更するときは
--timeoutを使い、一定時間で自動的に元へ戻るようにしておくと締め出しを防げる(例:sudo firewall-cmd --add-port=22/tcp --timeout=300) - 変更前に現状を控えておく(
sudo firewall-cmd --list-allやsudo ufw statusの出力を保存)
切り戻しは、閉じたときと逆の操作です。サービスを止めたなら sudo systemctl enable --now サービス名、ファイアウォールで塞いだなら --add-service / --add-port(firewalld)や ufw allow(ufw)で許可を戻します。
2026年の現行環境での違い
ひと昔前の解説では、開いているポートを見つけてプロセスを kill する方法や、chkconfig でサービスを止める方法が主流でした。現在の主要ディストリビューションでは事情が変わっています。
- サービス管理は systemd に統一:
chkconfigやserviceコマンドではなくsystemctlを使います。停止と自動起動無効化はdisable --nowが定石です。 - ファイアウォールの実体は nftables:RHEL系の firewalld も Ubuntu の ufw も、内部では新しい
nftablesを操作する上位ツールになっています。直接iptablesを叩く記事は現在では過渡的な情報です。firewalld / ufw 経由での管理が推奨されます。 - ポート確認は ss が標準:
netstatは非推奨扱いとなり、多くの環境で標準インストールされなくなりました。確認にはssを使います。
つまり、いまのサーバーで不要なポートを閉じるなら「systemctl でサービスを止める」か「firewalld / ufw で遮断する」の2択で、いずれも ss で検証する、という型を覚えておけば十分です。
まとめ
不要なポートを閉じる作業は、プロセスを一時的に止めることではなく、恒久的に開かない状態にすることが目的です。使わないサービスは systemctl disable --now で止め、動かしたまま外から隠したいものは firewalld / ufw で遮断し、ss で検証する。この一連の流れを型として持っておけば、公開サーバーの攻撃面を確実に減らせます。作業の前後で SSH を締め出さないことだけは、常に最優先で確認してください。
開いているポートの棚卸し(点検)そのものについては、別記事「Linuxで開いているポートを棚卸しする運用点検の手順」で詳しく解説しています。閉じる前の現状把握に役立ててください。

コメント