netconsoleを利用したkernel panic時のstack trace取得

こんにちは、HACKNOTEのJunya.kです。
EC2インスタンス上のLINUXにおいてnetconsoleを利用してkernel panic時のstack traceを取得する方法についての記事です。

なぜそんなことをするのか?

カーネルクラッシュした際の挙動をログとして確認するには、一般にカーネルダンプ、kdumpが使われます。
ところが、EC2インスタンス上のLINUXではkdumpが使えません。
これではクラッシュした際にクラッシュ原因がわからず困ってしまいます。

そこで、この記事ではnetconsoleを利用してクラッシュ時の挙動を見ていきます。

環境構築

1.EC2インスタンスを2つ立てる(Amazon Linux 2)

2.ポート開放

後に使用するncコマンドではUDP接続を利用します。
UDPのポートを開放しておきましょう。ここではUDP11112番ポートを開放したものとします。
インスタンスのセキュリティグループからインバウンドを編集し、UDPについてのルールを追加します。

3.ncコマンドをインストールする

両インスタンスでncコマンドをインストールします。

$ sudo su -
# yum install nc nmap
# nc --version
Ncat: Version 7.50 ( https://nmap.org/ncat )

ncコマンドのテスト

netconsoleを利用する際にUDP接続を行うので、UDP接続の確認をします。

サーバー

11112番ポートで待ち受けます。

# nc -u -l 11112 
12345

クライアント

# nc -u [サーバー側IPアドレス] 11112
12345

netconsoleによるクラッシュの監視

受信側

UDP通信で待ち受けます。

# nc -u -l 11112

送信側

net consoleを利用します。以下で指定するIPアドレスはプライベートIPアドレスであることに気をつけて下さい。

# modprobe netconsole 'netconsole=[server port]@[server IP address]/eth0,[client port]@[client IP address]/[client mac address]'
# echo hoge > /dev/kmsg
# echo c > /proc/sysrq-trigger

受信側

# nc -u -l 11112
[   78.727493] hoge
[   87.581579] sysrq: SysRq : Trigger a crash
[   87.585239] BUG: unable to handle kernel NULL pointer dereference at           (null)
[   87.590923] IP: sysrq_handle_crash+0x12/0x20
[   87.594216] PGD 800000003d121067 P4D 800000003d121067 PUD 3d122067 PMD 0 
[   87.599247] Oops: 0002 [#1] SMP PTI
[   87.602300] Modules linked in: netconsole sunrpc mousedev sb_edac evdev button psmouse ena ip_tables x_tables xfs libcrc32c crc32_pclmul crc32c_intel ghash_clmulni_intel pcbc ata_piix libata aesni_intel aes_x86_64 crypto_simd glue_helper xen_blkfront cryptd scsi_mod dm_mirror dm_region_hash dm_log dm_mod dax ipv6 crc_ccitt autofs4
[   87.622502] CPU: 0 PID: 3289 Comm: bash Not tainted 4.14.88-88.76.amzn2.x86_64 #1
[   87.629032] Hardware name: Xen HVM domU, BIOS 4.2.amazon 08/24/2006
[   87.634055] task: ffff8880389f0000 task.stack: ffffc90000430000
[   87.639023] RIP: 0010:sysrq_handle_crash+0x12/0x20
[   87.643260] RSP: 0018:ffffc90000433df8 EFLAGS: 00010286
[   87.647791] RAX: ffffffff81424290 RBX: 0000000000000063 RCX: 0000000000000000
[   87.653495] RDX: 0000000000000000 RSI: ffff88803e2164d8 RDI: 0000000000000063
[   87.659125] RBP: ffffffff81f5fa20 R08: 00000000000001ab R09: ffff88803cb19000
[   87.664895] R10: 0000000000000001 R11: 0000000000000040 R12: 0000000000000007
[   87.670610] R13: 0000000000000000 R14: 0000000000d92780 R15: 0000000000000000
[   87.676417] FS:  00007f8c7c293740(0000) GS:ffff88803e200000(0000) knlGS:0000000000000000
[   87.683300] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   87.688137] CR2: 0000000000000000 CR3: 00000000386e4004 CR4: 00000000001606f0
[   87.694119] Call Trace:
[   87.696875]  __handle_sysrq+0x84/0x130
[   87.700264]  write_sysrq_trigger+0x2b/0x30
[   87.704053]  proc_reg_write+0x40/0x70
[   87.707747]  __vfs_write+0x36/0x160
[   87.711121]  ? __audit_syscall_entry+0xbc/0x110
[   87.715391]  vfs_write+0xad/0x1a0
[   87.718763]  SyS_write+0x52/0xc0
[   87.721790]  do_syscall_64+0x67/0x100
[   87.725127]  entry_SYSCALL_64_after_hwframe+0x3d/0xa2
[   87.729443] RIP: 0033:0x7f8c7b97b894
[   87.732705] RSP: 002b:00007ffd8eb24f88 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
[   87.739099] RAX: ffffffffffffffda RBX: 0000000000000002 RCX: 00007f8c7b97b894
[   87.744807] RDX: 0000000000000002 RSI: 0000000000d92780 RDI: 0000000000000001
[   87.750521] RBP: 0000000000d92780 R08: 000000000000000a R09: 0000000000d891f0
[   87.756314] R10: 000000000000000a R11: 0000000000000246 R12: 0000000000000002
[   87.762149] R13: 0000000000000001 R14: 00007f8c7bc46760 R15: 0000000000000002
[   87.767962] Code: 41 5d 41 5e 41 5f e9 2e e0 cf ff 48 89 ef e8 96 fb ff ff e9 ae fe ff ff 90 0f 1f 44 00 00 c7 05 e9 dd 0a 01 01 00 00 00 0f ae f8 <c6> 04 25 00 00 00 00 01 c3 0f 1f 44 00 00 0f 1f 44 00 00 53 8d 
[   87.782860] RIP: sysrq_handle_crash+0x12/0x20 RSP: ffffc90000433df8
[   87.788156] CR2: 0000000000000000
[   87.791859] ---[ end trace 5559b4f4c3a2fde0 ]---
[   87.796108] Kernel panic - not syncing: Fatal exception
[   87.800586] Kernel Offset: disabled

これでkernel panic時のstack traceを取得できることが確認できました。