hana_shinのLinux技術ブログ

Linuxの技術情報を掲載しています。特にネットワークをメインに掲載していきます。

ssコマンドの使い方



1 ssコマンドとは?

ソケットの状態を確認するコマンドです。CentOS6まではnetstatコマンドが使われていましたが、CentOS7からssコマンドにかわりました。

2 検証環境

2.1 ネットワーク構成

サーバとクライアントの2台構成です。図中のens33はNICの名前です。IPv4アドレスの他に、IPv6リンクローカルアドレスも記載しています。

                               192.168.2.0/24
client(ens33) ------------------------------------------(ens33) server
        .105                                           .100
fe80::3e2:a9c0:9fa6:a8ad/64                            fe80::174:936a:8876:8055/64

2.2 版数

CentOS版数は、サーバ、クライアントともに下記版数です。

[root@server ~]# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)

カーネル版数は以下のとおりです。

[root@server ~]# uname  -r
3.10.0-1160.el7.x86_64

ssコマンドの版数は以下のとおりです。

[root@server ~]# ss -version
ss utility, iproute2-ss170501

3 マニュアルのインストール

ssコマンドのマニュアルは、man以外にiproute-docパッケージにもあります。manに記載されていない説明もあるので、iproute-docパッケージに含まれるマニュアルも取得します。

[root@server ~]# yum -y install iproute-doc

ps2pdfコマンドを使うため、ghostscriptパッケージをインストールします。

[root@server ~]# yum -y install ghostscript

以下の場所にマニュアルがインストールされます。

[root@server ~]# ls /usr/share/doc/iproute-doc-4.11.0/ss.ps
/usr/share/doc/iproute-doc-4.11.0/ss.ps

psファイルをpdfファイルに変換します。

[root@server ~]# ps2pdf /usr/share/doc/iproute-doc-4.11.0/ss.ps ss.pdf

4 オプション一覧

オプションは以下のとおりです。

[root@server ~]# ss -help
Usage: ss [ OPTIONS ]
       ss [ OPTIONS ] [ FILTER ]
   -h, --help          this message
   -V, --version       output version information
   -n, --numeric       don't resolve service names
   -r, --resolve       resolve host names
   -a, --all           display all sockets
   -l, --listening     display listening sockets
   -o, --options       show timer information
   -e, --extended      show detailed socket information
   -m, --memory        show socket memory usage
   -p, --processes     show process using socket
   -i, --info          show internal TCP information
   -s, --summary       show socket usage summary
   -b, --bpf           show bpf filter socket information
   -E, --events        continually display sockets as they are destroyed
   -Z, --context       display process SELinux security contexts
   -z, --contexts      display process and socket SELinux security contexts
   -N, --net           switch to the specified network namespace name

   -4, --ipv4          display only IP version 4 sockets
   -6, --ipv6          display only IP version 6 sockets
   -0, --packet        display PACKET sockets
   -t, --tcp           display only TCP sockets
   -S, --sctp          display only SCTP sockets
   -u, --udp           display only UDP sockets
   -d, --dccp          display only DCCP sockets
   -w, --raw           display only RAW sockets
   -x, --unix          display only Unix domain sockets
       --vsock         display only vsock sockets
   -f, --family=FAMILY display sockets of type FAMILY
       FAMILY := {inet|inet6|link|unix|netlink|vsock|help}

   -K, --kill          forcibly close sockets, display what was closed
   -H, --no-header     Suppress header line

   -A, --query=QUERY, --socket=QUERY
       QUERY := {all|inet|tcp|udp|raw|unix|unix_dgram|unix_stream|unix_seqpacket|packet|netlink|vsock_stream|vsock_dgram}[,QUERY]

   -D, --diag=FILE     Dump raw information about TCP sockets to FILE
   -F, --filter=FILE   read filter information from FILE
       FILTER := [ state STATE-FILTER ] [ EXPRESSION ]
       STATE-FILTER := {all|connected|synchronized|bucket|big|TCP-STATES}
         TCP-STATES := {established|syn-sent|syn-recv|fin-wait-{1,2}|time-wait|closed|close-wait|last-ack|listen|closing}
          connected := {established|syn-sent|syn-recv|fin-wait-{1,2}|time-wait|close-wait|last-ack|closing}
       synchronized := {established|syn-recv|fin-wait-{1,2}|time-wait|close-wait|last-ack|closing}
             bucket := {syn-recv|time-wait}
                big := {established|syn-sent|fin-wait-{1,2}|closed|close-wait|last-ack|listen|closing}

5 TCPソケットを表示する方法(-t)

TCPソケットの状態を確認するには、-tオプションを使います。なお、出力結果を見やすくするため、IPv4ソケット(4オプション指定)だけを表示します。

5.1 全てのTCPソケットを表示する方法(-a)

-aは、全てのTCPソケットを表示するオプションです。私の環境では、LISTENとESTABLISH状態のTCPソケットが表示されました。ソケットの状態としては、他にもTIME-WAIT、FIN-WAIT-2等あります。

[root@server ~]# ss -ta4
State      Recv-Q Send-Q                                Local Address:Port                                                 Peer Address:Port
LISTEN     0      5                                     192.168.122.1:domain                                                          *:*
LISTEN     0      128                                               *:ssh                                                             *:*
LISTEN     0      128                                       127.0.0.1:ipp                                                             *:*
LISTEN     0      100                                       127.0.0.1:smtp                                                            *:*
LISTEN     0      128                                               *:sunrpc                                                          *:*
ESTAB      0      36                                    192.168.2.100:ssh                                                  192.168.2.12:50540

5.2 サービス名をポート番号で確認する方法(-n)

-nは、サービス名ではなくポート番号を表示するオプションです。-nオプションをつけてssコマンドを実行すると、sshは22であることがわかります。なお、サービス名とポート番号の対応関係は、/etc/servicesに登録されています。

[root@server ~]# ss -tan4
State      Recv-Q Send-Q                                  Local Address:Port                                                 Peer Address:Port
LISTEN     0      5                                       192.168.122.1:53                                                              *:*
LISTEN     0      128                                                 *:22                                                              *:*
LISTEN     0      128                                         127.0.0.1:631                                                             *:*
LISTEN     0      100                                         127.0.0.1:25                                                              *:*
LISTEN     0      128                                                 *:111                                                             *:*
ESTAB      0      36                                      192.168.2.100:22                                                   192.168.2.12:50540

5.3 LISTEN状態のソケットを表示する方法(-l)

-lは、LISTEN状態のソケットだけを表示するオプションです。-lオプションをつけてssコマンドを実行すると、LISTEN状態のソケットだけが表示されます。

[root@server ~]# ss -tln4
State      Recv-Q Send-Q                                  Local Address:Port                                                 Peer Address:Port
LISTEN     0      5                                       192.168.122.1:53                                                              *:*
LISTEN     0      128                                                 *:22                                                              *:*
LISTEN     0      128                                         127.0.0.1:631                                                             *:*
LISTEN     0      100                                         127.0.0.1:25                                                              *:*
LISTEN     0      10                                                  *:11111                                                           *:*
LISTEN     0      128                                                 *:111                                                             *:*

5.4 ソケットを使っているプロセスを表示する方法(-p)

-pは、ソケットを使っているプロセスを表示するオプションです。右端を確認すると、1行目と2行目のESTABLISH状態のソケットは、sshdプロセスが使っていることがわかります。

[root@server ~]# ss -tp4
State      Recv-Q Send-Q                                    Local Address:Port                                                     Peer Address:Port
ESTAB      0      0                                         192.168.2.100:ssh                                                      192.168.2.12:51303                 users:(("sshd",pid=1983,fd=3))
ESTAB      0      36                                        192.168.2.100:ssh                                                      192.168.2.12:50540                 users:(("sshd",pid=1777,fd=3))

6 UDPソケットを表示する(-u)

UDPTCPとちがって、コネクションという概念がありません。TCPのソケットのように、LISTEN、ESTABLISH等の状態はありませんが、ssコマンドでは、データの送受信を行っているソケットはESTABLISHと表示されます。また、データの送受信を行っていないソケットは、UNCONNと表示されます。

6.1 全てのUDPソケットを表示する方法(-a)

IPv4UDPソケットを全て表示してみます。左端がUNCONN と表示されているので、いずれのソケットもデータの送受信をしていないことがわかります。

[root@server ~]# ss -ua4
State      Recv-Q Send-Q                                    Local Address:Port                                                     Peer Address:Port
UNCONN     0      0                                                     *:mdns                                                                *:*
UNCONN     0      0                                                     *:56771                                                               *:*
UNCONN     0      0                                         192.168.122.1:domain                                                              *:*
UNCONN     0      0                                              *%virbr0:bootps                                                              *:*
UNCONN     0      0                                                     *:bootpc                                                              *:*
UNCONN     0      0                                                     *:sunrpc                                                              *:*
UNCONN     0      0                                             127.0.0.1:323                                                                 *:*
UNCONN     0      0                                                     *:798                                                                 *:*

IPv6UDPソケットを全て表示してみます。

[root@server ~]# ss -ua6
State      Recv-Q Send-Q               Local Address:Port                                Peer Address:Port
UNCONN     0      0                             [::]:sunrpc                                      [::]:*
UNCONN     0      0                            [::1]:323                                         [::]:*
UNCONN     0      0                             [::]:798                                         [::]:*

6.2 データの送受信をしているソケットだけを表示する方法

ここでは、iperf3を使って、クライアントからサーバにUDPパケットを送信してみます。このとき、サーバのIPv6ソケットの状態を確認してみます。インストール、ポート番号開放等のiperf3の使い方は、iperf3コマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

サーバでiperf3を起動します。

[root@server ~]# iperf3 -s
-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------

クライアントでiperf3を実行します。-uはUDPパケット送信、-tはテスト時間(秒)を表しています。

[root@client ~]# iperf3 -c 192.168.2.100 -u -t 600

サーバで、-aオプションを指定せずssコマンドを実行します。-aオプションを付けるとデータ送受信していないソケットも表示されてしまうからです。iperf3がUDPパケットのデータ送受信に使用しているIPv6のソケットが表示されていることがわかります。

[root@server ~]# ss -un6
State      Recv-Q Send-Q                 Local Address:Port                                Peer Address:Port
ESTAB      0      0             [::ffff:192.168.2.100]:5201                      [::ffff:192.168.2.105]:44368

7 アドレスフィルタでソケットを絞り込む方法

アドレスフィルタを使うと、ポート番号やIPアドレスを指定して、特定のソケットだけを表示することができます。

7.1 ポート番号による絞り込み

テスト用にLISTEN状態のソケットを3つ作成します。ncコマンドのインストール、ポート開放等は、ncコマンドの使い方(ネットワーク実験の幅が広がるなぁ~) - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# nc -l 11111&
[1] 4040
[root@server ~]# nc -l 11112&
[2] 4041
[root@server ~]# nc -l 11113&
[3] 4042

初期状態を確認します。ncコマンドで作成したLISTEN状態のソケットが3つあることがわかります。

[root@server ~]# ss -lnt4
State       Recv-Q Send-Q                                         Local Address:Port                                                        Peer Address:Port
LISTEN      0      10                                                         *:11111                                                                  *:*
LISTEN      0      10                                                         *:11112                                                                  *:*
LISTEN      0      10                                                         *:11113                                                                  *:*
-snip-

11112番ポートのLISTEN状態のソケットだけを表示してみます。

[root@server ~]# ss -lnt4 'sport == :11112'
State       Recv-Q Send-Q                                         Local Address:Port                                                        Peer Address:Port
LISTEN      0      10                                                         *:11112                                                                  *:*

11112番ポート以外のLISTEN状態のソケットを表示してみます。

[root@server ~]# ss -lnt4 'sport != :11112'
State       Recv-Q Send-Q                                         Local Address:Port                                                        Peer Address:Port
LISTEN      0      10                                                         *:11111                                                                  *:*
LISTEN      0      10                                                         *:11113                                                                  *:*
LISTEN      0      128                                                        *:111                                                                    *:*
LISTEN      0      5                                              192.168.122.1:53                                                                     *:*
LISTEN      0      128                                                        *:22                                                                     *:*
LISTEN      0      128                                                127.0.0.1:631                                                                    *:*
LISTEN      0      100                                                127.0.0.1:25                                                                     *:*

11112番ポート未満のLISTEN状態のソケットを表示してみます。

[root@server ~]#  ss -lnt4 'sport < :11112'
State       Recv-Q Send-Q                                         Local Address:Port                                                        Peer Address:Port
LISTEN      0      10                                                         *:11111                                                                  *:*
LISTEN      0      128                                                        *:111                                                                    *:*
LISTEN      0      5                                              192.168.122.1:53                                                                     *:*
LISTEN      0      128                                                        *:22                                                                     *:*
LISTEN      0      128                                                127.0.0.1:631                                                                    *:*
LISTEN      0      100                                                127.0.0.1:25                                                                     *:*

11112番ポート以上のLISTEN状態のソケットを表示してみます。

[root@server ~]# ss -lnt4 'sport >= :11112'
State       Recv-Q Send-Q                                         Local Address:Port                                                        Peer Address:Port
LISTEN      0      10                                                         *:11112                                                                  *:*
LISTEN      0      10                                                         *:11113                                                                  *:*

7.2 IPアドレスによる絞り込み

サーバでncコマンドを実行します。

[root@server ~]# nc -kl 11111

クライアントでncコマンドを実行します。ncコマンドを実行すると、クライアントとサーバの間でTCPコネクションが確立されます。

[root@client ~]# nc 192.168.2.100 11111

サーバでssコマンドを実行します。このとき、サーバのIPアドレスを送信元にするソケットを表示してみます。

[root@server ~]# ss -tn4 src 192.168.2.100
State      Recv-Q Send-Q                    Local Address:Port                                   Peer Address:Port
ESTAB      0      0                         192.168.2.100:11111                                 192.168.2.105:51082
-snip-

サーバでssコマンドを実行します。このとき、クライアントのIPアドレス送信先にするソケットを表示してみます。

[root@server ~]#  ss -tn4 dst 192.168.2.105
State      Recv-Q Send-Q                    Local Address:Port                                   Peer Address:Port
ESTAB      0      0                         192.168.2.100:11111                                 192.168.2.105:51082

8 TCPの状態でソケットを絞り込む方法(STATE-FILTER)

TCPの状態によって、表示するソケットを絞り込むことができます。書式は以下のとおりです。

[root@server ~]# ss state [STATE-FILTER]

STATE-FILTERには、以下の状態を指定することができます。

  • established
  • syn-sent
  • syn-recv
  • fin-wait-1
  • fin-wait-2
  • time-wait
  • closed
  • close-wait
  • last-ack
  • closing

8.1 ESTABLISHED状態のソケットを表示する方法(state established)

ESTABLISHED状態のソケットを表示してみます。ここでは、さらにポート番号を指定して表示するESTABLISHED状態のソケットを絞り込みました。

[root@server ~]# ss state established 'sport == :22'
Netid Recv-Q Send-Q                                          Local Address:Port                                                           Peer Address:Port
tcp   0      0                                               192.168.2.100:ssh                                                            192.168.2.12:51303
tcp   0      36                                              192.168.2.100:ssh                                                            192.168.2.12:50540

8.2 TIME-WAIT状態のソケットを表示する方法(state time-wait)

TIME-WAIT状態は、先にcloseシステムコールを実行するアクティブクローズ側がとる状態です。closeシステムコールを実行するとFINパケットが送信されます。以下の図では、クライアントがcloseシステムコールを実行してFINパケットをサーバに送信しています。サーバがクライアントより先にcloseシステムコールを実行すれば、サーバが TIME-WAIT状態をとります。

            client                  server
    (アクティブクローズ側)      (パッシブクローズ側)
              |                       |
              |                       |
    close() ->|-------- FIN --------->|
              |<------- FIN + ACK ----|
       -*-    |--------- ACK -------->|
        |     |                       |
        |     |                       |
   TIME-WAIT  |                       |
      60(s)   |                       |
        |     |                       |
        |     |                       |
       -*-    |                       |

TIME-WAIT状態のソケットを確認するため、以下の手順を実行します。

サーバでncコマンドを実行します。ncコマンドのインストール方法、ポート番号開放の説明は、ncコマンドの使い方(ネットワーク実験の幅が広がるなぁ~)旧版 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# nc -kl 11111

クライアントでncコマンドを実行します。ncコマンドを実行すると、クライアントとサーバの間でTCPコネクションが確立されます。

[root@client ~]# nc 192.168.2.100 11111

ncコマンド実行時の様子を図示すると、以下のようになります。

                 client                  server
                   |                       |
                   |                       |<- nc -kl 11111
                   |                       |
 nc server 11111-> |-------- SYN --------->|
                   |<------- SYN + ACK ----|
                   |-------- ACK --------->|
                   |                       |

クライアントでssコマンドを実行して、ESTABLISHED状態のソケットを表示してみます。

[root@client ~]# ss -n state established 'dport == :11111'
Netid Recv-Q Send-Q                  Local Address:Port                                 Peer Address:Port
tcp   0      0                       192.168.2.105:51046                               192.168.2.100:11111

次に、クライアントで、Ctrl+Cを押下してncコマンドを終了します。ncコマンドを終了すると、冒頭で説明したとおり、ncプロセスがclose()システムコールを実行して、FINパケットをサーバに送信します。

[root@client ~]# nc 192.168.2.100 11111
^C

ソケットの状態がTIME-WAITであることがわかります。

[root@client ~]# ss -n state time-wait
Netid Recv-Q Send-Q                  Local Address:Port                                 Peer Address:Port
tcp   0      0                       192.168.2.105:51046                               192.168.2.100:11111

8.3 SYS-SENT状態のソケットを表示する方法(state syn-sent)

サーバでncコマンドを実行します。

[root@server ~]# nc -kl 11111

サーバでfirewall-cmdを実行します。TCPの11111番ポート宛てのパケットはDROPするというルールを設定します。firewall-cmdの使い方は、firewall-cmdの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# firewall-cmd --direct --add-rule ipv4 filter INPUT 1 -p tcp --dport 11111 -j DROP

設定したルールを確認します。

[root@server ~]# firewall-cmd --direct --get-all-rules
ipv4 filter INPUT 1 -p tcp --dport 11111 -j DROP

クライアントでncコマンドを実行します。ncコマンドを実行すると、クライアントからサーバにSYNパケットが送信されます。しかし、 firewall-cmdで宛先ポート番号が11111番のパケットを廃棄(DROP)する設定をしたので、SYNパケットが再送されます。最終的にはSYNパケットを規定回数送信して、ncコマンドが終了します。

[root@client ~]# nc 192.168.2.100 11111

SYNパケットを再送しているときに、ソケットの状態を確認します。ソケットの状態がSYS-SENTであることがわかります。

[root@client ~]# ss -n state syn-sent
Netid Recv-Q Send-Q                  Local Address:Port                                 Peer Address:Port
tcp   0      1                       192.168.2.105:51058                               192.168.2.100:11111

後始末をします。設定したルールを削除します。

[root@server ~]# firewall-cmd --direct --remove-rule ipv4 filter INPUT 1 -p tcp --dport 11111 -j DROP
success

ルールを確認します。設定したルールが削除されたことがわかります。

[root@server ~]# firewall-cmd --direct --get-all-rules
[root@server ~]#

9 時刻情報を表示する方法(-o)

-oは、ソケットの時刻に関する情報を表示するオプションです。
たとえば、TIME-WAIT状態のソケットは60秒間存在します。このとき、"-o"オプションを使うと、あとどのくらいの時間、ソケットが存在するかがわかります。"-o"オプションを使った実行例を以下に示します。

サーバでncコマンドを実行します。

[root@server ~]# nc -kl 11111

クライアントでncコマンドを実行します。

[root@client ~]# nc 192.168.2.100 11111

クライアントで、Ctrl+Cを押下してncコマンドを終了します。

[root@client ~]# nc 192.168.2.100 11111
^C

ncコマンドの終了直後、ssコマンドを実行します。右端にソケットの状態と存在時間が表示されていることがわかります。以下の例では残り時間は58秒です。

[root@client ~]# ss -no state time-wait
Netid Recv-Q Send-Q                  Local Address:Port                                 Peer Address:Port
tcp   0      0                       192.168.2.105:51062                               192.168.2.100:11111               timer:(timewait,58sec,0)

ssコマンドを実行します。残り時間が19秒になったことがわかります。

[root@client ~]# ss -no state time-wait
Netid Recv-Q Send-Q                  Local Address:Port                                 Peer Address:Port
tcp   0      0                       192.168.2.105:51062                               192.168.2.100:11111               timer:(timewait,19sec,0)

再度ssコマンドを実行します。60秒経過するとTIME-WAIT状態のソケットがなくなったことがわかります。

[root@client ~]# ss -no state time-wait
Netid Recv-Q Send-Q                  Local Address:Port                                 Peer Address:Port

10 TCPの情報を表示する方法(-i)

  • iは、ソケットに対応したTCPの情報を表示するオプションです。

10.1 LISTEN状態のソケットに対するTCPの情報表示

ssコマンドを実行します。このとき、LISTEN状態のソケットに対するTCPの情報を表示してみます。たとえば、このソケットは、輻輳回避アルゴリズムとしてcubicを使用していることがわかります。

[root@server ~]# ss -tli4
State       Recv-Q Send-Q                                       Local Address:Port                                                        Peer Address:Port
LISTEN      0      5                                            192.168.122.1:domain                                                                 *:*
         cubic rto:1000 mss:536 cwnd:10 lastsnd:28736385 lastrcv:28736385 lastack:28736385
-snip-

10.2 ESTABLISHED状態のソケットに対するTCPの情報表示

ESTABLISHED状態のソケットに対するTCPの情報を表示してみます。

[root@server ~]# ss -ti4
State       Recv-Q Send-Q                                       Local Address:Port                                                        Peer Address:Port
ESTAB       0      0                                            192.168.2.100:ssh                                                         192.168.2.12:51303
         cubic wscale:8,7 rto:237 rtt:36.201/9.223 ato:40 mss:1460 rcvmss:1424 advmss:1460 cwnd:10 bytes_acked:107889 bytes_received:34538 segs_out:1462 segs_in:1624 send 3.2Mbps lastsnd:349171 lastrcv:44805 lastack:288793 pacing_rate 6.5Mbps rcv_rtt:337403 rcv_space:29362
-snip-

11 ソケットが使用するメモリの使用状況を表示する方法(-m)

-mは、ソケットが使用する各種メモリの使用状況を表示するオプションです。

[root@server ~]# ss -tm4
State       Recv-Q Send-Q                                       Local Address:Port                                                        Peer Address:Port
ESTAB       0      0                                            192.168.2.100:ssh                                                         192.168.2.12:51303
         skmem:(r0,rb369280,t0,tb87040,f4096,w0,o0,bl0,d0)
-snip-
項目 カーネルの該当部分 意味
r sk_rmem_alloc_get(sk) カーネル受信バッファ(sk_receive_queue)に存在するパケットのサイズ(sk_buff構造体の管理領域も含む)を表す
rb sk->sk_rcvbuf カーネル受信バッファのサイズを表す。上記結果は369,280(byte)であることを表している。net.ipv4.tcp_rmem[2]まで増加可能
t sk_wmem_alloc_get(sk) カーネル送信バッファ(sk_write_queue)に存在するパケットのサイズ(sk_buff構造体の管理領域も含む)を表す
tb sk->sk_sndbuf カーネル送信バッファのサイズを表す。上記結果は87,040(byte)であることを表している。net.ipv4.tcp_wmem[2]まで増加可能
f sk->sk_forward_alloc 未稿
w sk->sk_wmem_queued 未稿
o atomic_read(&sk->sk_omem_alloc) 未稿
bl sk->sk_backlog.len 未稿

12 ソケットの詳細情報を表示する方法(-e)

-eは、ソケットのinode番号、sk構造体の先頭アドレスを表示するオプションです。

[root@server ~]# ss -ten4
State       Recv-Q Send-Q                                         Local Address:Port                                                        Peer Address:Port
ESTAB       0      0                                              192.168.2.100:22                                                          192.168.2.12:51303               timer:(keepalive,96min,0) ino:33010 sk:ffff885daed007c0 <->
ESTAB       0      36                                             192.168.2.100:22                                                          192.168.2.12:50540               timer:(on,248ms,0) ino:31753 sk:ffff885daed00000 <->

13 ネームスペースのソケットを確認する方法(-N)

ネームスペースのソケットを確認する方法を説明します。まず、"host1"という名前のネームスペースを作成します。

[root@server ~]# ip netns add host1

作成したネームスペースを確認します。

[root@server ~]# ip netns list
host1

作成したネームスペース(host1)に入ります。

[root@server ~]# ip netns exec host1 bash

host1でncコマンドを実行します。このとき、TCPの11111番ポートでListenするようにします。

[root@server ~]# nc -kl 11111

もう1つターミナルをオープンしてssコマンドを実行します。このとき、-Nオプションにはネームスペース(host1)指定します。11111番ポートでLISTEN状態のソケットが存在することがわかります。

[root@server ~]# ss -N host1 -tln4
State      Recv-Q Send-Q                                  Local Address:Port                                                 Peer Address:Port
LISTEN     0      10                                                  *:11111                                                           *:*

host1でncコマンドを終了します。そして、exitを実行して、host1から抜けます。

[root@server ~]# nc -kl 11111
^C
[root@server ~]# exit
exit

作成したネームスペースを削除します。

[root@server ~]# ip netns del host1
[root@server ~]# ip netns list
[root@server ~]#

14 Recv-Q,Send-Qの意味について

ssコマンドの実行結果にRecv-Q,Send-Qがあります。ここでは、Recv-Q,Send-Qの意味について、それぞれ確認してみます。

  • Recv-Q:ソケットの受信バッファに残っている受信データのバイト数を表します。
  • Send-Q:ソケットの送信バッファに残っている送信データのバイト数を表します。

14.1 Recv-Qについて

アプリケーションが、ソケットの受信バッファから受信データを読み出せないと、ソケットに受信データが残ったままになります。このとき、ssコマンドを実行すると、ソケットに残ったままの受信データのバイト数がRecv-Qに表示されます。ここでは、以下の手順を実行して、Recv-Qの意味を確認します。

サーバでncコマンドを実行します。

[root@server ~]#  nc -kl 11111

クライアントでncコマンドを実行すると、TCPコネクションが確立されます。

[root@client ~]# nc 192.168.2.100 11111

TCPコネクション確立後、Ctrl+Zを押下してncプロセスを停止します。

[root@server ~]#  nc -kl 11111
^Z
[1]+  停止                  nc -kl 11111

プロセスの状態を確認します。ncプロセスが停止状態(T)であることがわかります。

[root@server ~]# ps -C nc -o comm,s
COMMAND         S
nc              T

クライアントからサーバにデータを送信します。改行を含めてサーバに6バイト送信します。

[root@client ~]# nc 192.168.2.100 11111
12345

サーバでssコマンドを実行して、ソケットの状態を確認します。Recv-Qが6と表示されていることがわかります。

[root@server ~]# ss -tn4 'sport == :11111'
State      Recv-Q Send-Q   Local Address:Port                  Peer Address:Port
ESTAB      6      0        192.168.2.100:11111                192.168.2.105:51066

fgコマンドを実行して、停止していたncプロセスを起動します。

[root@server ~]# fg 1
nc -kl 11111
12345

ソケットの状態を確認します。起動したncプロセスが、ソケットの受信バッファのデータをユーザ空間に読みだしたため、Recv-Qの値が0になったことがわかります。

[root@server ~]# ss -tn4 'sport == :11111'
State      Recv-Q Send-Q   Local Address:Port                  Peer Address:Port
ESTAB      0      0        192.168.2.100:11111                192.168.2.105:51066

14.2 Send-Qについて

ソケットの送信バッファに残っているデータは、相手からACKが返ってくると削除されます。ここでは、クライアントからサーバに送信したデータのACKを、サーバのOUTPUTチェインで廃棄して、クライアントに返信されないようにして、クライアントのソケットに送信データが残ったままの状態をつくってみます。そして、その時のSend-Qの値を確認してみます。

サーバでncコマンドを実行します。

[root@server ~]# nc -kl 11111

クライアントでncコマンドを実行すると、TCPコネクションが確立されます。

[root@client ~]# nc 192.168.2.100 11111

クライアントでssコマンドを実行して、ソケットの状態を確認します。Send-Q が0と表示されていることがわかります。

[root@client ~]# ss -tn4 'dport == :11111'
State       Recv-Q Send-Q               Local Address:Port                              Peer Address:Port
ESTAB       0      0                    192.168.2.105:51068                            192.168.2.100:11111

サーバのOUTPUTチェインでACKを廃棄する設定をします。

[root@server ~]# firewall-cmd --direct --add-rule ipv4 filter OUTPUT 1 -p tcp --sport 11111 -j DROP
success

設定したルールを確認します。

[root@server ~]#  firewall-cmd --direct --get-all-rules
ipv4 filter OUTPUT 1 -p tcp --sport 11111 -j DROP

クライアントからサーバにデータを送信します。改行を含めてサーバに6バイト送信します。

[root@client ~]# nc 192.168.2.100 11111
12345

ソケットの状態を確認します。サーバからACKを受信できないため、Send-Qの値が6になっていることがわかります。

[root@client ~]# ss -tn4 'dport == :11111'
State       Recv-Q Send-Q               Local Address:Port                              Peer Address:Port
ESTAB       0      6                    192.168.2.105:51078                            192.168.2.100:11111

ルールを削除します。

[root@server ~]# firewall-cmd --direct --remove-rule ipv4 filter OUTPUT 1 -p tcp --sport 11111 -j DROP
success

ルールを確認します。設定したルールが削除されたことがわかります。

[root@server ~]#  firewall-cmd --direct --get-all-rules
[root@server ~]#

ソケットの状態を確認します。サーバからACKを受信すると、Send-Qの値が0になることがわかります。

[root@client ~]# ss -tn4 'dport == :11111'
State       Recv-Q Send-Q               Local Address:Port                              Peer Address:Port
ESTAB       0      0                    192.168.2.105:51080                            192.168.2.100:11111

Z 参考情報

私が業務や記事執筆で参考にした書籍を以下のページに記載します。
Linux技術のスキルアップをしよう! - hana_shinのLinux技術ブログ