のぴぴのメモ

自分用のLinuxとかの技術メモ

EC2でnetconsoleを使ってカーネルメッセージを取得する

1.はじめに

EC2インスタンスで、netconsoleを使ってカーネルメッセージを別サーバに飛ばして見る方法のメモです。ncatを利用しnetconsoleサーバを一時的に作る方法と、syslogサーバに飛ばす方法の、2つを説明します。*1

2.前提

  • OS: Amazon Linux 2 LTS Candidate 2*2
  • 同一VPC内にnetconsoleのサーバとクライアントのインスタンスを立ててカーネルメッセージを取得
  • netconsoleのサーバを一時的に立てて取得する方法とsyslogに飛ばす方法の両方を試します。

3.netconsole serverを一時的に立てて取得

デバックや再現テストとかで一時的に使いたいという場合はncatコマンドで簡易的なサーバを立ててカーネルメッセージを取得することができます。以下の説明の構成概要は以下の通りです。

3.1 netconsole serverの準備

(1) security group設定

今回の例では、UDPの6666port で受診しますので、以下のようなInbound許可ルールを持つセキュリティーグループを設定して、netconsole serverインスタンスにアタッチします。

方向 タイプ プロトコル ポート ソース
Inbound custom UDPルール UDP 6666 172.31.37.0/24
(2) ncatのパッケージインストール

ncatコマンドは、nmap-ncatパッケージに含まれていますので、このパッケージをインストールします。

sudo yum -y install nmap-ncat
(3) ifconfigでネット設定を確認

ncatコマンドでlistenするIPアドレスと、そのIPアドレスが割り当てられているMACアドレス(クライアントで利用)を控えます。

$ ifconfig 
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 9001
        inet 172.31.37.224  netmask 255.255.240.0  broadcast 172.31.47.255
        inet6 fe80::410:9aff:feda:c3d2  prefixlen 64  scopeid 0x20<link>
        ether 06:10:9a:da:c3:d2  txqueuelen 1000  (Ethernet)
        RX packets 27150  bytes 35693608 (34.0 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 10838  bytes 805351 (786.4 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

今回の場合での必要情報は、以下になります。

(4)サーバ起動(フォアグランド実行)

事前にncatコマンドを実行して、netconsoleのパケットの受診ができるようにします。

ncat -l -u 172.31.37.224 6666 | tee ~/netconsole.log
  • オプションの説明
    • "-l" listenモードにするオプション
    • "-u" UDP通信を指定(デフォルトはTCP通信)

3.2 netconsole client実行

カーネルメッセージを出力するサーバの設定です。netconsoleのカーネルモジュールにオプションをつけてローディングすればOKです。一時的な利用を想定して、netconsoleモジュールを手動でロードする手順にしています。

(1)クライアントのネット設定を確認

利用するIPアドレスと、そのIPアドレスが割り当てられているデバイス名を確認します。

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 9001
        inet 172.31.37.12  netmask 255.255.240.0  broadcast 172.31.47.255
        inet6 fe80::4ca:cdff:fe50:cc8  prefixlen 64  scopeid 0x20<link>
        ether 06:ca:cd:50:0c:c8  txqueuelen 1000  (Ethernet)
        RX packets 26294  bytes 35430311 (33.7 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2764  bytes 318056 (310.6 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

確認する情報は以下になります。

(2)netconsoleのローディング

modprobeコマンドを利用してnetconsoleカーネルモジュールをローディングします。"netconsole="以下はこのカーネルモジュールのオプション設定です。

sudo modprobe netconsole 'netconsole=6666@172.31.37.12/eth0,6666@172.31.37.224/06:10:9a:da:c3:d2'

netconsoleオプションの書式は以下の通りです。*3
netconsole=[src-port]@[src-ip]/[<dev>],[tgt-port]@<tgt-ip>/[tgt-macaddr]

  • クライアント側 : [src-port]@[src-ip]/[<dev>]
    • src-port : クライアント側で利用するポート
    • src-ip: クライアント側のIPアドレス
    • <dev>: 上記src-ipが割り当てられているデバイス
  • サーバ側
    • tgt-port: サーバ側でListenしているポート
    • tgt-ip: ターゲット側でListenしているIPアドレス
    • tgt-macaddr : 上記tgt-ipが割り当てられているデバイスMACアドレス

4.syslog serverでカーネルメッセージを取得する

カーネルメッセージを定常的またはある程度の期間取得し続ける場合は、syslogサーバを立てて取得した方が良いかもしれません。ここではsyslogをUDPの514ポートでlistenする構成の手順を記載します。

4.1 rsyslogサーバの設定

(1)rsyslogにUDPでのListenを有効化

UDPの514番ポートでの受信ができるようにrsyslog.confを設定します。
/etc/rsyslog.conf:

# Provides UDP syslog reception
$ModLoad imudp
$UDPServerRun 514
(2)設定の有効化

rsyslogを再起動し、設定を有効化します。

$ sudo systemctl restart rsyslog
(3)設定確認

UDPの514番ポートでrsyslogがListenしているかnetstatで確認します。"0 0.0.0.0:syslog"(IPv4)、"0 [::]:syslog "(IPv6)が表示されればOKです。

$ netstat -l | grep syslog
udp        0      0 0.0.0.0:syslog          0.0.0.0:*
udp6       0      0 [::]:syslog             [::]:*

4.2 クライアント(netconsole)の設定

クライアント側は恒常的なメッセージ収集のため、サーバ起動時にnetconsoleが設定されるように"/etc/sysconfig/netconsole"に送信先となるsyslogサーバのIPアドレス設定を行います。

(1)送信先のsyslogサーバIPとポート設定

/etc/sysconfig/netconsole

# The IP address of the remote syslog server to send messages to
SYSLOGADDR=172.31.37.224

# The listening port of the remote syslog daemon
SYSLOGPORT=514
(2)netconsoleのサービスの再起動

netconsole.serviceを再起動し設定を反映させます。
またOS再起動後も反映されるようい"systemctl enable・・・"でサービスを有効化します。

$ sudo systemctl restart netconsole.service
$ sudo systemctl enable netconsole.service

*1:ちなみに、なんでこんな調査をしたかというと、m4インスタンスlinuxでのテストで、"sysctl -w kernel.panic=0"(パニック発生時にハングする)を設定してハングさせたいという話があったのですが、panic発動させると設定に従わずとどうしても再起動してOSがあがってくる (panic=0が機能しない)という話があり調べたものです。その話はまた別途書きたいと思います。

*2:未検証ですが、Amazon Linux1でも基本一緒だと思います

*3:カーネルソースコードのDocument/netにあるnetconsole.txtに説明があります