#!/usr/bin/env bash set -uo pipefail echo "=== 1. Detecting Attached RPi SD/SSD in WSL2 ===" lsblk -o NAME,SIZE,FSTYPE,PARTUUID,MODEL # Find the newly attached disk (not sda, sdb, sdc, sdd) TARGET_DEV="" for dev in /dev/sd[e-z]; do if [ -b "${dev}2" ]; then TARGET_DEV="$dev" break fi done if [ -z "$TARGET_DEV" ]; then echo "[ERROR] Could not find attached RPi disk (/dev/sde..z with partition 2)!" exit 1 fi BOOT_PART="${TARGET_DEV}1" ROOT_PART="${TARGET_DEV}2" echo "Target Disk: $TARGET_DEV (Boot: $BOOT_PART, Root: $ROOT_PART)" blkid "$BOOT_PART" "$ROOT_PART" echo "" echo "=== 2. Inspecting Ext4 Superblock BEFORE Repair ($ROOT_PART) ===" dumpe2fs -h "$ROOT_PART" 2>/dev/null | grep -E "Filesystem volume name|Filesystem UUID|Filesystem state|Errors behavior|Filesystem created|Last mount time|Last write time|Mount count|Maximum mount count|Last checked|Journal|Inode count|Free inodes|Block count|Free blocks" echo "" echo "=== 3. Running e2fsck -fy on $ROOT_PART ===" e2fsck -fy "$ROOT_PART" FSCK_RC=$? echo "e2fsck exit code: $FSCK_RC (0=no errors, 1=errors corrected, 2=corrected)" echo "" echo "=== 4. Setting Ext4 Errors Behavior to 'continue' ===" tune2fs -e continue "$ROOT_PART" dumpe2fs -h "$ROOT_PART" 2>/dev/null | grep -E "Filesystem state|Errors behavior|Last checked" echo "" echo "=== 5. Mounting $ROOT_PART & $BOOT_PART to Inspect & Harden OS Config ===" mkdir -p /mnt/rpi_root /mnt/rpi_boot mount "$ROOT_PART" /mnt/rpi_root mount "$BOOT_PART" /mnt/rpi_boot echo "--- Hostname & Network Config ---" cat /mnt/rpi_root/etc/hostname 2>/dev/null || true cat /mnt/rpi_root/etc/network/interfaces 2>/dev/null | grep -v "^#" | grep -v "^$" || true ip_cfg=$(grep -rn "140.44.4." /mnt/rpi_root/etc/network/ /mnt/rpi_root/etc/NetworkManager/ /mnt/rpi_root/etc/systemd/network/ 2>/dev/null || true) echo "$ip_cfg" echo "--- Current /etc/fstab ---" cat /mnt/rpi_root/etc/fstab # Harden /etc/fstab (add nofail to /boot/firmware or /boot and any nfs/glusterfs mounts) cp /mnt/rpi_root/etc/fstab /mnt/rpi_root/etc/fstab.bak python3 -c ' p = "/mnt/rpi_root/etc/fstab" with open(p, "r") as f: lines = f.readlines() new_lines = [] for line in lines: s = line.strip() if not s or s.startswith("#"): new_lines.append(line) continue parts = s.split() if len(parts) >= 4: mp, fstype, opts = parts[1], parts[2], parts[3] if (mp in ("/boot/firmware", "/boot") or fstype == "vfat") and "nofail" not in opts: parts[3] = opts + ",nofail" line = "\t".join(parts) + "\n" elif fstype in ("glusterfs", "nfs", "nfs4", "cifs") and "nofail" not in opts: parts[3] = opts + ",nofail,x-systemd.automount,x-systemd.device-timeout=30" line = "\t".join(parts) + "\n" new_lines.append(line) with open(p, "w") as f: f.writelines(new_lines) ' echo "--- Hardened /etc/fstab ---" cat /mnt/rpi_root/etc/fstab # Ensure both /mnt/rpi_boot/cmdline.txt and /mnt/rpi_root/boot/cmdline.txt (if regular file) have fsck.repair=yes and ro for cpath in /mnt/rpi_boot/cmdline.txt /mnt/rpi_root/boot/cmdline.txt /mnt/rpi_root/boot/firmware/cmdline.txt; do if [ -f "$cpath" ] && [ ! -L "$cpath" ]; then if ! grep -q "fsck.repair=yes" "$cpath"; then sed -i "s/rootfstype=ext4/rootfstype=ext4 fsck.repair=yes/" "$cpath" fi if ! grep -qE "(^| )ro( |$)" "$cpath"; then sed -i "s/rootwait/ro rootwait/" "$cpath" fi echo "Verified $cpath: $(cat "$cpath")" fi done echo "--- Checking Kernel Modules in /lib/modules vs Boot Kernel ---" ls -la /mnt/rpi_root/lib/modules/ ls -la /mnt/rpi_root/boot/ echo "--- Checking Recent Logs / Crash Evidence on Root FS ---" ls -la /mnt/rpi_root/var/log/ 2>/dev/null | head -n 20 if [ -d /mnt/rpi_root/var/log/journal ]; then journalctl -D /mnt/rpi_root/var/log/journal -n 30 --no-pager 2>/dev/null || true fi tail -n 30 /mnt/rpi_root/var/log/syslog /mnt/rpi_root/var/log/messages /mnt/rpi_root/var/log/daemon.log 2>/dev/null || true sync umount /mnt/rpi_boot umount /mnt/rpi_root echo "=== 6. Repair and Hardening Complete! Unmounted cleanly. ==="