Oh, no! I crashed my router!

How many times have you been doing something on your router, you reboot to ensure the new configuration works, and it just absolutely doesn’t… DNS resolution doesn’t work, or the radios won’t turn on, or a firewall rule in nftables is blocking traffic and you’re so flustered that you can’t remember how to delete that rule to restore internet.

There’s a way to set up your computer so that you can recover. This is for Linux computers, but an enterprising Windows or Mac aficionado can translate it for those platforms.

First, on a drive that’s got some free space on it, set up a directory. I named mine “OpenWRT_One”.

In your Terminal window, navigate to that directory.

Create two files (backup.sh, restore.sh). They’ll be empty at first. I’ve found the easiest way is to right-click in your file manager, select New > Text File, then rename the text file.

Make the two files executable:

chmod +x backup.sh
chmod +x restore.sh

Populate the files with their scripts:

For backup.sh:

#!/bin/bash
ROUTER_IP="192.168.1.1"
OUT_FILE="$(date +%Y-%m-%d-%H%M)-openwrt_backup.tar.gz"

echo "[1/3] Synchronizing remote repository cache..."
ssh root@"$ROUTER_IP" "apk update"

echo ""
echo "[2/3] Generating APK package list and archiving system configurations..."
ssh root@"$ROUTER_IP" "mkdir -p /etc/backup; apk info -w > /etc/backup/installed_packages.txt; sysupgrade -b /tmp/backup.tar.gz"

echo ""
echo "[3/3] Pulling archive package to your computer..."
scp -O root@"$ROUTER_IP":/tmp/backup.tar.gz ./"$OUT_FILE"

ssh root@"$ROUTER_IP" "rm -f /tmp/backup.tar.gz"
echo "Done! Saved as $OUT_FILE"

echo ""
echo "Press Enter to close this window..."
read -r

For restore.sh:

#!/bin/bash
ROUTER_IP="192.168.1.1"

run_restoration() {
    echo "======================================================="
    echo "       OPENWRT ONE - INTERACTIVE RESTORE MENU"
    echo "======================================================="
    echo "Scanning for configurations..."
    echo ""

    # Build an indexed array of all backup archives in the directory
    MAPFILE=()
    while IFS= read -r line; do
        MAPFILE+=("$line")
    done < <(ls -1 *-openwrt_backup.tar.gz 2>/dev/null)

    if [ ${#MAPFILE[@]} -eq 0 ]; then
        echo "ERROR: No backup files found in this directory!"
        return 1
    fi

    echo "Available Backups:"
    echo "-------------------------------------------------------"
    for i in "${!MAPFILE[@]}"; do
        printf "  [%d]  %s\n" "$((i+1))" "${MAPFILE[$i]}"
    done
    echo "-------------------------------------------------------"

    echo -n "Enter number [1-${#MAPFILE[@]}] (or press Enter to cancel): "
    read -r CHOICE

    # Pure string validation to safeguard against non-numeric entries
    if [[ ! "$CHOICE" =~ ^[0-9]+$ ]] || [ "$CHOICE" -lt 1 ] || [ "$CHOICE" -gt "${#MAPFILE[@]}" ]; then
        echo "Selection canceled or invalid. Exiting safely..."
        sleep 15
        return 0
    fi

    SELECTED_INDEX=$((CHOICE-1))
    BACKUP_FILE="${MAPFILE[$SELECTED_INDEX]}"

    echo ""
    echo "======================================================="
    echo " WARNING: AUTOMATED FLASH RESTORATION INITIATED"
    echo "======================================================="
    echo "Target backup chosen: $BACKUP_FILE"
    echo "-------------------------------------------------------"
    echo -n "Are you sure you want to proceed? (Type upper case Y and Enter): "
    read -r CONFIRM

    if [ "$CONFIRM" != "Y" ]; then
        echo "Restoration canceled by user. Exiting..."
        sleep 15
        return 0
    fi

    echo ""
    echo "[1/3] Uploading selected backup profile to router RAM..."
    scp -O ./"$BACKUP_FILE" root@"$ROUTER_IP":/tmp/backup.tar.gz

    echo ""
    echo "[2/3] Extracting configuration payload and executing router reboot..."
    ssh root@"$ROUTER_IP" "tar -C / -zxf /tmp/backup.tar.gz && rm -f /tmp/backup.tar.gz && reboot"

    echo ""
    echo "-----------------------------------"
    echo "Waiting for the router to reboot..."
    echo "------------------------------------"
    sleep 15

    while ping -c 1 -W 1 "$ROUTER_IP" &>/dev/null; do
        echo -n "."
        sleep 5
    done

    echo ""
    echo "Router detected online. Waiting for active WAN internet connection..."
    while ! ssh root@"$ROUTER_IP" "ping -c 1 -W 2 1.1.1.1" &>/dev/null; do
        echo -n "."
        sleep 5
    done

    echo ""
    echo "[3/3] Triggering user-installed package installation via APK..."
    ssh root@"$ROUTER_IP" '
      if [ -f /etc/backup/installed_packages.txt ]; then
        echo "APK configuration tracker file verified. Synchronizing remote cache..."
        apk update
        echo "Downloading and reinstalling your applications..."
        xargs -r apk add < /etc/backup/installed_packages.txt
        echo "SUCCESS: User-installed applications reinstalled! Performing final reboot..."
        reboot
      else
        echo "ERROR: Package tracking list not found."
      fi
    '

    echo ""
    echo "Restoration complete! Router is rebooting..."
}

# Execute the restoration function and force the terminal window to stay open on exit
run_restoration
echo ""
echo "Press Enter to close this window..."
read -r

Now, there are two ways you can start these scripts. Some Linux flavors have a right-click “Run As Program” context menu, and lacking that, you can call them in a Terminal window:

To back up:

sh backup.sh

To restore:

sh restore.sh

The backup script will put the .tar.gz backup file in the same directory as the two script files.

So, before you make any changes, back up. If something goes wrong, restore.