Power on / off NAS by using WOL and SSHPASS

hi guys! I have the solution that is fully functional but with some security concerns. Here is my full guide, that could help:

:white_check_mark: SOLUTION

  • Used sshpass only inside the Advanced SSH & Web Terminal add-on, not from Home Assistant Core.
  • Stored the NAS password in a file, avoiding exposure in command lines.
  • Used SSH config for clean targeting of remote hosts.
  • Separated scripts and shell commands.
  • Set sensible file permissions.

Requirements:

  • Advanced SSH & Web Terminal Add-on
  • Protection mode off in the Add-on

Config of Advanced SSH & Web Terminal Add-on:

username: "hassio"
password: "!secret ssh_pass"
authorized_keys:
  - >-
    ssh-rsa
    AAAAB3NzaC1yc2EAAAADAQABAAA...TRUNCATED...
    homeassistant
sftp: false
compatibility_mode: false
allow_agent_forwarding: false
allow_remote_port_forwarding: false
allow_tcp_forwarding: false
init_commands:
  - apk add --update --no-cache sshpass
allow_remote: true

NOTE: The add-on’s init_commands only run at container boot time, not when you open a new Terminal window in the UI. The terminal you open is likely a new shell session not tied to the startup init_commands. Even though I restarted the service, sometimes sshpass disappeared. That’s why, I have put it in the script as well.

VSC Add-on in Home Assistant:

/config/.ssh/config

# homeassistant server
Host 10.10.10.18
  UpdateHostKeys yes
  User hassio
  UserKnownHostsFile /config/.ssh/known_hosts
  IdentityFile /config/.ssh/id_rsa_HA
  IdentitiesOnly yes

/config/.ssh/id_rsa_HA

-----BEGIN OPENSSH PRIVATE KEY-----
b3Bl...

/config/.ssh/known_hosts
only created the file

/config/pass/ssh_nas_pass.txt

<your NAS admin password>

/config/scripts/nas_reboot.sh

#!/bin/sh
command -v sshpass >/dev/null 2>&1 || apk add --update --no-cache sshpass
sshpass -f /root/config/pass/ssh_nas_pass.txt ssh \
  -o StrictHostKeyChecking=accept-new \
  -o UserKnownHostsFile=/root/config/.ssh/known_hosts \
  -o KexAlgorithms=+diffie-hellman-group1-sha1 \
  -o HostKeyAlgorithms=ssh-rsa \
  -t [email protected] reboot

/config/scripts/nas_shutdown.sh

#!/bin/sh
command -v sshpass >/dev/null 2>&1 || apk add --update --no-cache sshpass
sshpass -f /root/config/pass/ssh_nas_pass.txt ssh \
  -o StrictHostKeyChecking=accept-new \
  -o UserKnownHostsFile=/root/config/.ssh/known_hosts \
  -o KexAlgorithms=+diffie-hellman-group1-sha1 \
  -o HostKeyAlgorithms=ssh-rsa \
  -t [email protected] poweroff

/config/configuration.yaml

shell_command: !include shell_commands.yaml

/config/shell_commands.yaml

nas_reboot: ssh -F /config/.ssh/config [email protected] "/root/config/scripts/nas_reboot.sh"
nas_shutdown: ssh -F /config/.ssh/config [email protected] "/root/config/scripts/nas_shutdown.sh"

Set the file permissions:

% ssh ha
chmod 700 /root/config/.ssh
chmod 600 /root/config/.ssh/id_rsa_HA
chmod 600 /root/config/.ssh/config
chmod +x /config/scripts/nas_reboot.sh
chmod +x /config/scripts/nas_shutdown.sh

Do the first login manually to build up known_hosts file and test SSH configuration:

% ssh ha
➜  ~ ssh-keyscan 10.10.10.10 >> /config/.ssh/known_hosts
➜  ~ docker ps -a
CONTAINER ID   IMAGE                                                      COMMAND      CREATED        STATUS         PORTS   NAMES
f187c7e759af   ghcr.io/home-assistant/qemux86-64-homeassistant:2025.7.4   "/init"      16 hours ago   Up 12 minutes          homeassistant
➜  ~ docker exec -it f187c7e759af /bin/bash
homeassistant:/config# ssh -F /config/.ssh/config [email protected]
The authenticity of host '10.10.10.18 (10.10.10.18)' can't be established.
ED25519 key fingerprint is SHA256:FBZoBinSQJCtRvOopqvcl6tJ2s4WFm2HS1T3THFNmv4.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.10.18' (ED25519) to the list of known hosts.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/config/.ssh/id_rsa_HA' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "/config/.ssh/id_rsa_HA": bad permissions
no such identity: /config/.ssh/id_rsa: No such file or directory
homeassistant:/config# chmod 600 /config/.ssh/id_rsa_HA
homeassistant:/config# ssh-keygen -p -f /config/.ssh/id_rsa_HA -m pem
homeassistant:/config# ssh -F /config/.ssh/config [email protected]

:lock: Security comments & Suggestions

1. Sensitive Files Placement

  • If you’re using /config/pass/ssh_nas_pass.txt — this is readable by any add-on or integration with access to /config. Consider moving it to /root/.secrets/ssh_nas_pass.txt inside the Advanced SSH add-on, which is more isolated.

    :warning: You’ll then also need to update your scripts to reference the new path.

NOTE: If I put it in the container, the info will be lost when the add-on is updated. That’s why I took this risk.

2. Hardcoded Credentials in Scripts

  • The SSH password is still read in plain text via sshpass. If your NAS supports SSH key-based login, you should switch to using a key instead. That way:

    • You eliminate sshpass
    • You avoid storing passwords anywhere
    • You can lock down the key with from= in the authorized_keys on the NAS

If that’s not possible, consider restricting the NAS SSH user:

  • Create a dedicated NAS user for HA with limited rights (just reboot and poweroff)

  • Disable interactive shell for that user on the NAS (nologin shell or command-restricted keys)

  • Disable password auth on NAS if switching to key-based auth:

    PermitRootLogin prohibit-password
    PasswordAuthentication no
    

NOTE: This is valid on a newer NAS. In my case this was not possible due to busybox and embedded linux.


3. Minimal Add-on Permissions

  • You’re already running Protection mode: off, which is required to access /root and /config. Keep that limited to this add-on only.
  • Also make sure SSH access is limited to LAN or VPN users only — do not expose SSH externally.