お金をかけずにサーバーの勉強をしよう

ssコマンド

2024年4月3日

メニューへ戻る

ネットワークソケットの状態を確認します。

サーバープログラムはほぼ TCP/IPを使って通信をしていると思います。

(サーバーマシンを立ち上げた時というより)サーバープログラムでサービスを開始した時に、何故か通信が上手くいかない、繋がらないってことは本当によくあります。

作業者が IPアドレスやポート番号を勘違いしているとか、サーバープログラムのネットワーク設定を間違えている事がほとんどですけど、その原因に辿り着くための一助として ssコマンド(another utility to investigate sockets)を使ってみましょう。

以前は netstat というコマンドがありましたが、最近の Linux OSでは、ssコマンドの利用が推奨されていますし、Ubuntuには ssコマンドはデフォルトで入っていますが、netstatコマンドはパッケージを導入しないと使えません。

ですのでこれから Linuxでサーバーのお勉強をする方は、まずは ssコマンドを使えるようになっておきましょう。

環境は Lubuntu 22.04.4を使っていますが、他の Linux OSのいずれでもほぼ同じだと思います。
(検証してないですが多分大丈夫)


論より証拠で早速実行してみます。

[/usr/bin/ss]ファイルが実行対象ファイルです。

subro@Lubuntu2204:~$ ss
Netid State  Recv-Q Send-Q                                      Local Address:Port       Peer Address:Port  Process
u_dgr ESTAB  0      0                                     /run/systemd/notify 23395                 * 0
u_dgr ESTAB  0      0                            /run/systemd/journal/dev-log 23421                 * 0

〜〜〜 以下省略 〜〜〜

ssコマンドをオプションなしで実行すると、デフォルトで起動されているプロセスが UNIXドメインソケットを使って通信しているものがモロモロと出てきてしまうので、適宜オプションを使ってなるべく欲しい物だけ出すようにします。

私がよく使うオプションは以下です。
(好みなのでこれにしないといけない訳ではありません)

aAll
待受け状態(LISTEN)もそれ以外(TCPでは ESTABLISH)も表示する。
nNumeric
ポート表示を [/etc/services]ファイルの名前に変換しないで番号にする。
tTCP
TCPで通信しているものを表示する。
uUDP
UDPで通信しているものを表示する。
pProcess
対象のソケットを使っているプロセスを表示する。

ssコマンドはオプションを一杯使うので覚え切れないのですが、使う度に調べるのも面倒なので、私は「アントアップ」とか勝手に名付けて覚えています。

実際にやってみます。

subro@Lubuntu2204:~$ ss -antup
Netid    State     Recv-Q    Send-Q                           Local Address:Port             Peer Address:Port    Process
udp      UNCONN    0         0                                      0.0.0.0:43360                 0.0.0.0:*
udp      UNCONN    0         0                                127.0.0.53%lo:53                    0.0.0.0:*
udp      ESTAB     0         0                           192.168.1.45%ens33:68                192.168.1.1:67
udp      UNCONN    0         0                                      0.0.0.0:631                   0.0.0.0:*
udp      UNCONN    0         0                                      0.0.0.0:5353                  0.0.0.0:*
udp      UNCONN    0         0                                         [::]:40261                    [::]:*
udp      UNCONN    0         0             [fe80::96cc:75a6:ebf:d7cf]%ens33:546                      [::]:*
udp      UNCONN    0         0                                         [::]:5353                     [::]:*
tcp      LISTEN    0         128                                  127.0.0.1:631                   0.0.0.0:*
tcp      LISTEN    0         4096                             127.0.0.53%lo:53                    0.0.0.0:*
tcp      ESTAB     0         0                                 192.168.1.45:34214           xx.xx.xxx.xxx:443      users:(("firefox",pid=1519,fd=60))
tcp      ESTAB     0         0                                 192.168.1.45:52338         xxx.xxx.xxx.xxx:443      users:(("firefox",pid=1519,fd=138))

項目名は以下を表します。

Netid(ここでは)TCPか UDPか。
Stateソケットの状態
大体 TCPを見るので以下の通り。
LISTEN = 待受け中
ESTAB = 通信中
Recv-Q/Send-Q通信待ちしているパケットの数
(詳細は割愛)
Local Address:Portssコマンドを実行したマシン側の IPアドレスとポート。
Peer Address:Port通信先の IPアドレスとポート。
Processソケットを使っているプロセスの情報。

上の実行例だと、下2行が Firefoxがインターネット上のサーバーに https(443/tcp)でアクセスしている様子を表していますね。

でもそれ以外はプロセス名が出ていません。
どうやら一般ユーザーだと自分のプロセスしかプロセス情報を得られないようです。

こういうときは sudoコマンドを使って管理者権限でやってみます。

subro@Lubuntu2204:~$ sudo ss -antup
Netid    State     Recv-Q    Send-Q                          Local Address:Port          Peer Address:Port   Process
udp      UNCONN    0         0                                     0.0.0.0:43360              0.0.0.0:*       users:(("avahi-daemon",pid=713,fd=14))
udp      UNCONN    0         0                               127.0.0.53%lo:53                 0.0.0.0:*       users:(("systemd-resolve",pid=676,fd=13))
udp      ESTAB     0         0                          192.168.1.45%ens33:68             192.168.1.1:67      users:(("NetworkManager",pid=718,fd=25))
udp      UNCONN    0         0                                     0.0.0.0:631                0.0.0.0:*       users:(("cups-browsed",pid=1046,fd=7))
udp      UNCONN    0         0                                     0.0.0.0:5353               0.0.0.0:*       users:(("avahi-daemon",pid=713,fd=12))
udp      UNCONN    0         0                                        [::]:40261                 [::]:*       users:(("avahi-daemon",pid=713,fd=15))
udp      UNCONN    0         0            [fe80::96cc:75a6:ebf:d7cf]%ens33:546                   [::]:*       users:(("NetworkManager",pid=718,fd=27))
udp      UNCONN    0         0                                        [::]:5353                  [::]:*       users:(("avahi-daemon",pid=713,fd=13))
tcp      LISTEN    0         128                                 127.0.0.1:631                0.0.0.0:*       users:(("cupsd",pid=796,fd=7))
tcp      LISTEN    0         4096                            127.0.0.53%lo:53                 0.0.0.0:*       users:(("systemd-resolve",pid=676,fd=14))
tcp      ESTAB     0         0                                192.168.1.45:36502        xx.xxx.xx.xxx:443     users:(("firefox",pid=1519,fd=77))
tcp      ESTAB     0         0                                192.168.1.45:39666        xx.xxx.xx.xxx:443     users:(("firefox",pid=1519,fd=98))

他には IPv4のソケットだけみたい事が多いので [4] もよく使います。

4IPv4のソケットを表示。
6IPv6のソケットを表示。


このコマンドを実行した結果よくあるのが、

の 2パターンです。

あとちょっと込み入った状況では、プロキシサーバーなどでソケットが多くなり過ぎて枯渇している、ということもあります。

ssコマンドの詳細は manコマンドでマニュアルを見て頂くとして、今後 UNIXドメインソケットを使うプログラムを扱う時にもこのコマンドを使うことになると思います。

私が知っている有名所では PHPや MySQLなんかありました。


==========
簡単に実行できる割に非常に有用なので覚えておいて損はないでしょう。

「あんとあっぷ」このおまじないで、これまでよりも一段階上の障害対応を(吐)。