Files
pxe-server/playbook/pxe-server-helpers/smb-soft-reset.sh
cproudlock d3a0f90ca1 Re-imaging the same PC: clear its stale SMB/conntrack state every time
A PC whose imaging failed and is re-imaged gets the same IP, and the
server still held state from the dead run, so net use failed (System
error 53). The April fix (18537ac) did not cover it:

- The dnsmasq hook only acted on 'add'/'del'. A re-image comes back to the
  existing lease, which dnsmasq reports as 'old', and only when the
  hostname/MAC changed. Now dnsmasq sets script-on-renewal, and the hook
  clears state on 'old' when the request comes from PXE firmware or iPXE
  (vendor class PXEClient), i.e. the machine just network-booted. A
  Windows lease renewal (MSFT 5.0) is left alone.
- The 1 h conntrack timeout never applied after a reboot: systemd-sysctl
  runs before ufw loads nf_conntrack, so the keys did not exist and the
  5-day default stayed. /etc/modules-load.d/pxe-conntrack.conf loads it
  first.
- smb-soft-reset.sh flushed neighbours on br-pxe, which no longer exists.

Live 2026-10-14. Hook tested on the server with an unused IP: network-boot
renewal clears, Windows renewal and no vendor class do not, add clears.
2026-10-14 17:19:33 -04:00

88 lines
3.2 KiB
Bash
Executable File

#!/bin/bash
# smb-soft-reset.sh - progressive soft recovery for the WinPE re-image
# "System error 53 has occurred" issue without having to power-cycle the box.
# Error 53 = network path not found; the TCP connect to :445 never
# completes. Root cause is almost always stale kernel netfilter conntrack
# state that systemctl restart smbd doesn't touch. Full reboot clears it;
# this script tries to do the same without the reboot.
#
# Run as root (sudo) when the issue happens. It applies increasingly
# aggressive fixes and pauses between steps so you can retry the WinPE
# re-image without closing this shell.
#
# Step 1: reload smbd config (cheapest, may clear cached state)
# Step 2: restart nmbd (NetBIOS daemon - separate from smbd)
# Step 3: restart smbd (full smbd restart, kills all child sessions)
# Step 4: kill any leftover smbd child processes that survived restart
# Step 5: flush conntrack for 172.16.9.0/24 (kernel connection tracking)
# Step 6: flush ARP / neighbour cache
# Step 7: drop TCP sockets on port 445 via ss -K
# Step 8: restart dnsmasq (DHCP/TFTP state as a last resort before reboot)
set -e
pause() {
echo
echo "----------------------------------------------------------------"
echo "$1"
echo " Try your WinPE re-image NOW. Did it work?"
echo " [Enter] to continue to next step, Ctrl+C to stop."
echo "----------------------------------------------------------------"
read -r _
}
if [ "$EUID" -ne 0 ]; then
echo "Run as root: sudo $0" >&2
exit 1
fi
echo "=== Step 1/8: reload smbd config ==="
systemctl reload smbd 2>&1 || true
pause "Step 1 done"
echo "=== Step 2/8: restart nmbd ==="
systemctl restart nmbd 2>&1 || true
pause "Step 2 done"
echo "=== Step 3/8: restart smbd ==="
systemctl restart smbd 2>&1
pause "Step 3 done"
echo "=== Step 4/8: kill any leftover smbd children ==="
# systemctl restart should take care of this with KillMode=control-group,
# but belt + suspenders since the issue has been surviving restarts.
pkill -9 -x smbd 2>/dev/null || true
sleep 1
systemctl start smbd 2>&1
pause "Step 4 done"
echo "=== Step 5/8: flush conntrack entries for 172.16.9.0/24 ==="
if command -v conntrack >/dev/null 2>&1; then
conntrack -D -s 172.16.9.0/24 2>&1 || true
conntrack -D -d 172.16.9.0/24 2>&1 || true
else
echo " conntrack tool not installed - skipping (apt install conntrack)"
fi
pause "Step 5 done"
echo "=== Step 6/8: flush ARP / neighbour cache ==="
ip neigh flush all 2>&1 || true
pause "Step 6 done"
echo "=== Step 7/8: drop tcp sockets on port 445 ==="
# ss -K requires iproute2 >= 4.11 and CONFIG_INET_DIAG_DESTROY in the kernel.
# Drops existing TCP connections to port 445 without touching listening socket.
ss -K dport = 445 2>&1 || echo " ss -K not supported on this system"
ss -K sport = 445 2>&1 || true
pause "Step 7 done"
echo "=== Step 8/8: restart dnsmasq ==="
systemctl restart dnsmasq 2>&1
pause "Step 8 done"
echo
echo "All soft-fix steps exhausted. If the issue is still present, you'll"
echo "have to power-cycle. Before you do, run /usr/local/sbin/smb-diag.sh"
echo "and share the /tmp/smb-diag-*.log output so we can pinpoint which"
echo "kernel state the reboot is actually clearing."