【Linux】lsof、ss、nmapコマンドでポート確認!

今回は、Linuxポートを使用しているアプリケーションを確認する方法を説明します。

「サーバーを用意したのにうまく通信できない!」
「使用したいポートがすでに何かに使われている!」

と困ったときに、原因調査に役立つ知識です。

具体的には、

・ポートってよく聞くけど何?
・似たような文脈でソケットというのもあるけど、ポートとの違いは何?
・すでにポートが使われているみたいなんだけど、どのプログラムが使っているのか調べられる?
・外部に向けて必要なポートが解放されているか(不必要なポートが閉じられているか)確認できる?

といった疑問に答えます。

それでは、行ってみましょう。

目次

ポート(port)とは

shutterstock_789476149

ポート(port)には、「港」という意味があります。

そこで、Linuxのポートを「港」に見立てると、Linux(サーバー)は「島」、インターネットは「海(ケーブルが船の航路)」になります。

また、Linux(サーバー)で動作するWebサーバーなどのサーバーアプリケーションは「島にある企業」というイメージでしょうか。

Linux(サーバー)には0番~65535番のポートが存在しますので、これはそのままに0番~65535番のが存在すると考えます。

続けて、ポートに関する説明をいくつかピックアップして、港の概念で説明し直してみましょう。

ポートを開いたり閉じたり?

港のたとえで考えると、「ポートを開く」は「港の使用を許可して船(荷物)を受け入れる」という意味で、「ポートを閉じる」は「港を使用禁止にして船(荷物)を受け入れない」という意味です。

「Linuxのポートを閉じて、外部からの通信を遮断する」という言い方を聞いたことがあるでしょうか。

これは、「港を使用禁止にして、外部からの船(荷物)が入港できないようにする」というイメージです。

また、「セキュリティを考慮して80番と443番のポートだけを開く」という説明は、「セキュリティを考慮して80番の港と443番の港だけ使用を許可して船(荷物)を受け付け、他の港は(誰/何が乗っているかわからないため)使用禁止にして船(荷物)を受け入れない」と言いかえられます。

1つのプロセスが複数のポートを使用する?
複数のプロセスが1つのポートを共用する?

Linuxでは、1つのプロセスが2つ以上のポートを使用する場合があります。

※ここで突然「プロセス」という言葉がでてきましたが、ここでは、サーバーアプリケーションとほぼ同義と考えても差し支えありません。

逆に、複数のプロセスが1つのポートを共用することはありません。

港にたとえると、1つの企業が2つ以上の港を使用する場合がありますが、2つの企業が1つの港を共用することはありません、となります。

徐々にポートと港のイメージが重なってきたでしょうか。

ポートの特定方法は?

ポートは、Linux(サーバー)にある何番のポートか(=島にある何番の港か)という点にのみ注目した概念です。

そのため、単純に番号だけで特定されます。

それ以外の情報はありません。

ソケットとは

shutterstock_764004589

さて、次はポートと非常に似たような概念であるソケットの話をします。

この後に紹介するコマンドの中には、ソケットの情報を確認するコマンドがあります。

そこで、なぜソケットの情報を確認すると、ポートの情報がわかるのか、という点について理解する必要があります。

ソケットは港(ポート)の管理者と言える

先ほどの、ポートを港にたとえた話を続けると、ソケットは港の管理者のようなイメージと言えます。

島にある企業(=サーバーアプリケーション)が、80番の港に荷物が届くのを待つ場合、80番の港に管理者(=ソケット)を配置します。

たとえば船(荷物)が無事に届いた場合、港の管理者(=ソケット)は、企業の担当者(=また別のソケット)に送受信の管理を引き継ぎます。

逆に船(荷物)が一部欠けていた場合、港の管理者(=ソケット)は、他の島の港にいる管理者(=送信元のソケット)に、再送を依頼します。

このように、ポートが港なら、ソケットは管理者、と言えるくらいの違いがあります。

ソケットの特定方法は?

管理者(=ソケット)は、自分の島にも他の島にも存在するため、島の番号と港の番号(=IPアドレスとポート番号)+αの情報を組み合わせて特定されます。

ソケットを特定する情報の中にポート番号が含まれるため、ソケットの状況(IPアドレス+ポート番号+α)を確認すれば、ポートの状況が確認できるという考え方です。

内部からポートの状況を確認する

さて、たとえを交えながら長々と説明してしまいましたが、ここからは、Linuxのコマンドを中心に説明していきましょう。

まず初めは、内部からポートの状況を確認する方法を説明します。

内部からポートの状況を確認することは、島のたとえで言えば、島の役人が、島の企業が、それぞれどの港を使っているかを調べることにたとえられます。

プロセスが使用しているポートを確認する

特定のファイルやポートをオープンしているプロセスを確認するlsofコマンドで、プロセスが使用しているポートを調べる方法を紹介します。

入力するコマンドは以下のとおりです。

sudo lsof -i -P

そして、実行結果は以下のとおりです。

COMMAND    PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
avahi-dae  698    avahi   12u  IPv4  18833      0t0  UDP *:5353
avahi-dae  698    avahi   13u  IPv6  18834      0t0  UDP *:5353
avahi-dae  698    avahi   14u  IPv4  18835      0t0  UDP *:60008
avahi-dae  698    avahi   15u  IPv6  18836      0t0  UDP *:38367
cupsd      707     root   10u  IPv6  18906      0t0  TCP ip6-localhost:631 (LISTEN)
cupsd      707     root   11u  IPv4  18907      0t0  TCP localhost:631 (LISTEN)
cups-brow  727     root    8u  IPv4  18008      0t0  UDP *:631
dhclient  1231     root    6u  IPv4  20845      0t0  UDP *:68
dnsmasq   1251   nobody    4u  IPv4  20184      0t0  UDP yazaki-VirtualBox:53
dnsmasq   1251   nobody    5u  IPv4  20185      0t0  TCP yazaki-VirtualBox:53 (LISTEN)
dnsmasq   1251   nobody   11u  IPv4  20208      0t0  UDP *:37000
ntpd      2292      ntp   16u  IPv6  25003      0t0  UDP *:123
ntpd      2292      ntp   17u  IPv4  25006      0t0  UDP *:123
ntpd      2292      ntp   18u  IPv4  25010      0t0  UDP localhost:123
ntpd      2292      ntp   19u  IPv4  25012      0t0  UDP 10.0.2.15:123
ntpd      2292      ntp   20u  IPv6  25014      0t0  UDP ip6-localhost:123
ntpd      2292      ntp   21u  IPv6  25016      0t0  UDP [fe80::df7f:1c50:ea1e:89b0]:123
apache2   4078     root    4u  IPv6  28543      0t0  TCP *:80 (LISTEN)
apache2   4081 www-data    4u  IPv6  28543      0t0  TCP *:80 (LISTEN)
apache2   4082 www-data    4u  IPv6  28543      0t0  TCP *:80 (LISTEN)

この表示から、以下の内容が読み取れます。

  • 「apache2」で始まる3行の表示から、
    apache2コマンドの3つのプロセス(4078,4081,4082)が、
    任意のIPアドレスの80番ポートからの通信を待っている(TCPの場合はLISTENと表示されます)
  • 「dhclient」で始まる行の表示から、
    dhclientコマンドの1つのプロセスが、
    任意のIPアドレスの68番ポートからの通信を待っている(UDPの場合はLISTENと表示されません)

同様に、53番ポート123番ポート631番ポート5353番ポート37000番ポート38367番ポート60008番ポートからの通信を待っているプロセスがあることがわかります。

接続待ちをしているソケットを確認する

接続待ちをしているソケットを確認するssコマンドで、ポートを利用しているアプリケーションを調べる方法を紹介します。

sudo ss -ltunp

実行結果は、以下のとおりです。

Netid State      Recv-Q Send-Q Local Address:Port               Peer Address:Port
udp   UNCONN     0      0              *:60008                      *:*                   users:(("avahi-daemon",pid=698,fd=14))
udp   UNCONN     0      0              *:631                        *:*                   users:(("cups-browsed",pid=727,fd=8))
udp   UNCONN     0      0      127.0.1.1:53                         *:*                   users:(("dnsmasq",pid=1251,fd=4))
udp   UNCONN     0      0              *:68                         *:*                   users:(("dhclient",pid=1231,fd=6))
udp   UNCONN     0      0      10.0.2.15:123                        *:*                   users:(("ntpd",pid=2292,fd=19))
udp   UNCONN     0      0      127.0.0.1:123                        *:*                   users:(("ntpd",pid=2292,fd=18))
udp   UNCONN     0      0              *:123                        *:*                   users:(("ntpd",pid=2292,fd=17))
udp   UNCONN     0      0       *%enp0s3:37000                      *:*                   users:(("dnsmasq",pid=1251,fd=11))
udp   UNCONN     0      0              *:5353                       *:*                   users:(("avahi-daemon",pid=698,fd=12))
udp   UNCONN     0      0             :::38367                     :::*                   users:(("avahi-daemon",pid=698,fd=15))
udp   UNCONN     0      0      fe80::df7f:1c50:ea1e:89b0%enp0s3:123                       :::*                   users:(("ntpd",pid=2292,fd=21))
udp   UNCONN     0      0            ::1:123                       :::*                   users:(("ntpd",pid=2292,fd=20))
udp   UNCONN     0      0             :::123                       :::*                   users:(("ntpd",pid=2292,fd=16))
udp   UNCONN     0      0             :::5353                      :::*                   users:(("avahi-daemon",pid=698,fd=13))
tcp   LISTEN     0      5      127.0.1.1:53                         *:*                   users:(("dnsmasq",pid=1251,fd=5))
tcp   LISTEN     0      5      127.0.0.1:631                        *:*                   users:(("cupsd",pid=707,fd=11))
tcp   LISTEN     0      128           :::80                        :::*                   users:(("apache2",pid=4082,fd=4),("apache2",pid=4081,fd=4),("apache2",pid=4078,fd=4))
tcp   LISTEN     0      5            ::1:631                       :::*                   users:(("cupsd",pid=707,fd=10))

この表示から、以下の内容が読み取れます。

  • 「apache2」が含まれる行の表示から、
    apache2コマンドの3つのプロセスが、
    任意のIPアドレスの80番ポートからの通信を待っている(TCPの場合はLISTENと表示されます)
  • 「dhclient」が含まれる行の表示から、
    dhclientコマンドの1つのプロセスが、
    任意のIPアドレスの68番ポートからの通信を待っている(UDPの場合はUNCONNと表示されます)

こちらも同様に、53番ポート123番ポート631番ポート5353番ポート37000番ポート38367番ポート60008番ポートからの通信を待っているプロセスがあることがわかります。

外部からポートの状況を確認する

次に、外部からポートの状況(主にopenclosedfiltered)を確認する方法を紹介します。

外部からポートの状況を確認することは、島のたとえで言えば、他の島の役人が、どの港が使用できるかを調べること(どの企業が使っているかはわからない)にたとえられます。

TCPのポートの状況を確認する

まずはTCPに限定したコマンドから紹介します。

nmap -p 0-65535 localhost

実行結果は以下のとおりです。

Starting Nmap 7.01 ( https://nmap.org ) at 2018-06-10 19:20 JST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000055s latency).
Not shown: 65534 closed ports
PORT    STATE SERVICE
80/tcp  open  http
631/tcp open  ipp

Nmap done: 1 IP address (1 host up) scanned in 2.05 seconds

この表示から、以下の内容が読み取れます。

  • 「PORT STATE SERVICE」の下の2行の表示から、
    80番ポートと、631番ポートが外部からの通信を受け付けている状態(open)になっている
  • 「PORT STATE SERVICE」の上の1行の表示から、
    80番と631番以外の65534個のポートは、すべて外部からの通信を受け付けているアプリケーションがない状態(closed)になっている

lsofコマンドやssコマンドで確認したdnsmasqコマンドが待っているはずの53番ポートは、外部からは閉じて見えるようですね。

UDPのポートの状況を確認する

次は、UDPに限定したコマンドを紹介します。

UDPの場合は、全ポートをスキャンすると大変な時間がかかるため、調査するポートも限定しています。

sudo nmap -sU localhost

実行結果は以下のとおりです。

Starting Nmap 7.01 ( https://nmap.org ) at 2018-06-10 19:25 JST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.0000060s latency).
Not shown: 996 closed ports
PORT     STATE         SERVICE
68/udp   open|filtered dhcpc
123/udp  open          ntp
631/udp  open|filtered ipp
5353/udp open|filtered zeroconf

Nmap done: 1 IP address (1 host up) scanned in 2.75 seconds

この表示から、以下の内容が読み取れます。

  • 「PORT STATE SERVICE」の下の4行の表示から、
    68番ポート631番ポート5353番ポートの3つが、
    外部からの通信を受け付けている状態(open)または外部からの通信がフィルタリングされている状態(filtered)のどちらかになっており、判別できない
  • 「PORT STATE SERVICE」の上の1行の表示から、
    よく使われているポートのうちの996個のポートは、
    外部からの通信を受け付けているアプリケーションがない状態(closed)になっている

53番ポート37000番ポート38367番ポート60008番ポートは、lsofコマンドssコマンドで確認すると通信を受け付けているように見えますが、実行結果に含まれていませんので、次のコマンドで確認します。

sudo nmap -p 53,37000,38367,60008 -sU localhost

次のように表示されました。

Starting Nmap 7.01 ( https://nmap.org ) at 2018-06-10 19:33 JST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000053s latency).
PORT      STATE         SERVICE
53/udp    closed        domain
37000/udp closed        unknown
38367/udp closed        unknown
60008/udp open|filtered unknown

Nmap done: 1 IP address (1 host up) scanned in 1.39 seconds

なるほど、53番ポート37000番ポート38367番ポートは、外部からの通信を受け付けているアプリケーションがない状態(closed)ですね。

そして、60008番ポートは、外部からの通信を受け付けている状態(open)または外部からの通信がフィルタリングされている状態(filtered)のどちらかになっており、判別できないことがわかりました。

まとめ

今回は、ポートを「港」に、ソケットを「港の管理者」にたとえながら、それぞれの概要を説明しました。

また、ポートを使用しているプロセスを調べる方法と、外部からのポートの状況を調べる方法を紹介しました。

今回紹介したlsofコマンドssコマンドnmapコマンドには、さまざまなオプションが用意されています。

オプションを適切に組み合わせることで、必要な情報をすばやく取得できるでしょう。

興味が湧いた方は、コマンドのオプションも調べてみると面白いですよ!

では、今回はこの辺で!

この記事を書いた人

侍エンジニア塾は「人生を変えるプログラミング学習」をコンセンプトに、過去多くのフリーランスエンジニアを輩出したプログラミングスクールです。侍テック編集部では技術系コンテンツを中心に有用な情報を発信していきます。

目次