<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Watchdog on inetshell</title><link>https://inet.sh/en/tags/watchdog/</link><description>Recent content in Watchdog on inetshell</description><generator>Hugo</generator><language>en</language><lastBuildDate>Mon, 05 Oct 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://inet.sh/en/tags/watchdog/index.xml" rel="self" type="application/rss+xml"/><item><title>A LUKS server that hangs and never comes back: watchdog, SSH unlock with dropbear, and netconsole</title><link>https://inet.sh/en/posts/linux/luks-ssh-unlock-dropbear-watchdog-netconsole/</link><pubDate>Mon, 05 Oct 2026 00:00:00 +0000</pubDate><guid>https://inet.sh/en/posts/linux/luks-ssh-unlock-dropbear-watchdog-netconsole/</guid><description>An Ubuntu host with a LUKS-encrypted root freezes and stays dead for hours: no watchdog, kdump stuck asking for the passphrase, and every reboot stops at the prompt. A hardware watchdog (iTCO) driven by systemd, panics and lockups that reboot, dropbear-initramfs to type the passphrase over SSH, and netconsole so the crash log survives on another machine.</description><content:encoded><![CDATA[<h2 id="tldr">TL;DR</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1"># 1. Hardware watchdog: if the kernel freezes, the chipset resets the machine</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> iTCO_wdt &gt; /etc/modules-load.d/iTCO_wdt.conf
</span></span><span class="line"><span class="cl">mkdir -p /etc/systemd/system.conf.d
</span></span><span class="line"><span class="cl"><span class="nb">printf</span> <span class="s1">&#39;[Manager]\nRuntimeWatchdogSec=60s\nRebootWatchdogSec=5min\n&#39;</span> &gt; /etc/systemd/system.conf.d/90-watchdog.conf
</span></span><span class="line"><span class="cl"><span class="nb">printf</span> <span class="s1">&#39;kernel.panic = 10\nkernel.softlockup_panic = 1\nkernel.hardlockup_panic = 1\nkernel.printk = 5 4 1 7\n&#39;</span> &gt; /etc/sysctl.d/90-crash-recovery.conf
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 2. SSH in the initramfs to type the LUKS passphrase</span>
</span></span><span class="line"><span class="cl">apt install dropbear-initramfs
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s1">&#39;DROPBEAR_OPTIONS=&#34;-p 2222 -s -j -k -I 300 -c cryptroot-unlock&#34;&#39;</span> &gt; /etc/dropbear/initramfs/dropbear.conf
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s1">&#39;IP=192.168.1.20::192.168.1.1:255.255.255.0:server1:eno1:off&#39;</span> &gt; /etc/initramfs-tools/conf.d/90-remote-unlock
</span></span><span class="line"><span class="cl"><span class="c1"># public keys in /etc/dropbear/initramfs/authorized_keys</span>
</span></span><span class="line"><span class="cl">update-initramfs -u
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 3. After a reboot, from the LAN</span>
</span></span><span class="line"><span class="cl">ssh -p <span class="m">2222</span> root@192.168.1.20      <span class="c1"># asks for the passphrase, boot continues</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Plus netconsole to another machine to learn <strong>why</strong> it went down (below).</p>
<h2 id="the-problem">The problem</h2>
<p>A host with a LUKS-encrypted root (passphrase only, no TPM) freezes mid-morning. No power cut, the journal stops mid-line, no errors. Nobody notices until someone walks over and powers it on by hand: six hours down.</p>
<p>Three things stretch the outage and erase the evidence:</p>
<table>
  <thead>
      <tr>
          <th>Problem</th>
          <th>Consequence</th>
          <th>Fix</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>No watchdog</td>
          <td>A frozen kernel waits for a human</td>
          <td>Hardware watchdog petted by systemd</td>
      </tr>
      <tr>
          <td>kdump active (Ubuntu default) with <code>kernel.panic=0</code></td>
          <td>The capture kernel needs the passphrase to write <code>/var/crash</code>, boots with no USB and no network, and waits forever</td>
          <td>Turn kdump off, <code>kernel.panic=10</code></td>
      </tr>
      <tr>
          <td>Passphrase-only LUKS root</td>
          <td>Any unattended reboot stops at the prompt</td>
          <td>dropbear in the initramfs</td>
      </tr>
      <tr>
          <td>A hard freeze leaves nothing in the local journal</td>
          <td>No way to find the cause</td>
          <td>netconsole to another machine</td>
      </tr>
  </tbody>
</table>
<h2 id="1-hardware-watchdog-and-reboot-on-panic">1. Hardware watchdog and reboot on panic</h2>
<p>On Intel machines the chipset watchdog is <code>iTCO_wdt</code>. Ubuntu blacklists every watchdog driver, but that only stops automatic loading; loading it by name works:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="nb">echo</span> iTCO_wdt &gt; /etc/modules-load.d/iTCO_wdt.conf
</span></span><span class="line"><span class="cl">modprobe iTCO_wdt
</span></span><span class="line"><span class="cl">cat /sys/class/watchdog/watchdog0/identity      <span class="c1"># iTCO_wdt</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>systemd pets it. If PID 1 stops petting for 60 s (frozen kernel), the chipset resets the machine. <code>RebootWatchdogSec</code> also bounds shutdowns that hang:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="c1"># /etc/systemd/system.conf.d/90-watchdog.conf</span>
</span></span><span class="line"><span class="cl"><span class="k">[Manager]</span>
</span></span><span class="line"><span class="cl"><span class="na">RuntimeWatchdogSec</span><span class="o">=</span><span class="s">60s</span>
</span></span><span class="line"><span class="cl"><span class="na">RebootWatchdogSec</span><span class="o">=</span><span class="s">5min</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">systemctl daemon-reexec
</span></span><span class="line"><span class="cl">systemctl show -p WatchdogDevice -p RuntimeWatchdogUSec
</span></span><span class="line"><span class="cl"><span class="c1"># WatchdogDevice=/dev/watchdog0  RuntimeWatchdogUSec=1min</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>So that panics and lockups reboot instead of hanging:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="c1"># /etc/sysctl.d/90-crash-recovery.conf</span>
</span></span><span class="line"><span class="cl"><span class="na">kernel.panic</span> <span class="o">=</span> <span class="s">10</span>
</span></span><span class="line"><span class="cl"><span class="na">kernel.softlockup_panic</span> <span class="o">=</span> <span class="s">1</span>
</span></span><span class="line"><span class="cl"><span class="na">kernel.hardlockup_panic</span> <span class="o">=</span> <span class="s">1</span>
</span></span><span class="line"><span class="cl"><span class="na">kernel.printk</span> <span class="o">=</span> <span class="s">5 4 1 7</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><code>kernel.printk = 5 …</code> raises the console level so warnings also go out over netconsole (step 3). <code>hardlockup_panic</code> needs the NMI watchdog, which is on by default.</p>
<p><strong>kdump</strong>: with an encrypted root and no automatic unlock, its capture kernel cannot write the dump and sits at the passphrase prompt. Turn it off:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">sed -i <span class="s1">&#39;s/^USE_KDUMP=.*/USE_KDUMP=0/&#39;</span> /etc/default/kdump-tools
</span></span><span class="line"><span class="cl">systemctl disable --now kdump-tools
</span></span><span class="line"><span class="cl">kdump-config unload
</span></span></code></pre></td></tr></table>
</div>
</div><p>And get back the memory it reserves. <code>kdump-tools.cfg</code> adds <code>crashkernel=</code> from <code>/etc/default/grub.d/</code>, and those files are read <strong>in alphabetical order</strong>: a file that strips it has to sort after it (<code>zz-</code>, not <code>99-</code>):</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">cat &gt; /etc/default/grub.d/zz-no-crashkernel.cfg <span class="s">&lt;&lt;&#39;EOF&#39;
</span></span></span><span class="line"><span class="cl"><span class="s">GRUB_CMDLINE_LINUX_DEFAULT=&#34;$(printf &#39;%s&#39; &#34;$GRUB_CMDLINE_LINUX_DEFAULT&#34; | sed -E &#39;s/(^| )crashkernel=[^ ]*//g; s/^ +//&#39;)&#34;
</span></span></span><span class="line"><span class="cl"><span class="s">EOF</span>
</span></span><span class="line"><span class="cl">update-grub
</span></span><span class="line"><span class="cl">grep -c crashkernel /boot/grub/grub.cfg     <span class="c1"># 0</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>That way a package update cannot bring it back.</p>
<h2 id="2-unlock-luks-over-ssh-with-dropbear">2. Unlock LUKS over SSH with dropbear</h2>
<p><code>dropbear-initramfs</code> puts a minimal SSH server in the initramfs, started <strong>before</strong> the disk is opened:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">apt install dropbear-initramfs
</span></span></code></pre></td></tr></table>
</div>
</div><p>Options in <code>/etc/dropbear/initramfs/dropbear.conf</code> (on older Debian/Ubuntu the file is <code>/etc/dropbear-initramfs/config</code>):</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="nv">DROPBEAR_OPTIONS</span><span class="o">=</span><span class="s2">&#34;-p 2222 -s -j -k -I 300 -c cryptroot-unlock&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">IFDOWN</span><span class="o">=</span><span class="s2">&#34;*&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><table>
  <thead>
      <tr>
          <th>Option</th>
          <th>Why</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>-p 2222</code></td>
          <td>A different port from the real sshd: the host key differs, so <code>known_hosts</code> does not clash</td>
      </tr>
      <tr>
          <td><code>-s</code></td>
          <td>No passwords, keys only</td>
      </tr>
      <tr>
          <td><code>-j -k</code></td>
          <td>No port forwarding</td>
      </tr>
      <tr>
          <td><code>-I 300</code></td>
          <td>Drops idle sessions after 5 min</td>
      </tr>
      <tr>
          <td><code>-c cryptroot-unlock</code></td>
          <td>Every login runs <code>cryptroot-unlock</code> and nothing else</td>
      </tr>
      <tr>
          <td><code>IFDOWN=&quot;*&quot;</code></td>
          <td>When done, takes the NIC down and flushes it so the real system configures it from scratch (matters if a bridge sits on top)</td>
      </tr>
  </tbody>
</table>
<p>Restricted public keys, one per line:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1"># /etc/dropbear/initramfs/authorized_keys  (mode 0600)</span>
</span></span><span class="line"><span class="cl">no-port-forwarding,no-agent-forwarding,no-X11-forwarding ssh-ed25519 AAAA... laptop
</span></span><span class="line"><span class="cl">no-port-forwarding,no-agent-forwarding,no-X11-forwarding ssh-ed25519 AAAA... phone
</span></span></code></pre></td></tr></table>
</div>
</div><p>Initramfs network with a static IP, without touching GRUB (kernel <code>ip=</code> syntax: <code>client::gateway:netmask:hostname:device:autoconf</code>):</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1"># /etc/initramfs-tools/conf.d/90-remote-unlock</span>
</span></span><span class="line"><span class="cl"><span class="nv">IP</span><span class="o">=</span>192.168.1.20::192.168.1.1:255.255.255.0:server1:eno1:off
</span></span></code></pre></td></tr></table>
</div>
</div><p>Use the physical NIC. If the system has a bridge (<code>br0</code>), it does not exist yet in the initramfs: name the interface that is its uplink.</p>
<p>Rebuild and check that everything made it in:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">update-initramfs -u
</span></span><span class="line"><span class="cl">lsinitramfs /boot/initrd.img-<span class="k">$(</span>uname -r<span class="k">)</span> <span class="p">|</span> grep -E <span class="s1">&#39;sbin/dropbear$|cryptroot-unlock$|90-remote-unlock|authorized_keys&#39;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="unlock">Unlock</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">ssh -p <span class="m">2222</span> root@192.168.1.20
</span></span><span class="line"><span class="cl"><span class="c1"># Please unlock disk dm_crypt-0:</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Type the passphrase; the session closes by itself and the boot continues. The local keyboard still works in parallel: whichever answers first wins. The first time, compare the host key with the ones in <code>/etc/dropbear/initramfs/dropbear_*_host_key</code>:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">dropbearkey -y -f /etc/dropbear/initramfs/dropbear_ed25519_host_key <span class="p">|</span> grep -o <span class="s1">&#39;SHA256:.*&#39;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="3-netconsole-make-the-crash-log-survive">3. netconsole: make the crash log survive</h2>
<p>A hard freeze gets nothing to disk. netconsole sends kernel messages over UDP to another machine from inside the kernel (netpoll), so they get out even when userspace is already dead.</p>
<p>On the host, through configfs and <strong>after</strong> the interface exists. The module option form (<code>netconsole=…</code> on the command line) runs before NetworkManager builds a bridge and is useless here:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">modprobe netconsole
</span></span><span class="line"><span class="cl">mountpoint -q /sys/kernel/config <span class="o">||</span> mount -t configfs none /sys/kernel/config
</span></span><span class="line"><span class="cl"><span class="nv">T</span><span class="o">=</span>/sys/kernel/config/netconsole/log-host
</span></span><span class="line"><span class="cl">mkdir <span class="nv">$T</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> br0          &gt; <span class="nv">$T</span>/dev_name
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> 192.168.1.20 &gt; <span class="nv">$T</span>/local_ip
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> 192.168.1.30 &gt; <span class="nv">$T</span>/remote_ip
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="m">6666</span>         &gt; <span class="nv">$T</span>/remote_port
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="m">1</span>            &gt; <span class="nv">$T</span>/enabled
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;&lt;4&gt;netconsole: </span><span class="k">$(</span>hostname<span class="k">)</span><span class="s2"> streaming&#34;</span> &gt; /dev/kmsg
</span></span></code></pre></td></tr></table>
</div>
</div><p>Put it in a <code>oneshot</code> service with <code>After=</code> and <code>BindsTo=</code> on <code>sys-subsystem-net-devices-br0.device</code> so it is set up on every boot. If the bridge is recreated while the system is up, the target is not re-armed by itself: restart the service.</p>
<p>On the other machine (physical, on the same segment: a VM on the same host goes down with it), a <code>socat</code> receiver that only accepts that host and writes to the journal:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="c1"># /etc/systemd/system/netconsole-server1.service</span>
</span></span><span class="line"><span class="cl"><span class="k">[Unit]</span>
</span></span><span class="line"><span class="cl"><span class="na">Description</span><span class="o">=</span><span class="s">netconsole receiver for server1</span>
</span></span><span class="line"><span class="cl"><span class="na">After</span><span class="o">=</span><span class="s">network-online.target</span>
</span></span><span class="line"><span class="cl"><span class="na">Wants</span><span class="o">=</span><span class="s">network-online.target</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">[Service]</span>
</span></span><span class="line"><span class="cl"><span class="na">ExecStart</span><span class="o">=</span><span class="s">/usr/bin/socat -u UDP-RECV:6666,bind=192.168.1.30,range=192.168.1.20/32 STDOUT</span>
</span></span><span class="line"><span class="cl"><span class="na">StandardOutput</span><span class="o">=</span><span class="s">journal</span>
</span></span><span class="line"><span class="cl"><span class="na">SyslogIdentifier</span><span class="o">=</span><span class="s">netconsole-server1</span>
</span></span><span class="line"><span class="cl"><span class="na">Restart</span><span class="o">=</span><span class="s">always</span>
</span></span><span class="line"><span class="cl"><span class="na">DynamicUser</span><span class="o">=</span><span class="s">yes</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">[Install]</span>
</span></span><span class="line"><span class="cl"><span class="na">WantedBy</span><span class="o">=</span><span class="s">multi-user.target</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">journalctl -t netconsole-server1 --since <span class="s2">&#34;-12h&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>The <code>netconsole: … streaming</code> line marks each boot; what comes before the last marker is the end of the previous boot. Look for <code>Kernel panic</code>, <code>soft lockup</code>, <code>hard LOCKUP</code>, <code>NVRM: Xid</code>, or PCIe/Thunderbolt AER errors.</p>
<h2 id="test-it">Test it</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">cat /sys/class/watchdog/watchdog0/<span class="o">{</span>identity,state,timeout<span class="o">}</span>   <span class="c1"># iTCO_wdt active 60</span>
</span></span><span class="line"><span class="cl">cat /sys/kernel/kexec_crash_loaded                           <span class="c1"># 0: kdump off</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;&lt;4&gt;netconsole test </span><span class="k">$(</span>date +%T<span class="k">)</span><span class="s2">&#34;</span> &gt; /dev/kmsg            <span class="c1"># shows up on the receiver</span>
</span></span><span class="line"><span class="cl">systemctl reboot                                             <span class="c1"># then unlock over SSH</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>The full test, <strong>only with someone ready to unlock</strong>: <code>echo c &gt; /proc/sysrq-trigger</code> triggers a panic. Its text should reach the receiver, the host reboots after 10 s and waits at the LUKS prompt.</p>
<h2 id="traps">Traps</h2>
<ul>
<li><strong>The previous kernel has no dropbear.</strong> <code>update-initramfs -u</code> only rebuilds the running kernel&rsquo;s initramfs. If you boot the previous kernel from GRUB (the usual way out when a new one fails), its initramfs may predate dropbear: only the keyboard works there. Check with <code>lsinitramfs</code> or rebuild it with <code>update-initramfs -u -k &lt;version&gt;</code>.</li>
<li><strong>LAN only.</strong> There is no VPN or Tailscale in the initramfs. To unlock from outside, advertise the host&rsquo;s IP (<code>/32</code>) from a subnet router that runs on <strong>another</strong> machine on the LAN.</li>
<li><strong>&ldquo;Host key changed&rdquo;.</strong> Port 2222 has different keys from the normal sshd; the <code>known_hosts</code> entry is <code>[192.168.1.20]:2222</code>.</li>
<li><strong>The wrong NIC.</strong> If the cable is on a USB adapter or a dock and the IP is on the onboard NIC, the initramfs has no network. At the local console, look for <code>IP-Config: eno1 …</code>.</li>
<li><strong>netconsole does not show up in the host&rsquo;s own <code>tcpdump</code></strong>: netpoll bypasses the capture taps. Look on the receiver.</li>
<li><strong>Only messages below <code>console_loglevel</code> go out</strong>: with <code>5</code>, warnings and worse, never <code>info</code> or <code>debug</code>.</li>
<li><strong>Watchdog false positives</strong>: if systemd goes 60 s without petting it, the box reboots and you type the passphrase again. For kernel debugging, remove the <code>.conf</code> and run <code>systemctl daemon-reexec</code>.</li>
<li><strong>TPM2/clevis</strong> would unlock by itself, but also for anyone who walks off with the machine and powers it on. Here the passphrase over SSH won.</li>
</ul>
<h2 id="see-also">See also</h2>
<ul>
<li><a href="/en/posts/linux/luks-header-backup-keys/">LUKS: back up and restore the header, and add, change or remove keys</a></li>
<li><a href="/en/posts/linux/ssh-agent-systemd/">Persistent ssh-agent with systemd</a></li>
</ul>
]]></content:encoded></item></channel></rss>