CentOS ポート確認方法を徹底解説:システム管理者必携の知識とコマンド集
サーバー運用やネットワーク管理において、ポートの状態を確認することは非常に重要です。サービスが正常に起動しているか、外部からアクセスできるか、セキュリティ上の問題はないかなど、様々な状況判断の基礎となります。CentOS(およびRHEL、AlmaLinux、Rocky Linuxなどの派生ディストリビューション)環境で、これらのポートに関連する情報をどのように確認すれば良いのか、本記事で徹底的に解説します。
システム管理者や開発者はもちろん、これからCentOSサーバーを触る方にとっても、この知識は必須です。基本的なコマンドから応用的な使い方、さらにはリモートホストのポート確認方法、そして見落としがちなファイアウォールやSELinuxとの関連性まで、網羅的に説明します。
目次
- はじめに:なぜポート確認が必要なのか?
- ポートの基礎知識:TCP/UDP、ポート番号、ソケット
- TCPとUDP
- ポート番号の範囲と種類
- ソケットとコネクションの状態
- ローカルホストで開いているポートを確認する
netstat
コマンド:古き良き定番ツールnetstat
の基本的な使い方- 主要オプションの詳細解説
netstat
の出力形式と読み方netstat
を使った応用的な確認方法
ss
コマンド:netstat
の後継としてss
の基本的な使い方ss
の主要オプションss
の出力形式と読み方ss
を使った応用的な確認方法netstat
とss
の比較
lsof
コマンド:プロセスとポートを関連付けるlsof
のインストールlsof
の基本的な使い方lsof
を使った特定のポートやプロセスの確認
/etc/services
ファイル:サービス名とポート番号のマッピング/proc/net/
以下のファイル:システムの生情報
- 特定のポートを使用しているプロセスを確認する
- 特定のプロセスが使用しているポートを確認する
- リモートホストのポートを確認する
telnet
コマンド:シンプルながら役立つテストツールnc
(netcat) コマンド:多機能なネットワークツールnmap
コマンド:本格的なポートスキャナーnmap
のインストールnmap
の基本的なスキャンnmap
の主要オプション
curl
またはwget
:HTTP/Sポートの確認
- ファイアウォールとSELinuxの確認:ポートが開いていてもアクセスできない原因
firewalld
によるポートの確認iptables
によるポートの確認- SELinux によるポートの確認
- ポート確認に関するトラブルシューティング
- 「ポートが開いているはずなのに接続できない」
- 「特定のサービスが起動しているのにポートが LISTEN していない」
- 「コマンドが見つからない」
- 「Permission denied(権限がない)」
- まとめ:状況に応じたツール選択とセキュリティ意識
1. はじめに:なぜポート確認が必要なのか?
サーバー上で稼働する様々なサービス(Webサーバー、データベース、SSHなど)は、ネットワークを介して通信するために特定の「ポート」を使用します。ポートは、IPアドレスと組み合わせて通信のエンドポイントを識別する役割を果たします。
ポートの状態を確認する必要がある主なシナリオは以下の通りです。
- サービス起動の確認: Webサーバー(Apache, Nginx)がポート80や443でリクエストを待っているか、データベース(MySQL, PostgreSQL)がポート3306や5432で接続を受け付けているかなどを確認します。サービスを起動したのに外部からアクセスできない場合、まずポートが正しく開いているかを確認します。
- ネットワークトラブルシューティング: クライアントからサーバーに接続できない場合に、サーバー側のポートが LISTEN しているか、あるいはクライアントからそのポートへの通信がファイアウォールなどでブロックされていないかなどを切り分けるためにポート状態を確認します。
- リソース監視とトラブル特定: 特定のプロセスが予期しないポートを使用していないか、大量のコネクションを張っていないかなどを確認し、システムリソースの枯渇や異常な動作を検知します。
- セキュリティ監査と脆弱性対策: 意図しないポートが開いていないかを確認し、不要なサービスを停止したり、ファイアウォールでアクセスを制限したりします。開いているポートは攻撃対象となる可能性があるため、最小限にすることがセキュリティの基本です。
このように、ポートの確認はサーバーの状態把握、問題解決、そしてセキュリティ維持のために不可欠な作業です。
2. ポートの基礎知識:TCP/UDP、ポート番号、ソケット
ポート確認を行う前に、ポートに関する基本的な概念を理解しておきましょう。
TCPとUDP
ネットワーク通信で最も一般的に使用されるプロトコルにTCP (Transmission Control Protocol) とUDP (User Datagram Protocol) があります。
- TCP: 信頼性の高い通信プロトコルです。データを送信する前にコネクションを確立し、データが正しく届いたか確認応答を行い、順序保証や再送制御を行います。Web (HTTP/HTTPS)、SSH、FTP、SMTPなどの多くのアプリケーション層プロトコルで使用されます。
- UDP: コネクションレスの通信プロトコルです。データの送達や順序は保証されませんが、高速な通信が可能です。DNS、DHCP、NTP、VoIPなどで使用されます。
ポートはTCPとUDPそれぞれで独立しており、「TCPポート80」と「UDPポート80」は技術的には別物です。ポート確認時には、通常TCPとUDPのどちらのポートを確認しているのかを意識する必要があります。
ポート番号の範囲と種類
ポート番号は0から65535までの整数値です。これらのポート番号は以下の3つの範囲に分類されます。
- ウェルノウンポート (Well-Known Ports): 0から1023まで。一般的なサービスに割り当てられています。例: 22 (SSH), 25 (SMTP), 53 (DNS), 80 (HTTP), 443 (HTTPS)。これらのポートを使用するサービスは、通常root権限で起動する必要があります。
- レジスタードポート (Registered Ports): 1024から49151まで。特定のアプリケーションのために登録されたポートです。例: 3306 (MySQL), 5432 (PostgreSQL), 8080 (Webプロキシなど)。
- ダイナミック/プライベートポート (Dynamic/Private Ports): 49152から65535まで。クライアントが一時的に使用したり、サーバーが特定の用途で自由に使用したりします。
システムが通信を行う際、サーバー側は特定のウェルノウンポートやレジスタードポートで待ち受けますが、クライアント側は通常、ダイナミックポートから空いているポートを自動的に割り当てて通信を開始します。
ソケットとコネクションの状態
ポートは、IPアドレスと組み合わされて「ソケット」を形成します。ソケットはネットワーク通信のエンドポイントです。
ポートの状態は様々な段階に変化します。主な状態は以下の通りです(特にTCPの場合)。
- LISTEN: サーバー側がクライアントからの接続要求を待っている状態です。サービスが正常に起動し、外部からの接続を受け付け可能な状態であることを示します。
- ESTABLISHED: TCPコネクションが正常に確立され、データ送受信可能な状態です。
- SYN_SENT: クライアントがサーバーへの接続要求 (SYNパケット) を送信し、サーバーからの応答を待っている状態です。
- SYN_RECV: サーバーがクライアントから接続要求 (SYNパケット) を受信し、応答 (SYN+ACKパケット) を送信し、クライアントからの確認応答を待っている状態です(スリーウェイハンドシェイクの中間状態)。
- FIN_WAIT1, FIN_WAIT2, TIME_WAIT, CLOSE_WAIT, LAST_ACK, CLOSING: コネクション切断プロセスにおける様々な中間状態です。
- CLOSED: コネクションが存在しない状態です。
ポート確認コマンドの出力では、これらの状態が表示され、現在の通信状況を把握することができます。通常、サービスが待ち受け状態にあることを確認するには LISTEN 状態を見ます。
3. ローカルホストで開いているポートを確認する
まずは、CentOSサーバー自身でどのようなポートが開いていて、どのプロセスがそれを使用しているかを確認する方法を見ていきましょう。
netstat
コマンド:古き良き定番ツール
netstat
(network statistics) コマンドは、Linuxシステムでネットワーク接続、ルーティングテーブル、インターフェース統計、マスカレード接続などを表示するための伝統的なツールです。現在ではより高機能な ss
コマンドに置き換えられつつありますが、依然として広く使用されています。
netstat
の基本的な使い方
開いているポート(待ち受け状態のソケット)を確認するために最もよく使われるのは以下のオプションの組み合わせです。
bash
netstat -tuln
-t
: TCPソケットを表示します。-u
: UDPソケットを表示します。-l
: LISTEN状態のソケットのみを表示します。-n
: ポート番号やIPアドレスをサービス名やホスト名に変換せず、数値のまま表示します。これにより、DNSルックアップなどが不要になり、表示が速くなります。また、特定のポート番号を直接確認する際に便利です。
実行例:
bash
$ netstat -tuln
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp6 0 0 :::22 :::* LISTEN
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN
tcp6 0 0 ::1:25 :::* LISTEN
udp 0 0 0.0.0.0:68 0.0.0.0:*
udp 0 0 192.168.1.10:123 0.0.0.0:*
udp 0 0 127.0.0.1:123 0.0.0.0:*
udp 0 0 0.0.0.0:123 0.0.0.0:*
udp6 0 0 :::123 :::*
この例では、TCPポート22 (SSH) がIPv4 (0.0.0.0:22
) とIPv6 (:::22
) の両方で LISTEN 状態にあること、TCPポート25 (SMTP) がループバックアドレス (127.0.0.1:25
, ::1:25
) で LISTEN 状態にあること、そしてUDPポート123 (NTP) などが待ち受けていることが分かります。
主要オプションの詳細解説
-a
(–all): LISTEN状態だけでなく、すべての状態のソケットを表示します (ESTABLISHED, TIME_WAITなど)。-p
(–programs): ソケットを使用しているプロセスのPID (Process ID) とプログラム名を表示します。このオプションを使うには通常root権限が必要です (sudo netstat -tulnp
)。-r
(–route): ルーティングテーブルを表示します。-i
(–interfaces): ネットワークインターフェースの統計情報を表示します。-e
(–extend): 詳細な情報を表示します (ユーザーID、inodeなど)。-s
(–statistics): 各プロトコルの統計情報を表示します。
netstat
の出力形式と読み方
netstat -tuln
などの出力は通常以下のカラムで構成されます。
Proto
: プロトコル (tcp, udp, tcp6, udp6)。Recv-Q
: 受信キューのバイト数。アプリケーションがまだ処理していないデータ量。Send-Q
: 送信キューのバイト数。リモートホストに送信されたが、まだ確認応答されていないデータ量。LISTEN状態のソケットでは通常0です。Local Address
: ローカルホストのIPアドレスとポート番号。0.0.0.0
または:::
は、すべてのインターフェースのIPアドレスを意味します。例えば0.0.0.0:22
は、そのサーバーのどのIPアドレス宛てのポート22への接続も受け付けることを意味します。127.0.0.1
または::1
はループバックアドレスです。そのサーバー自身からの接続のみを受け付けます。- 特定のIPアドレスが表示されている場合、そのIPアドレス宛ての接続のみを受け付けます。
Foreign Address
: リモートホストのIPアドレスとポート番号。LISTEN状態のソケットでは0.0.0.0:*
または:::*
と表示され、どのリモートホストからの接続でも受け付けることを意味します。ESTABLISHED状態の場合は、接続している相手のIPアドレスとポートが表示されます。State
: ソケットの状態 (LISTEN, ESTABLISHEDなど)。UDPはコネクションレスのため、状態は表示されません。
netstat -tulnp
を実行すると、最後に PID/Program name
のカラムが追加されます。
bash
$ sudo netstat -tulnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 896/sshd
tcp6 0 0 :::22 :::* LISTEN 896/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1103/master
tcp6 0 0 ::1:25 :::* LISTEN 1103/master
udp 0 0 0.0.0.0:68 0.0.0.0:* 863/dhclient
udp 0 0 192.168.1.10:123 0.0.0.0:* 961/ntpd
udp 0 0 127.0.0.1:123 0.0.0.0:* 961/ntpd
udp 0 0 0.0.0.0:123 0.0.0.0:* 961/ntpd
udp6 0 0 :::123 :::* 961/ntpd
この出力から、TCPポート22はPID 896のsshd
プロセスが、TCPポート25はPID 1103のmaster
プロセス(Postfixなど)が使用していることが分かります。
netstat
を使った応用的な確認方法
-
特定のポートが LISTEN しているか確認:
bash
sudo netstat -tulnp | grep :80
またはポート番号が分かっているなら-n
は必須です。
bash
sudo netstat -tulnp | grep ':80 ' # ポート番号の後にスペースを入れると正確
ポート番号の後にスペースを入れるのは、例えばポート800や8080などが含まれてしまうのを避けるためです。grep
のパターンを:80$
(行末が:80) としても良いですが、IPv6やPID/Program name カラムがあるとマッチしない可能性があります。:80[ \t]
のようにスペースまたはタブに続くパターンが良いでしょう。 -
特定のプロトコルのソケットのみ表示:
bash
netstat -tlun | grep tcp # TCPのみ
netstat -tlun | grep udp # UDPのみ -
確立された接続を表示:
bash
netstat -ant # -a (all) -n (numeric) -t (tcp) -
特定のIPアドレスへの接続を表示:
bash
netstat -an | grep 'ESTABLISHED.*192.168.1.100'
netstat
は多機能ですが、出力形式が固定されており、フィルタリングや詳細情報の取得には他のコマンドやgrep
との組み合わせが必要です。
ss
コマンド:netstat
の後継として
ss
(socket statistics) コマンドは、netstat
に代わる新しいツールとして開発されました。大規模なシステムや多くのコネクションがある環境で、netstat
よりも高速かつ効率的にソケット情報を取得できます。これは、ss
が /proc/net/
以下のファイルを直接読むのではなく、カーネル空間でより効率的に情報を取得する仕組みになっているためです。
ss
の基本的な使い方
netstat
と同様に、待ち受けポートの確認には以下の組み合わせがよく使われます。オプションは似ていますが、一部異なります。
bash
ss -tuln
-t
: TCPソケットを表示します。-u
: UDPソケットを表示します。-l
: LISTEN状態のソケットのみを表示します。-n
: ポート番号やIPアドレスを数値で表示します。
実行例:
bash
$ ss -tuln
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
tcp LISTEN 0 128 127.0.0.1:25 0.0.0.0:*
tcp LISTEN 0 128 [::]:22 [::]:*
tcp LISTEN 0 128 [::1]:25 [::]:*
udp UNCONN 0 0 0.0.0.0:68 0.0.0.0:*
udp UNCONN 0 0 192.168.1.10:123 0.0.0.0:*
udp UNCONN 0 0 127.0.0.1:123 0.0.0.0:*
udp UNCONN 0 0 0.0.0.0:123 0.0.0.0:*
udp UNCONN 0 0 [::]:123 [::]:*
出力のフォーマットはnetstat
と少し異なりますが、基本的な情報は同じです。UDPソケットの状態はUNCONN
(unconnected) と表示されます。
ss
の主要オプション
ss
にも多くのオプションがあり、netstat
と似たものが多いです。
-a
(–all): すべてのソケットを表示します。-p
(–processes): ソケットを使用しているプロセスの情報 (PIDとプログラム名) を表示します。通常root権限が必要です (sudo ss -tulnp
)。-s
(–summary): ソケットの概要統計を表示します。-o
(–options): タイマー情報などを表示します。-i
(–info): 内部的なTCP情報などを表示します (RTT, キューサイズなど)。トラブルシューティングに非常に役立ちます。-r
(–resolve): ポート番号やIPアドレスをサービス名やホスト名に変換します (-n
の逆)。-e
(–extended): 詳細なソケット情報を表示します (ユーザーIDなど)。
sudo ss -tulnp
の実行例:
bash
$ sudo ss -tulnp
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=896,fd=3))
tcp LISTEN 0 128 127.0.0.1:25 0.0.0.0:* users:(("master",pid=1103,fd=13))
tcp LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=896,fd=4))
tcp LISTEN 0 128 [::1]:25 [::]:* users:(("master",pid=1103,fd=14))
udp UNCONN 0 0 0.0.0.0:68 0.0.0.0:* users:(("dhclient",pid=863,fd=6))
udp UNCONN 0 0 192.168.1.10:123 0.0.0.0:* users:(("ntpd",pid=961,fd=24))
udp UNCONN 0 0 127.0.0.1:123 0.0.0.0:* users:(("ntpd",pid=961,fd=23))
udp UNCONN 0 0 0.0.0.0:123 0.0.0.0:* users:(("ntpd",pid=961,fd=22))
udp UNCONN 0 0 [::]:123 [::]:* users:(("ntpd",pid=961,fd=25))
netstat -p
と異なり、ss -p
はプロセスの情報 (users:(("program_name",pid=PID,fd=FD))
) を別カラムではなく最後のカラムにまとめて表示します。
ss
の出力形式と読み方
ss
の基本的な出力カラムは以下の通りです。
Netid
: プロトコルファミリー (tcp, udp, raw, unixなど)。State
: ソケットの状態 (LISTEN, ESTABLISHED, UNCONNなど)。Recv-Q
: 受信キューのバイト数 (またはパケット数)。Send-Q
: 送信キューのバイト数 (またはパケット数)。Local Address:Port
: ローカルのIPアドレスとポート番号。Peer Address:Port
: リモートのIPアドレスとポート番号。- その他のオプション (
-p
,-i
,-o
) で追加される情報。
ss
を使った応用的な確認方法
ss
の大きな利点は、強力なフィルタリング機能を持つことです。特定の条件に合うソケットだけを効率的に表示できます。フィルタリングは出力の一番最後に指定します。
-
特定のポートが LISTEN しているか確認:
bash
sudo ss -tulnp | grep ':80 ' # netstat と同様に grep でも可能
またはss
のフィルタリング機能を使う。
bash
sudo ss -tln '( sport = :80 or dport = :80 )' # TCPでローカルorリモートポートが80
sudo ss -tln state LISTEN '( sport = :80 or dport = :80 )' # TCP LISTEN状態のポート80
フィルタリングの条件は括弧()
で囲み、sport
(source port),dport
(destination port),state
(状態) などを使います。ポート番号の前に:
をつけます。 -
特定のIPアドレスへの接続を表示:
bash
ss -an state established '( dport = :22 and dst 192.168.1.100 )' # 宛先が192.168.1.100のTCP 22番への確立済み接続
src
(source IP),dst
(destination IP) でIPアドレスを指定できます。 -
大量のTIME_WAIT状態のソケットを表示:
bash
ss -s # 統計情報のサマリー。TIME-WAITなどが表示される
ss -ant | grep TIME-WAIT | wc -l # netstatとgrepで数を数える
ss -ant state time-wait | wc -l # ssのフィルタリングで数を数える
大量のTIME_WAITソケットは、サーバーが高負荷であることや設定の問題を示す場合があります。 -
ソケットの詳細な内部情報を表示:
bash
ss -antpui # TCP (-t), 全て (-a), 数値 (-n), プロセス (-p), UDP (-u), 内部情報 (-i)
-i
オプションは、TCPの再送カウンタ (retrans
), RTT (rtt
), キューサイズ (wscale
), 輻輳制御アルゴリズム (cubic
) など、高度なデバッグに役立つ情報を提供します。
netstat
と ss
の比較
機能/特徴 | netstat |
ss |
---|---|---|
速度・効率 | 低速 (特に多数のソケット時) | 高速 |
情報ソース | /proc/net/* を読み込む |
カーネル内部構造から直接 |
フィルタリング | なし (grepなどと併用) | 強力なフィルタリング機能あり |
表示できる情報 | 基本的 | 詳細な内部情報 (-i, -o) |
プロセス情報 (-p ) |
PID/Program name | PID, Program name, FD |
互換性 | 広く使用されている | 比較的新しい |
新しいシステムでは ss
が推奨されます。特に大量のコネクションを扱うサーバーでは、ss
の速度とフィルタリング能力が非常に有用です。しかし、netstat
もまだ多くの環境で利用可能であり、基本的な確認には十分です。
lsof
コマンド:プロセスとポートを関連付ける
lsof
(list open files) コマンドは、システム上で開かれているファイルやネットワークソケットを、それを使用しているプロセスと共に一覧表示する非常に強力なツールです。「ファイル」には通常のファイルだけでなく、ディレクトリ、ブロックデバイス、共有ライブラリ、パイプ、ネットワークソケットなども含まれます。
lsof
のインストール
CentOSにデフォルトでインストールされていない場合は、以下のコマンドでインストールできます。
“`bash
sudo yum install lsof
または CentOS Stream 8 / RHEL 8 / Rocky Linux 8 / AlmaLinux 8 以降の場合
sudo dnf install lsof
“`
lsof
の基本的な使い方
ネットワークソケットに関連する情報を表示するには、-i
オプションを使用します。
bash
sudo lsof -i
これは、開いているすべてのIPv4およびIPv6のインターネットファイル(ソケット)を表示します。root権限が必要です。
実行例:
bash
$ sudo lsof -i
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd 1 root 46u IPv6 32387 0t0 TCP *:ssh (LISTEN)
systemd 1 root 47u IPv4 32388 0t0 TCP *:ssh (LISTEN)
master 1103 root 13u IPv4 38052 0t0 TCP localhost:smtp (LISTEN)
master 1103 root 14u IPv6 38053 0t0 TCP localhost:smtp (LISTEN)
sshd 896 root 3u IPv4 33345 0t0 TCP host.example.com:ssh->192.168.1.100:51234 (ESTABLISHED)
sshd 896 root 4u IPv6 33346 0t0 TCP *:ssh (LISTEN) # LISTENしている親プロセスも表示される
dhclient 863 root 6u IPv4 32451 0t0 UDP *:bootpc
ntpd 961 ntp 22u IPv4 34021 0t0 UDP *:ntp
ntpd 961 ntp 23u IPv4 34023 0t0 UDP localhost:ntp
ntpd 961 ntp 24u IPv4 34025 0t0 UDP 192.168.1.10:ntp
ntpd 961 ntp 25u IPv6 34026 0t0 UDP *:ntp
lsof -i
の出力は、netstat
/ss
とは異なり、プロセス単位でソケットを表示するのが特徴です。
lsof
を使った特定のポートやプロセスの確認
lsof
は特定の条件でフィルタリングするオプションが豊富です。
-
特定のポートを使用しているプロセスを表示:
ポート番号を指定するには-i :ポート番号
を使います。プロトコルを限定する場合はtcp:
またはudp:
を前につけます。
bash
sudo lsof -i :80 # TCP/UDPに関わらずポート80
sudo lsof -i tcp:80 # TCPポート80
sudo lsof -i udp:53 # UDPポート53
例: TCPポート22 (ssh) を使用しているプロセスを表示
bash
$ sudo lsof -i tcp:22
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd 1 root 47u IPv4 32388 0t0 TCP *:ssh (LISTEN) # 親プロセス
sshd 896 root 3u IPv4 33345 0t0 TCP host.example.com:ssh->192.168.1.100:51234 (ESTABLISHED) # 子プロセス (既存接続)
sshd 896 root 4u IPv6 33346 0t0 TCP *:ssh (LISTEN) # 親プロセス
この例では、sshd
が LISTEN しているソケットと、確立済みのソケットの両方が表示されています。 -
特定のプロトコル、IPアドレス、ポートの組み合わせを指定:
[プロトコル]@[ホスト][:ポート]
の形式で指定できます。
bash
sudo lsof -i [email protected]:80 # 192.168.1.10のTCPポート80
sudo lsof -i udp@*:53 # すべてのIPのUDPポート53
sudo lsof -i @localhost:smtp # localhostのSMTPポート -
特定のプロセス (コマンド名) が使用しているポートを表示:
-c コマンド名
オプションを使います。
bash
sudo lsof -c sshd # sshd というコマンド名のプロセスが使用しているすべてのファイル/ソケット
ネットワークソケットに絞る場合は-c コマンド名 -i
と組み合わせます。
bash
$ sudo lsof -c sshd -i
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 896 root 3u IPv4 33345 0t0 TCP host.example.com:ssh->192.168.1.100:51234 (ESTABLISHED)
sshd 896 root 4u IPv6 33346 0t0 TCP *:ssh (LISTEN) -
特定のPIDが使用しているポートを表示:
-p PID
オプションを使います。
bash
sudo lsof -p 896 -i
lsof
の出力形式:
COMMAND
: プロセスを実行しているコマンド名。PID
: プロセスのPID。USER
: プロセスの所有ユーザー。FD
: ファイルディスクリプタ。u
は read/write モード、n
は network node を示します。数字はファイルディスクリプタ番号です。TYPE
: ファイルのタイプ。IPv4
,IPv6
,REG
(通常ファイル),DIR
(ディレクトリ) など。DEVICE
: デバイス番号。SIZE/OFF
: ファイルサイズまたはオフセット。ネットワークソケットの場合は通常0です。NODE
: ファイルシステムの inode 番号など。ネットワークソケットの場合はカーネルのソケット構造体のinodeライクな番号です。NAME
: ファイル名やネットワークソケットの情報。ネットワークソケットの場合はローカルアドレス:ポート -> リモートアドレス:ポート
の形式で表示され、状態も表示されます。
lsof
は、特定のポートをどのプロセスが使っているのか、あるいは特定のプロセスがどのポートを使っているのかをピンポイントで知りたい場合に非常に便利なツールです。
/etc/services
ファイル:サービス名とポート番号のマッピング
/etc/services
ファイルは、一般的なサービス名とそれに対応するポート番号、そして使用するプロトコル (TCP/UDP) のマッピングが記述されているテキストファイルです。netstat
や ss
コマンドで -n
オプションを付けない場合、このファイルを参照してポート番号をサービス名に変換して表示します。
このファイルを直接参照することで、特定のサービスがデフォルトでどのポートを使用するのか、あるいは特定のポートが一般的にどのサービスに使用されるのかを調べることができます。
bash
cat /etc/services | grep ssh
実行例:
bash
$ cat /etc/services | grep ssh
ssh 22/tcp # SSH Remote Login Protocol
ssh 22/udp
sshell 614/tcp # SSH Server Shell
sshell 614/udp
netconf-ssh 830/tcp # NETCONF over SSH
この例から、SSHがTCPポート22を使用することが分かります。また、TCPとUDPの両方のエントリがありますが、SSHプロトコル自体は通常TCPを使用します。
特定のポート番号に対応するサービス名を調べたい場合は、ポート番号で検索します。
bash
cat /etc/services | grep 80/tcp
実行例:
bash
$ cat /etc/services | grep 80/tcp
http 80/tcp # WorldWideWeb HTTP
これで、TCPポート80がHTTPに使用されることが分かります。
/etc/services
ファイルは単なるマッピング情報であり、実際にそのポートでサービスが起動しているかどうかを示すものではありません。サービスの起動確認には、前述の netstat
, ss
, lsof
コマンドを使用する必要があります。
/proc/net/
以下のファイル:システムの生情報
netstat
や ss
といったコマンドは、実際には /proc
ファイルシステムの下にある特定のファイルを読み込んで、その情報を整形して表示しています。ネットワークソケットに関する生の情報は /proc/net/
ディレクトリ以下に格納されています。
/proc/net/tcp
: 現在アクティブなTCPソケットの情報。/proc/net/udp
: 現在アクティブなUDPソケットの情報。/proc/net/tcp6
: 現在アクティブなIPv6 TCPソケットの情報。/proc/net/udp6
: 現在アクティブなIPv6 UDPソケットの情報。
これらのファイルの内容は、そのまま読んでも人間には分かりにくいフォーマットになっています。例えば、/proc/net/tcp
の内容は以下のようになります。
bash
$ cat /proc/net/tcp
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
0: 0100007F:0019 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 38052 1 ffff914685885000 100 0 0 100 0 0 0
1: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 32388 1 ffff914685884000 100 0 0 100 0 0 0
2: 6401A8C0:C742 0016A8C0:0016 01 00000000:00000000 02:00000041 00000000 0 0 33345 1 ffff914685883000 23 4 28 10 -1
...
各カラムの意味はドキュメントで定義されていますが、IPアドレスやポート番号は16進数で、状態 (st
) も数値コードで表されています (例: 0AはLISTEN, 01はESTABLISHED)。/proc/net/tcp
ファイルの詳細は /usr/src/linux/Documentation/networking/proc_net_tcp.txt
(または該当するバージョンのカーネルソースドキュメント) に記載されています。
通常、これらのファイルを直接解析するよりも、netstat
や ss
といったコマンドを使用する方がはるかに容易です。しかし、これらのコマンドがどのように情報を取得しているのかを理解する上で、/proc/net/
以下のファイルが存在することを知っておくのは有益です。
4. 特定のポートを使用しているプロセスを確認する
「このポート(例: 80番)がなぜ開いているんだ?」「このポートを使っているのはどのプロセスだ?」といった疑問に答えるには、ポート番号からプロセスを特定する必要があります。
これには netstat -p
、ss -p
、または lsof -i :ポート番号
が有効です。通常は sudo
を付けて実行します。
netstat -tulnp
と grep
を使用:
bash
sudo netstat -tulnp | grep ':80[ \t]'
出力例:
bash
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1234/httpd
tcp6 0 0 :::80 :::* LISTEN 1234/httpd
これにより、TCPポート80はPID 1234のhttpd
プロセスが使用していることが分かります。
ss -tulnp
と grep
を使用:
bash
sudo ss -tulnp | grep ':80[ \t]'
出力例:
bash
tcp LISTEN 0 128 0.0.0.0:80 0.0.0.0:* users:(("httpd",pid=1234,fd=5))
tcp LISTEN 0 128 [::]:80 [::]:* users:(("httpd",pid=1234,fd=6))
こちらも同様に、PID 1234のhttpd
プロセスが使用していることが分かります。ss
の出力はより詳細で、ファイルディスクリプタ(fd)も表示されます。
lsof -i :ポート番号
を使用:
bash
sudo lsof -i :80
出力例:
bash
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 1234 root 5u IPv4 45678 0t0 TCP *:http (LISTEN)
httpd 1234 root 6u IPv6 45679 0t0 TCP *:http (LISTEN)
lsof
はプロセス単位の表示なので、どのコマンド (COMMAND) のどのPID (PID) がそのポートを使用しているかが一目で分かります。
どのコマンドも目的は同じですが、出力形式や詳細度が異なります。一般的には lsof
が最も直接的で分かりやすいかもしれません。
5. 特定のプロセスが使用しているポートを確認する
逆に、「このプロセス(例: mysqld)はどのポートを使っているんだ?」という疑問に答える場合は、プロセス名やPIDからポートを特定します。
これも netstat -p
、ss -p
、または lsof
が有効です。
ps aux
と grep
でPIDを特定し、lsof -p PID -i
を使用:
まず、ps aux
や pgrep
などで対象プロセスのPIDを特定します。
bash
ps aux | grep mysqld
出力例:
bash
mysql 2000 0.5 3.0 1234567 87654 ? Sl Oct26 10:00 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin --log-error=/var/log/mysqld.log --pid-file=/var/run/mysqld/mysqld.pid
この例では、mysqld
のPIDは2000です。次に lsof -p
と -i
を組み合わせてポートを確認します。
bash
sudo lsof -p 2000 -i
出力例:
bash
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mysqld 2000 mysql 30u IPv4 98765 0t0 TCP *:mysql (LISTEN)
これで、PID 2000のmysqld
プロセスがTCPポート3306 (mysql
) でLISTENしていることが分かります。
lsof -c コマンド名 -i
を使用:
PIDを調べる手間を省くなら、コマンド名で直接 lsof -c
を使います。
bash
sudo lsof -c mysqld -i
このコマンドは、mysqld
というコマンド名のプロセスが使用しているすべてのネットワークソケットを表示します。
netstat -tulnp
や ss -tulnp
と grep
を使用:
netstat
や ss
の -p
オプションでプロセス名やPIDを含む情報を表示させ、それを grep
で絞り込むことも可能です。
bash
sudo netstat -tulnp | grep mysqld
出力例:
bash
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 2000/mysqld
bash
sudo ss -tulnp | grep mysqld
出力例:
bash
tcp LISTEN 0 128 0.0.0.0:3306 0.0.0.0:* users:(("mysqld",pid=2000,fd=30))
これらのコマンドも、プロセス名とポート番号の関連付けを確認するのに有効です。特に ss
はPIDとコマンド名がセットで表示されるため便利です。
6. リモートホストのポートを確認する
これまではローカルホスト上で開いているポートを確認する方法を見てきました。次に、他のサーバーやクライアントから、特定のサーバーの特定のポートに接続できるか、つまりそのポートが外部に開いているかを確認する方法を解説します。
telnet
コマンド:シンプルながら役立つテストツール
telnet
コマンドは、本来はリモートログインのためのプロトコルですが、特定のホストの特定のポートに対してTCP接続を試みるツールとしても広く利用されます。
CentOS 8/RHEL 8以降ではデフォルトでインストールされていないことが多いです。必要であればインストールします。
“`bash
sudo yum install telnet
または
sudo dnf install telnet
“`
使い方は簡単です。
bash
telnet [ホスト名またはIPアドレス] [ポート番号]
実行例:
サーバー server.example.com
のTCPポート80に接続を試みる場合。
bash
$ telnet server.example.com 80
Trying 192.168.1.100...
Connected to server.example.com.
Escape character is '^]'.
このように Connected to ...
と表示されれば、クライアントからサーバーの指定ポートまでTCP接続が成功したことを意味します。サーバー側でポートが LISTEN しており、かつ途中のファイアウォール(サーバーOSのファイアウォール含む)でブロックされていない状態です。接続後、HTTPの場合なら簡単なHTTPリクエスト (GET / HTTP/1.1
の後に空行を2つ続けて入力) を送ってみると、サーバーからの応答が見られることもあります。終了するには Ctrl + ]
を押してから quit
と入力します。
もし接続できない場合は、以下のようになります。
bash
$ telnet server.example.com 8080
Trying 192.168.1.100...
telnet: connect to address 192.168.1.100: Connection refused
Connection refused
と表示される場合、通常はサーバー側のOSがそのポートに対してTCP RST (Reset) パケットを返しています。これは、サーバーは応答しているが、そのポートでは誰も LISTEN していない状態です。サービスが起動していないか、別のポートで待ち受けている可能性があります。
bash
$ telnet server.example.com 8081
Trying 192.168.1.100...
^C # ここで固まるか、タイムアウトする
ここで固まるか、しばらく待ってから Connection timed out
のようなエラーが表示される場合、クライアントからサーバーの指定ポートへの通信が途中で破棄されています。これは、サーバー側のOSファイアウォールや、ネットワーク経路上のファイアウォール/セキュリティグループなどが通信をブロックしている可能性が高いです。
telnet
はTCP接続のテストには使えますが、UDPポートの確認はできません。
nc
(netcat) コマンド:多機能なネットワークツール
nc
(netcat) は、「ネットワークの万能ツール」と呼ばれるほど多機能なコマンドです。TCP/UDPのポートスキャン、ポートへのデータ送受信、簡易サーバー/クライアントとしてなど、様々な用途で利用できます。ポート確認においても telnet
より高機能です。
CentOS 8/RHEL 8以降では ncat
という名前になっている場合もありますが、多くの場合 nc
のシンボリックリンクがあります。インストールされていない場合はインストールします。
“`bash
sudo yum install nc
または
sudo dnf install ncat
“`
ポート確認によく使うのは -zv
(zero-I/O mode and verbose) オプションです。
bash
nc -zv [ホスト名またはIPアドレス] [ポート番号]
実行例 (TCPポート):
サーバー server.example.com
のTCPポート22 (SSH) に接続を試みる場合。
bash
$ nc -zv server.example.com 22
Connection to server.example.com 22 port [tcp/ssh] succeeded!
succeeded!
と表示されれば接続成功です。
実行例 (UDPポート):
UDPポート53 (DNS) に接続を試みる場合。UDPの場合は -u
オプションが必要です。-z
はTCP向けですが、UDPでもポートが開いているかどうかの「応答があるか」の確認に使えます。ただし、UDPはコネクションレスのため、応答がなくてもポートが開いている可能性や、応答があっても偽物である可能性もあります。
bash
$ nc -zv -u server.example.com 53
Connection to server.example.com 53 port [udp/domain] succeeded! # 応答があれば成功と表示されることが多い
UDPの確認はTCPほど確実ではありませんが、ある程度の目安にはなります。
ポート範囲の指定:
nc
はポート範囲を指定してスキャンすることも可能です。
bash
nc -zv [ホスト名またはIPアドレス] [開始ポート]-[終了ポート]
実行例:
サーバー server.example.com
のTCPポート20から25をスキャンする場合。
bash
$ nc -zv server.example.com 20-25
nc: connect to server.example.com port 20 (tcp) failed: Connection refused
Connection to server.example.com 21 port [tcp/ftp] succeeded!
nc: connect to server.example.com port 23 (tcp) failed: Connection refused
Connection to server.example.com 24 port [tcp/priv-mail] succeeded!
Connection to server.example.com 25 port [tcp/smtp] succeeded!
これにより、ポート21, 24, 25が開いていることが分かります。
nc
は手軽にポートの到達性を確認するのに便利なツールです。
nmap
コマンド:本格的なポートスキャナー
nmap
(Network Mapper) は、ネットワーク探索とセキュリティ監査のための強力なオープンソースツールです。特定のホスト上で開いているポートを詳細にスキャンしたり、稼働しているサービスの種類やバージョン、OSの種類などを特定したりすることができます。ポート確認の用途で最も多機能で信頼性の高いツールの一つです。
CentOSにデフォルトでインストールされていない場合はインストールします。
“`bash
sudo yum install nmap
または
sudo dnf install nmap
“`
nmap
の基本的なスキャン
最も基本的な使い方は、ホスト名を指定するだけです。これにより、一般的な1000個のTCPポートに対してスキャンが実行されます。
bash
nmap [ホスト名またはIPアドレス]
実行例:
サーバー server.example.com
をスキャンする場合。
“`bash
$ nmap server.example.com
Starting Nmap 7.92 ( https://nmap.org ) at 2023-10-27 10:30 JST
Nmap scan report for server.example.com (192.168.1.100)
Host is up (0.00034s latency).
Not shown: 997 closed tcp ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
443/tcp open https
Nmap done: 1 IP address (1 host up) scanned in 0.55 seconds
``
open
この出力は、TCPポート22, 80, 443が状態であることを示しています。
openはポートがリモートから到達可能で、そのポートでサービスが待ち受けている可能性が高い状態です。
closedはポートが到達可能だが、誰も待ち受けていない状態 (TCP RST応答がある) です。
filtered` は通信がフィルタリングされている状態 (応答がない) です。
nmap
の主要オプション
-p <ポート番号>
: 特定のポートやポート範囲を指定してスキャンします。-p 80
: ポート80のみ。-p 22,80,443
: ポート22, 80, 443。-p 1-1024
: ポート1から1024まで。-p T:80,443,U:53
: TCP 80, 443 および UDP 53 をスキャン。-p "*"
: 全ポート (1-65535) をスキャン (時間がかかります)。
-sS
: TCP SYNスキャン (デフォルト、root権限が必要)。TCP 3ウェイハンドシェイクを完了させず、SYN/SYN+ACK応答でポート状態を判断するため、フルコネクションスキャンよりステルス性が高いです。-sT
: TCPコネクトスキャン。TCP 3ウェイハンドシェイクを完了させて接続を試みるスキャン。telnet
と似た動作ですが、スキャン結果をレポートしてくれます。root権限は不要です。-sU
: UDPスキャン。UDPポートをスキャンします。UDPは応答がないことが多いため、TCPスキャンより時間がかかり、結果の解釈が難しい場合があります。-sV
: ポートで稼働しているサービスの種類とバージョンを検出します。-O
: OSの種類を検出します。-A
: OS検出、バージョン検出、スクリプトスキャン、tracerouteを有効にする、包括的なスキャンオプション。時間がかかります。-Pn
: ホスト生存確認 (Ping) をスキップします。ファイアウォールがPingをブロックしている場合などに有効ですが、ホストが存在しない場合もスキャンを試みます。-v
(–verbose): 詳細な情報を出力します。-vv
: さらに詳細な情報を出力します。
応用例:
- 特定のTCPポートが開いているか確認:
bash
nmap -p 80 server.example.com - 特定のTCPポート範囲とUDPポートをスキャン:
bash
nmap -p T:20-25,U:53 server.example.com - サービスバージョンも検出する:
bash
nmap -sV server.example.com - フルコネクトスキャンで特定のポートを確認 (root不要):
bash
nmap -sT -p 8080 server.example.com
nmap
は、リモートホストのポート状態を詳しく調べるための最も強力なツールです。ただし、スキャン対象のシステムによっては、不審な活動として検知される可能性があるため、許可なく外部のシステムに対して実行するべきではありません。自身の管理するシステムに対して、トラブルシューティングやセキュリティ確認のために使用しましょう。
curl
または wget
:HTTP/Sポートの確認
Webサーバー (HTTP/HTTPS) が応答しているかを確認するだけであれば、curl
や wget
といったHTTPクライアントコマンドが手軽です。これらは指定したURLにアクセスを試み、応答があればポート80または443が外部に開いていて、Webサーバーが稼働していることを確認できます。
bash
curl -I http://server.example.com/ # -I オプションでヘッダーのみ取得
curl -I https://server.example.com/
bash
wget --spider http://server.example.com/ # --spider でダウンロードせずリンクチェック
wget --spider https://server.example.com/
これらのコマンドがHTTPステータスコード(例: HTTP/1.1 200 OK
や 301 Moved Permanently
など)を含む応答を受け取れれば、対象のWebサーバーは指定したポート(通常80または443)で正常に待ち受けていると判断できます。接続ができない場合はエラーが表示されます。
7. ファイアウォールとSELinuxの確認:ポートが開いていてもアクセスできない原因
ローカルホストで netstat
や ss
コマンドを実行してポートが LISTEN 状態になっていることが確認できたとしても、リモートホストからそのポートに接続できない場合があります。その最も一般的な原因は、サーバーのファイアウォールやSELinuxによって通信がブロックされていることです。
firewalld
によるポートの確認
CentOS 7以降のデフォルトファイアウォールは firewalld
です。firewalld
はゾーンベースでファイアウォールルールを管理します。特定のサービスやポートが許可されているか確認する必要があります。
-
稼働中のゾーンとその設定を確認:
bash
sudo firewall-cmd --get-active-zones # 現在アクティブなゾーンを確認
sudo firewall-cmd --list-all --zone=public # publicゾーンの設定を全て表示 (一般的なサーバーのデフォルトゾーン)
# または全て表示
sudo firewall-cmd --list-all-zones
--list-all
の出力にports:
の項目があり、許可されているポートが表示されます。
public (active)
target: default
icmp-block-inbound: no
interfaces: eth0
sources:
services: cockpit dhcpv6-client ssh
ports: 80/tcp 443/tcp 8080/tcp # <-- ここで許可されているポートを確認
protocols:
forward: no
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
この例では、publicゾーンでSSH (service)、TCPポート80, 443, 8080が許可されています。 -
特定のポートが特定のゾーンで許可されているか確認:
bash
sudo firewall-cmd --zone=public --query-port=80/tcp # TCPポート80がpublicゾーンで許可されているか
許可されていればyes
、そうでなければno
と表示されます。
ポートが firewalld
でブロックされている場合は、適切なゾーンにサービスまたはポートを追加する必要があります。
bash
sudo firewall-cmd --zone=public --add-port=8080/tcp --permanent # ポート8080/tcpをpublicゾーンに恒久的に追加
sudo firewall-cmd --reload # firewalld設定をリロードして変更を適用
ポートを追加する際は、そのポートがどのサービスによって使用されているかを理解し、必要最小限のポートのみを開けるように注意してください。
iptables
によるポートの確認
CentOS 7以前や、CentOS 7以降でも iptables-services
パッケージをインストールして利用している場合は、iptables
コマンドでファイアウォールルールを確認します。
- 現在のルールセットを表示:
bash
sudo iptables -L -n -v-L
: チェーンのルールを表示します。-n
: ポート番号やIPアドレスを数値で表示します (名前解決をスキップ)。-v
: 詳細情報を表示します (パケット数、バイト数など)。
出力では、INPUT
チェーンを確認します。ここに、外部からの接続を許可 (ACCEPT) または拒否 (DROP/REJECT) するルールが定義されています。
bash
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 state NEW,ESTABLISHED
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 state NEW,ESTABLISHED
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:443 state NEW,ESTABLISHED
...
1000 50000 DROP all -- * * 0.0.0.0/0 0.0.0.0/0
この例では、TCPポート22, 80, 443への新規接続 (state NEW
) や確立済み接続 (state ESTABLISHED
) が ACCEPT
されています。最後に DROP all
のようなルールがあれば、リストされたポート以外はすべてブロックされます。
iptables
のルールは上から順に評価されます。特定のポートへのアクセスを許可するルールが DROP
ルールより上に定義されている必要があります。
iptables
でポートを許可するには、適切なルールを追加して保存/再起動が必要です。
bash
sudo iptables -A INPUT -p tcp --dport 8080 -j ACCEPT # TCPポート8080へのアクセスを許可するルールを追加
sudo service iptables save # 設定を保存 (古いCentOSの場合)
sudo systemctl enable iptables # サービスを有効化・起動 (CentOS 7以降でiptables-services使用の場合)
sudo systemctl restart iptables # iptablesサービスを再起動
firewalld
と iptables
は同時に使用することはできません。CentOS 7以降の新しいシステムでは firewalld
が推奨されます。
SELinux によるポートの確認
SELinux (Security-Enhanced Linux) は、Linuxのセキュリティを強化するための機構です。プロセスの動作を制限したり、特定のポートで通信することを許可されているサービスを制御したりします。たとえファイアウォールでポートが開いていても、SELinuxがそのポートでのサービスの通信を許可していない場合、アクセスが拒否されることがあります。
-
SELinuxの状態を確認:
bash
getenforce
出力がEnforcing
の場合、SELinuxが有効で強制モードで動作しています。Permissive
の場合は警告のみ、Disabled
の場合は無効です。トラブルシューティングのために一時的にPermissive
に設定してみることはありますが、本番環境ではEnforcing
が推奨されます。 -
SELinuxが特定のポートでの通信を許可しているサービスコンテキストを確認:
semanage
コマンドを使用します。このコマンドはpolicycoreutils-python-utils
パッケージに含まれています。“`bash
sudo yum install policycoreutils-python-utilsまたは
sudo dnf install policycoreutils-python-utils
“`インストール後、許可されているポート一覧を表示します。
bash
sudo semanage port -l
出力例:
“`
SELinux Port Type Proto Port Numberafpd_port_t tcp 4700
amanda_port_t tcp 10080
…
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
…
ssh_port_t tcp 22
``
http_port_t
このリストは、各サービスタイプ (例:,
ssh_port_t) がどのプロトコル/ポート番号での通信をSELinuxレベルで許可されているかを示します。例えば、Webサーバー (通常
httpd_tまたは
nginx_tというSELinuxコンテキストで動作) がポート8080で待ち受けたい場合、そのポートが
http_port_tに関連付けられている必要があります。上記の例では、ポート8080は
http_port_t`に含まれていないため、デフォルト設定のままではSELinuxによってブロックされる可能性があります。 -
特定のポートが許可されているか確認:
bash
sudo semanage port -l | grep 8080
出力がなければ、デフォルト設定ではそのポートはどのサービスタイプにも関連付けられていません。 -
ポートとサービスタイプの関連付けを追加/変更:
サービスが待ち受けるポートがSELinuxポリシーで許可されていない場合、追加する必要があります。例えば、TCPポート8080をWebサーバー (httpd) が使えるようにする場合:
bash
sudo semanage port -a -t http_port_t -p tcp 8080 # TCPポート8080をhttp_port_tに追加
-a
は追加、-t
はタイプ、-p
はプロトコルを指定します。変更を適用するには、通常リブートは不要ですが、サービスを再起動すると良いでしょう。
ファイアウォールとSELinuxは異なるレベルでアクセス制御を行っています。ポートが開いているか確認する際は、両方の設定を確認することが重要です。
8. ポート確認に関するトラブルシューティング
ポート確認に関連してよく発生する問題と、その切り分け方法をまとめます。
「ポートが開いているはずなのにリモートから接続できない」
-
ローカルでの LISTEN 状態確認: まず、サーバー自身で該当ポートが LISTEN 状態になっているか確認します。
bash
sudo ss -tulnp | grep ':ポート番号[ \t]'
または
bash
sudo lsof -i :ポート番号
ここで表示されない場合、そもそもサービスが正しく起動していないか、別のポートで待ち受けているか、特定のIPアドレス(例: 127.0.0.1)でのみ待ち受けている可能性があります。サービスの状態 (systemctl status サービス名
) や設定ファイルを確認してください。LISTEN しているアドレスが127.0.0.1
や::1
の場合は、ローカルからのアクセスのみ許可しており、外部からのアクセスは受け付けません。0.0.0.0
や:::
で待ち受けているか確認してください。 -
サーバーOSファイアウォール確認: ローカルで LISTEN しているにも関わらずリモートから接続できない場合、OSのファイアウォールがブロックしている可能性が高いです。
firewalld
の場合:sudo firewall-cmd --zone=public --query-port=ポート番号/プロトコル
で許可されているか確認。許可されていなければsudo firewall-cmd --zone=public --add-port=ポート番号/プロトコル --permanent
とsudo firewall-cmd --reload
で追加。iptables
の場合:sudo iptables -L -n -v
で該当ポートを許可するルールがあるか、DROP
ルールより上に定義されているか確認。必要に応じてルールを追加・保存・再起動。
-
SELinux 確認: SELinuxがEnforcingモードの場合、特定のポートで通信できるサービスタイプが制限されています。
getenforce
でEnforcingか確認。sudo semanage port -l | grep ポート番号
で該当ポートが適切なサービスタイプに関連付けられているか確認。関連付けがなければsudo semanage port -a -t サービスタイプ_port_t -p プロトコル ポート番号
で追加。
-
ネットワーク経路上の確認: サーバーOS、ファイアウォール、SELinuxいずれも問題ない場合、ネットワーク経路上の問題(ルーターのACL、クラウドプロバイダーのセキュリティグループ、ネットワーク機器のファイアウォールなど)の可能性が高いです。
- クライアント側から
telnet ホスト ポート
またはnc -zv ホスト ポート
で接続を試み、エラーメッセージを確認します。Connection timed out
なら経路上のブロック、Connection refused
ならサーバー側で誰も聞いていない状態です。 traceroute
コマンドでクライアントからサーバーまでの経路を確認し、どこまで到達できるか、あるいはどこでパケットが止まっているかヒントを得ます。
- クライアント側から
「特定のサービスが起動しているのにポートが LISTEN していない」
-
サービスの状態確認: サービスが本当に「正常に」起動しているか確認します。
bash
sudo systemctl status サービス名
Active: active (running)
と表示されていても、設定エラーなどで実際にはポートを LISTEN できていないことがあります。ログ (journalctl -u サービス名
や/var/log/messages
など) を確認してエラーが出ていないか調べます。 -
設定ファイル確認: サービスの設定ファイル(例: Apacheなら
/etc/httpd/conf/httpd.conf
, Nginxなら/etc/nginx/nginx.conf
, MySQLなら/etc/my.cnf
など)で、待ち受けポートや待ち受けIPアドレスが正しく設定されているか確認します。デフォルト以外のポートを使っている可能性もあります。 -
他のプロセスとのポート競合: 既に別のプロセスが同じポートを使用している場合、サービスが起動に失敗するか、意図しないポートで待ち受けてしまうことがあります。
bash
sudo ss -tulnp | grep ':ポート番号[ \t]'
または
bash
sudo lsof -i :ポート番号
で、該当ポートを別のプロセスが使用していないか確認します。競合している場合は、競合しているプロセスを停止するか、サービスの待ち受けポートを変更する必要があります。
「コマンドが見つからない (command not found)」
netstat
, ss
, lsof
, nc
, nmap
, firewall-cmd
, semanage
などのコマンドが存在しない場合、そのパッケージがインストールされていません。
使用したいコマンドに応じて、以下のコマンドでインストールします。(ディストリビューションのバージョンや派生によってパッケージ名が異なる場合があります)
netstat
,ss
:net-tools
またはiproute2
パッケージ (通常デフォルトインストール)lsof
:lsof
パッケージnc
:nc
またはncat
パッケージnmap
:nmap
パッケージfirewall-cmd
:firewalld
パッケージsemanage
:policycoreutils-python-utils
パッケージ
例:
bash
sudo yum install lsof nmap nc policycoreutils-python-utils
「Permission denied(権限がない)」
netstat -p
, ss -p
, lsof -i
など、プロセス情報を含むソケット情報を表示するには、通常root権限が必要です。これらのコマンドを実行する際は sudo
を付けて実行してください。
bash
sudo netstat -tulnp
sudo lsof -i :80
9. まとめ:状況に応じたツール選択とセキュリティ意識
CentOS環境でポートを確認するための様々なコマンドと方法を解説しました。それぞれのコマンドには得意なこと、不得意なことがあります。
netstat
: 基本的なローカルポート状態確認の定番。シンプルにLISTENポートや確立済み接続を見たい場合に。ss
:netstat
の後継。高速で詳細な情報、強力なフィルタリング機能が必要な場合に。lsof
: 特定のプロセスがどのポートを使っているか、あるいは特定のポートをどのプロセスが使っているかなど、プロセスとの関連付けを調べたい場合に。telnet
/nc
: リモートホストの特定のポートへの到達性を手軽に確認したい場合に。nmap
: リモートホストで開いているポートを体系的にスキャンし、サービス情報なども取得したい場合に。セキュリティ監査にも利用可能。firewall-cmd
/iptables
: OSレベルのファイアウォール設定を確認する場合に。semanage
: SELinuxによるポートのアクセス制御設定を確認する場合に。
これらのツールを適切に使い分けることで、システムの状態を正確に把握し、問題を迅速に解決することができます。
最後に、ポート確認はセキュリティと密接に関わる作業であることを忘れてはなりません。必要最小限のポートのみを開放し、不要なサービスは停止することがセキュリティの基本です。定期的にポート状態を確認し、意図しないポートが開いていないかチェックする習慣をつけましょう。
本記事が、あなたのCentOSサーバー管理の一助となれば幸いです。