Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
5
Help us understand the problem. What is going on with this article?
@hana_shin

nstatコマンドの使い方

More than 1 year has passed since last update.

1 nstatコマンドとは?

ネットワークの統計情報を表示するコマンドです。
CentOS6までは、ネットワークの統計情報はnetstat -sで取得しました。
CentOS7では、netstatコマンドではなくssコマンドを使うことが推奨されています。
しかし、ssコマンドはnetstat -sに相当する情報が取得できません。
一方、nstatコマンドは、netstat -sに相当する情報を表示することができます。
ここでは、nstatコマンドの使い方について説明します。

2 環境

VMware Workstation 14 Playerの仮想マシン(1台)を使いました。

OS版数
[root@server ~]# cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)

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

3 インストール方法

iprouteパッケージのインストール
[root@server ~]# yum -y install iproute
[root@server ~]# rpm -qa|grep iproute
iproute-4.11.0-14.el7.x86_64

[root@server ~]# nstat -V
nstat utility, iproute2-ss170501

4 オプション一覧

[root@server ~]# nstat -h
Usage: nstat [OPTION] [ PATTERN [ PATTERN ] ]
   -h, --help           this message
   -a, --ignore         ignore history
   -d, --scan=SECS      sample every statistics every SECS
   -j, --json           format output in JSON
   -n, --nooutput       do history only
   -p, --pretty         pretty print
   -r, --reset          reset history
   -s, --noupdate       don't update history
   -t, --interval=SECS  report average over the last SECS
   -V, --version        output version information
   -z, --zeros          show entries with zero activity

5 単純な使い方(オプション指定なし)

5.1 実行例

統計情報のカウンタが0以外のものを表示します。
左から2列目の情報が統計情報のカウンタです。
表示されるカウンタは、前回nstatコマンドを実行してからの差分を表します。

[root@server ~]# nstat
#kernel
IpInReceives                    18                 0.0
IpInDelivers                    18                 0.0
IpOutRequests                   10                 0.0
TcpInSegs                       18                 0.0
TcpOutSegs                      10                 0.0
TcpExtTCPHPHits                 6                  0.0
TcpExtTCPPureAcks               4                  0.0
TcpExtTCPHPAcks                 5                  0.0
TcpExtTCPOrigDataSent           10                 0.0
IpExtInOctets                   1098               0.0
IpExtOutOctets                  1848               0.0
IpExtInNoECTPkts                18                 0.0

5.2 差分の確認方法

クライアント、サーバの2台を用意します。クライアントでpingを実行します。
そのとき、サーバでnstatを実行して、ICMP関連統計情報のカウンタが、どのように
変化するのかを確認します。

初期情報の確認
[root@server ~]# nstat |grep Icmp
[root@server ~]#
クライアントからサーバにICMPパケットを1つ送信
[root@client ~]# ping -c 1 server
[root@server ~]# nstat |grep Icmp
IcmpInMsgs                      1                  0.0
IcmpInEchos                     1                  0.0
IcmpOutMsgs                     1                  0.0
IcmpOutEchoReps                 1                  0.0
IcmpMsgInType8                  1                  0.0
IcmpMsgOutType0                 1                  0.0
クライアントからサーバにICMPパケットを2つ送信
[root@client ~]# ping -c 2 server
[root@server ~]# nstat |grep Icmp
IcmpInMsgs                      2                  0.0
IcmpInEchos                     2                  0.0
IcmpOutMsgs                     2                  0.0
IcmpOutEchoReps                 2                  0.0
IcmpMsgInType8                  2                  0.0
IcmpMsgOutType0                 2                  0.0
ICMPパケット送信なしの場合
[root@server ~]# nstat |grep Icmp
[root@server ~]#

6 全ての統計情報を表示する方法(-z)

このオプションを指定すると、カウントが0の統計情報も含めて、すべての統計情報を表示します。

[root@server ~]# nstat -z
#kernel
IpInReceives                    91                 0.0
IpInHdrErrors                   0                  0.0
IpInAddrErrors                  0                  0.0
IpForwDatagrams                 0                  0.0
IpInUnknownProtos               0                  0.0
IpInDiscards                    0                  0.0
IpInDelivers                    84                 0.0
IpOutRequests                   80                 0.0
(中略)
IpExtInNoECTPkts                91                 0.0
IpExtInECT1Pkts                 0                  0.0
IpExtInECT0Pkts                 0                  0.0
IpExtInCEPkts                   0                  0.0

7 OS起動時からの累積値を表示する方法(-a)

OS起動時、統計情報のカウンタは0にリセットされます。
そこからの累積値を表示します。

[root@server ~]# nstat -a
#kernel
IpInReceives                    672595             0.0
IpInDelivers                    672558             0.0
IpOutRequests                   416925             0.0
IpOutNoRoutes                   16                 0.0
IcmpInMsgs                      1                  0.0
IcmpInEchos                     1                  0.0
IcmpOutMsgs                     2                  0.0
IcmpOutDestUnreachs             1                  0.0
IcmpOutEchoReps                 1                  0.0
IcmpMsgInType8                  1                  0.0
IcmpMsgOutType0                 1                  0.0
IcmpMsgOutType3                 1                  0.0
TcpActiveOpens                  24                 0.0
TcpPassiveOpens                 12                 0.0
TcpAttemptFails                 3                  0.0
TcpEstabResets                  4                  0.0
TcpInSegs                       672368             0.0
TcpOutSegs                      416751             0.0
TcpRetransSegs                  3                  0.0
TcpOutRsts                      68                 0.0
UdpInDatagrams                  189                0.0
UdpOutDatagrams                 202                0.0
Ip6InReceives                   10                 0.0
Ip6OutRequests                  11                 0.0
Ip6InMcastPkts                  10                 0.0
Ip6OutMcastPkts                 17                 0.0
Ip6InOctets                     1109               0.0
Ip6OutOctets                    728                0.0
Ip6InMcastOctets                1109               0.0
Ip6OutMcastOctets               1184               0.0
Ip6InNoECTPkts                  10                 0.0
Icmp6OutMsgs                    11                 0.0
Icmp6OutRouterSolicits          3                  0.0
Icmp6OutNeighborSolicits        2                  0.0
Icmp6OutMLDv2Reports            6                  0.0
Icmp6OutType133                 3                  0.0
Icmp6OutType135                 2                  0.0
Icmp6OutType143                 6                  0.0
TcpExtSyncookiesFailed          59                 0.0
TcpExtTW                        22                 0.0
TcpExtDelayedACKs               42                 0.0
TcpExtTCPPrequeued              14                 0.0
TcpExtTCPDirectCopyFromPrequeue 619                0.0
TcpExtTCPHPHits                 668806             0.0
TcpExtTCPHPHitsToUser           11                 0.0
TcpExtTCPPureAcks               459                0.0
TcpExtTCPHPAcks                 682                0.0
TcpExtTCPLossUndo               2                  0.0
TcpExtTCPTimeouts               3                  0.0
TcpExtTCPAbortOnData            1                  0.0
TcpExtTCPAbortOnClose           4                  0.0
TcpExtTCPRcvCoalesce            645                0.0
TcpExtTCPOFOQueue               1002               0.0
TcpExtTCPChallengeACK           2                  0.0
TcpExtTCPSYNChallenge           4                  0.0
TcpExtTCPAutoCorking            9                  0.0
TcpExtTCPSynRetrans             3                  0.0
TcpExtTCPOrigDataSent           1373               0.0
TcpExtTCPACKSkippedChallenge    2                  0.0
IpExtInMcastPkts                35                 0.0
IpExtInOctets                   40231311318        0.0
IpExtOutOctets                  21925904           0.0
IpExtInMcastOctets              1120               0.0
IpExtInNoECTPkts                27763273           0.0

8 特定の統計情報を表示する方法

ここでは、IpInReceivesの統計情報を表示してみます。

[root@server ~]# nstat IpInReceives
#kernel
IpInReceives                    5                  0.0

9 統計情報をjson形式で表示する方法

9.1 josn形式で表示する方法(-j)

[root@server ~]# nstat -j
{"kernel":{"IpInReceives":27,"IpInDelivers":26,"IpOutRequests":18,"TcpInSegs":23,"TcpOutSegs":15,"UdpInDatagrams":3,"UdpOutDatagrams":3,"TcpExtDelayedACKs":1,"TcpExtTCPHPHits":5,"TcpExtTCPPureAcks":4,"TcpExtTCPHPAcks":7,"TcpExtTCPOrigDataSent":12,"IpExtInMcastPkts":1,"IpExtInOctets":1724,"IpExtOutOctets":1724,"IpExtInMcastOctets":32,"IpExtInNoECTPkts":27}}

9.2 pretty形式で表示する方法(-p)

[root@server ~]# nstat -jp
{
    "kernel": {
        "IpInReceives": 19,
        "IpInDelivers": 18,
        "IpOutRequests": 13,
        "TcpInSegs": 16,
        "TcpOutSegs": 11,
        "UdpInDatagrams": 2,
        "UdpOutDatagrams": 2,
        "TcpExtDelayedACKs": 1,
        "TcpExtTCPHPHits": 4,
        "TcpExtTCPPureAcks": 3,
        "TcpExtTCPHPAcks": 5,
        "TcpExtTCPOrigDataSent": 9,
        "IpExtInMcastPkts": 1,
        "IpExtInOctets": 1206,
        "IpExtOutOctets": 1540,
        "IpExtInMcastOctets": 32,
        "IpExtInNoECTPkts": 19
    }
}

10 実験

ここでは、クライアントからサーバに様々なパケットを送信して、
統計情報がカウントアップすることを試してみます。

検証環境
               192.168.3.0/24
client ----------------------------- server
      .20                           .50

パケットの送信方法は、ここ(hping3コマンドの使い方)を参照ください。
随時追加予定です。

10.1 TcpInCsumErrors

TCPチェックサム異常を表す統計情報です。

ファイアウォール(netfiler)にも、TCPヘッダのチェックサムフィールドをチェックする処理があります。
その処理にひっかかってTCPパケットが廃棄されないようにするため、ファイアウォールを停止しておきます。

サーバ(ファイアウォールの停止)
[root@server ~]# systemctl stop firewalld.service

チェックサム異常に関係がある統計情報の初期値を確認する。

統計情報の確認(実験前の確認)
[root@server ~]# nstat -az|grep -i csum
IcmpInCsumErrors                0                  0.0
TcpInCsumErrors                 0                  0.0
UdpInCsumErrors                 0                  0.0
UdpLiteInCsumErrors             0                  0.0
Icmp6InCsumErrors               0                  0.0
Udp6InCsumErrors                0                  0.0
UdpLite6InCsumErrors            0                  0.0
IpExtInCsumErrors               0                  0.0

TCPヘッダのチェックサムフィールドに異常値を書き込んだパケットを1つ送信する。

クライアント
[root@client ~]# hping3 -I eth0 -c 1 -b -S -s 22222 -p 11111 server
HPING server (eth0 192.168.3.50): S set, 40 headers + 0 data bytes

--- server hping statistic ---
1 packets transmitted, 0 packets received, 100% packet loss
round-trip min/avg/max = 0.0/0.0/0.0 ms

TcpInCsumErrorsのカウンタがアップしていることがわかります。

統計情報の確認(実験後の確認)
[root@server ~]# nstat -az|grep -i csum
IcmpInCsumErrors                0                  0.0
TcpInCsumErrors               ★1                  0.0
UdpInCsumErrors                 0                  0.0
UdpLiteInCsumErrors             0                  0.0
Icmp6InCsumErrors               0                  0.0
Udp6InCsumErrors                0                  0.0
UdpLite6InCsumErrors            0                  0.0
IpExtInCsumErrors               0                  0.0

10.2 TcpExtTCPAbortOnClose

カーネル受信バッファから受信データを全て読み出さずにプロセスが終了すると、
パケット送信元にRSTパケットが送信されます。そのとき、本統計情報のカウンタがアップされます。

なお、カーネル受信バッファに残ったデータ量の確認はssコマンドで確認できます。
ssコマンドの使い方は、ここ(ssコマンドの使い方)を参照してください。

統計情報の確認(実験前の確認)
[root@server stap]# nstat -az|grep -i abort
TcpExtTCPAbortOnData            0                  0.0
TcpExtTCPAbortOnClose         ★0                  0.0
TcpExtTCPAbortOnMemory          0                  0.0
TcpExtTCPAbortOnTimeout         0                  0.0
TcpExtTCPAbortOnLinger          0                  0.0
TcpExtTCPAbortFailed            0                  0.0
実験
11111番ポートでListenします。
[root@server ~]# nc -kl 11111

クライアントからサーバ(ncプロセス)にTCPコネクションを確立します。
[root@client ~]# nc server 11111

Ctrl + zを押下して、ncプロセスを停止します。
[root@server ~]# nc -kl 11111
^Z
[1]+  停止                  nc -kl 11111

停止状態のプロセスにデータを送信します。
このデータはカーネルバッファに残ったまま、ユーザ空間のバッファには読み出されません。
[root@client ~]# nc server 11111
12345

ncプロセスを終了する。
[root@server ~]# pkill -SIGKILL nc
[1]+  強制終了            nc -kl 11111

ncプロセスを終了すると、TcpExtTCPAbortOnCloseがカウントアップしていることがわります。

統計情報の確認(実験後の確認)
[root@server stap]# nstat -az|grep -i abort
TcpExtTCPAbortOnData            0                  0.0
TcpExtTCPAbortOnClose         ★1                  0.0
TcpExtTCPAbortOnMemory          0                  0.0
TcpExtTCPAbortOnTimeout         0                  0.0
TcpExtTCPAbortOnLinger          0                  0.0
TcpExtTCPAbortFailed            0                  0.0

統計情報をカウントアップしている箇所は、2055行目(★)になります。

カーネルソース(カウントアップ該当箇所)
2007 void tcp_close(struct sock *sk, long timeout)
2008 {

2051         if (unlikely(tcp_sk(sk)->repair)) {
2052                 sk->sk_prot->disconnect(sk, 0);
2053         } else if (data_was_unread) {
2054                 /* Unread data was tossed, zap the connection. */
2055                 NET_INC_STATS_USER(sock_net(sk), LINUX_MIB_TCPABORTONCLOSE); 2056                 tcp_set_state(sk, TCP_CLOSE);
2057                 tcp_send_active_reset(sk, sk->sk_allocation);
2058         } else if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) {
2059                 /* Check zero linger _after_ checking for unread data. */
2060                 sk->sk_prot->disconnect(sk, 0);
2061                 NET_INC_STATS_USER(sock_net(sk), LINUX_MIB_TCPABORTONDATA);
2062         } else if (tcp_close_state(sk)) {
2063                 /* We FIN if the application

上記ソースの2055行目を通過したときにメッセージを表示するスクリプトを作成します。
systemtapの使い方は、ここ(SystemTapの使い方)を参照してください。

systemtapスクリプト(カウントアップの場所の確認用)
#!/usr/bin/stap

probe kernel.statement("tcp_close@net/ipv4/tcp.c:2055")
{
  printf("pp=%s\n",pp())
}

スクリプトの実行結果より、ncプロセスが終了すると、2055行目を通過していることがわかります。

systemtap実行結果
[root@server stap]# stap -v tcp.stop
Pass 1: parsed user script and 466 library scripts using 226640virt/39676res/3300shr/36504data kb, in 500usr/40sys/537real ms.
Pass 2: analyzed script: 1 probe, 1 function, 0 embeds, 0 globals using 288860virt/100156res/4124shr/98724data kb, in 410usr/130sys/572real ms.
Pass 3: translated to C into "/tmp/stapgE77fn/stap_7c1341a7e392c20c44d7b492e10804aa_1297_src.c" using 288860virt/100516res/4484shr/98724data kb, in 20usr/80sys/95real ms.
Pass 4: compiled C into "stap_7c1341a7e392c20c44d7b492e10804aa_1297.ko" in 2090usr/990sys/4900real ms.
Pass 5: starting run.
pp=kernel.statement("tcp_close@net/ipv4/tcp.c:2055")

10.3 IcmpInRedirects

ホストAが宛先BにルータYを経由してパケットを送信したとします。
しかし、宛先BはルータYよりルータZを経由した方が近いと判断されると、
ルータYからホストAにICMP Redirectメッセージが送信されます。

ホストAがICMP Redirectを受信すると、ホストAが送信するパケットは、
ルータYではなくルータZ経由で宛先Bに転送されるようになります。

ここでは、ICMP Redirectメッセージを受信したときに統計情報のカウンタが
アップされることを確認してみます。

なお、ICMP Redirectの送信方法は、ここ(hping3コマンドの使い方)を参照ください。

統計情報の確認(実験前の確認)
[root@server ~]# nstat -az IcmpInRedirects
#kernel
IcmpInRedirects                 0                  0.0
[root@client ~]# hping3 -I eth0 -1 -c 1 -C 5 -K 1 --icmp-ipsrc 192.168.3.50 --icmp-ipdst 172.16.0.10 --icmp-gw 192.168.3.
254 server
HPING server (eth0 192.168.3.50): icmp mode set, 28 headers + 0 data bytes

--- server hping statistic ---
1 packets transmitted, 0 packets received, 100% packet loss
round-trip min/avg/max = 0.0/0.0/0.0 ms
統計情報の確認(実験後の確認)
[root@server ~]# nstat -az IcmpInRedirects
#kernel
IcmpInRedirects                 1                  0.0

10.4 TcpExtSyncookiesSent

いわゆるSYN flood攻撃を受けたときにカウントアップする統計情報です。
SYN floodパケットの送信方法は、ここ(hping3コマンドの使い方)を参照してください。

サーバ側
[root@server ~]# nc -kl 11111
クライアント側
[root@client ~]# hping3 -I eth0 -a 192.168.3.200 -S -p 11111 -i u1000 server

クライアント側でhping3コマンドを実行すると、統計情報(TcpExtSyncookiesSent)の
カウンタがアップしていくことがわかります。

統計情報の確認
[root@server ~]# nstat -z|grep -i syn
TcpExtSyncookiesSent            13096              0.0
TcpExtSyncookiesRecv            0                  0.0
TcpExtSyncookiesFailed          0                  0.0
TcpExtTCPSYNChallenge           0                  0.0
TcpExtTCPSynRetrans             71                 0.0
TcpExtTCPACKSkippedSynRecv      0                  0.0

再度、nstatコマンドを実行します。
前回のnstatコマンド実行時から、TcpExtSyncookiesSentが9692増加していることがわかります。

統計情報の確認(少し時間をおいて確認)
[root@server ~]# nstat -z|grep -i syn
TcpExtSyncookiesSent            9692               0.0
TcpExtSyncookiesRecv            0                  0.0
TcpExtSyncookiesFailed          0                  0.0
TcpExtTCPSYNChallenge           0                  0.0
TcpExtTCPSynRetrans             32                 0.0
TcpExtTCPACKSkippedSynRecv      0                  0.0

SYN RECV状態のソケットを確認します。
ssコマンドの使い方は、ここ(ssコマンドの使い方)を参照ください。

ソケットの状態確認(サーバ側)
[root@server ~]# ss -n4 state syn-recv
Netid Recv-Q Send-Q                         Local Address:Port                                        Peer Address:Port
tcp   0      0                     192.168.3.50%if3461965:11111                                      192.168.3.200:34565
tcp   0      0                               192.168.3.50:11111                                      192.168.3.200:30407
tcp   0      0                     192.168.3.50%if3448365:11111                                      192.168.3.200:25083
tcp   0      0                     192.168.3.50%if3439966:11111                                      192.168.3.200:30406
tcp   0      0                     192.168.3.50%if3455765:11111                                      192.168.3.200:30264
tcp   0      0                     192.168.3.50%if3448565:11111                                      192.168.3.200:25225
tcp   0      0                               192.168.3.50:11111                                      192.168.3.200:24802
tcp   0      0                     192.168.3.50%if3447966:11111                                      192.168.3.200:24801
tcp   0      0                               192.168.3.50:11111                                      192.168.3.200:13849
tcp   0      0                               192.168.3.50:11111                                      192.168.3.200:13848
tcp   0      0                               192.168.3.50:11111                                      192.168.3.200:25227
tcp   0      0                               192.168.3.50:11111                                      192.168.3.200:29700
tcp   0      0                               192.168.3.50:11111                                      192.168.3.200:25228
tcp   0      0                               192.168.3.50:11111                                      192.168.3.200:25226
tcp   0      0                     192.168.3.50%if3454765:11111                                      192.168.3.200:29560
tcp   0      0                               192.168.3.50:11111

/var/log/messagesにも、SYN flood攻撃を受けた旨のメッセージが出力されていることがわかります。

/var/log/mesgaesの確認(サーバ側)
[root@server ~]# tail -f /var/log/messages
May 28 17:26:26 server kernel: TCP: request_sock_TCP: Possible SYN flooding on port 11111. Sending cookies.  Check SNMP counters.

Z 参考情報

Linux network metrics: why you should use nstat instead of netstat

5
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
hana_shin
写真は淡路島SAから明石海峡大橋を撮影したものです('19夏撮影)。'20年夏も3年連続で四国、大阪に行く予定でしたが、コロナ終息しないので断念。2021はぜひ行きたい!。取得済資格:ネットワークスペシャリスト、オンライン情報処理技術者。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
5
Help us understand the problem. What is going on with this article?