[Linux] 使用 netconsole 將 kernel message 傳送至遠端機器
最近在公司 Debug Hacks 的讀書會報告,用到了 netconsole 這個東西,
讓遠端 Linux 機器的 kernel 訊息可以透過網路傳出來,
下面記錄一下步驟囉~
Linux Configure Netconsole To Log Messages Over UDP Network
stackoverflow: How to start Syslogd server on Mac to accept remote logging messages?
1. 設定 netconsole 的傳送端 (Linux VM)
在 CentOS 7 上面,編輯 /etc/sysconfig/netconsole 這個檔案,
將 SYSLOGADDR 和 SYSLOGPORT 設定好,同時把註解 (#) 拿掉~
在本例中是設定成產生 Oops 訊息時,會傳送到遠端 192.168.1.106 的 514 (syslog) port:
# This is the configuration file for the netconsole service. By starting # this service you allow a remote syslog daemon to record console output # from this system. # The local port number that the netconsole module will use # LOCALPORT=6666 # The ethernet device to send console messages out of (only set this if it # can't be automatically determined) # DEV= # The IP address of the remote syslog server to send messages to SYSLOGADDR=192.168.1.106 # The listening port of the remote syslog daemon SYSLOGPORT=514 # The MAC address of the remote syslog server (only set this if it can't # be automatically determined) # SYSLOGMACADDR=
設定好之後,執行下面的指令重新啟動 netconsole:
/etc/init.d/netconsole restart
這時在 /var/log/messages 裡面,可以看到跟 netconsole 有關的訊息,
可以確認一下剛設定的 IP/port 是否都正確:
Sep 17 01:41:55 localhost systemd: Starting SYSV: Initializes network console logging... Sep 17 01:41:55 localhost netconsole:: inserting netconsole module with arguments netconsole=6666@192.168.1.108/enp0s3,514@192.168.1.106/88:1F:A1:22:AA:8E Sep 17 01:41:55 localhost kernel: netpoll: netconsole: local port 6666 Sep 17 01:41:55 localhost netconsole: Initializing netconsole [ OK ] Sep 17 01:41:55 localhost kernel: netpoll: netconsole: local IPv4 address 192.168.1.108 Sep 17 01:41:55 localhost kernel: netpoll: netconsole: interface 'enp0s3' Sep 17 01:41:55 localhost kernel: netpoll: netconsole: remote port 514 Sep 17 01:41:55 localhost kernel: netpoll: netconsole: remote IPv4 address 192.168.1.106 Sep 17 01:41:55 localhost kernel: netpoll: netconsole: remote ethernet address 88:1f:a1:22:aa:8e Sep 17 01:41:55 localhost kernel: console [netcon0] enabled Sep 17 01:41:55 localhost kernel: netconsole: network logging started Sep 17 01:41:55 localhost systemd: Started SYSV: Initializes network console logging.
2. 設定 netconsole 的接收端 (Mac)
在 Mac 上已經有 syslogd 了,不過預設是不接收遠端來的 syslog 請求,
可以執行下面的指令,讓 syslogd 可以接受外部的連線:
cd /System/Library/LaunchDaemons sudo /usr/libexec/PlistBuddy -c "add :Sockets:NetworkListener dict" com.apple.syslogd.plist sudo /usr/libexec/PlistBuddy -c "add :Sockets:NetworkListener:SockServiceName string syslog" com.apple.syslogd.plist sudo /usr/libexec/PlistBuddy -c "add :Sockets:NetworkListener:SockType string dgram" com.apple.syslogd.plist sudo launchctl unload com.apple.syslogd.plist sudo launchctl load com.apple.syslogd.plist
3. 在 Linux VM 上產生一個 Oops 訊息
在 Linux VM 上產生一個 kernel 訊息後,這訊息就會透過 netconsole 傳出來,
傳到指定好的接收端 (本例中是 Mac 上的 syslog port)~
下面利用 sysrq-trigger,直接送一個無效的字元出來:
echo h > /proc/sysrq-trigger
這樣就會產生 kernel 訊息,說明有哪些按鍵可以用,
這個訊息除了顯示在 Linux VM 上的 console 外,還會透過 netconsole 傳送到 Mac 端的 syslog port:
[ 7711.791849] SysRq : HELP : loglevel(0-9) reboot(b) crash(c) terminate-all-tasks(e) memory-full-oom-kill(f) kill-all-tasks(i) thaw-filesystems(j) sak(k) show-backtrace-all-active-cpus(l) show-memory-usage(m) nice-all-RT-tasks(n) poweroff(o) show-registers(p) show-all-timers(q) unraw(r) sync(s) show-task-states(t) unmount(u) show-blocked-tasks(w) dump-ftrace-buffer(z)
不過在我的測試過程中,似乎 Mac 上的 syslogd 接收不到 (或者是不顯示出來) Linux 端的訊息,
可是如果用 netcat 聽在 514 port,卻又看得到訊息,
因此問題究竟在哪裡,還要查查看…