Use SSH shell_commands without a password to Windows machine

Hey,
I’ve been trying all day to get this to work with no luck.
I’m trying to send a command to my PC to sleep over SSH from my Home Assistant (installed Home Assistant OS on Raspberry Pi 4). I’m trying to figure out the SSH keys so I can have the SSH command trigger without needing my Windows Machine’s password. I generated a key using “ssh-keygen” on windows and copied the contents of the id_rsa to a file in my config “/config/ssh_keys/id_rsa” as outlined in this post (Power on / off NAS by using WOL and SSHPASS - #2 by Lucan).
So my shell command is:

ssh -i /config/ssh_keys/id_rsa -o StrictHostKeyChecking=no username@ip_of_windows "powercfg -h off & rundll32.exe powrprof.dll,SetSuspendState 0,1,0"

However it still asks for the password when I test it in the SSH terminal on the Home Assistant.

I was eventually able to get it working through the terminal in Home Assistant by adding the HA’s public key to my Windows Machine’s authorized keys in “C:\Users\username.ssh\authorized_keys” as outlined in this video (Windows 10 SSH with Public Key Authentication - YouTube)
I’m able to connect without a password just fine with just a standard ssh command! HOWEVER, it doesn’t work when it runs through the shell_command script, it just errors saying: “Permission Denied (publickey, keyboard-interactive)”

So close yet so far. Any help would be greatly appriciated!
Cheers,
Josh

I don’t know if it’s a typo, but the typical path for authorized_keys is username/.ssh/authorized_keys, and it needs to contain the public key that corresponds to the private key that you’re providing via -i /config/ssh_keys/id_rsa. The typical way to ensure that the public key gets added to the right machine in the right place is to use ssh-copy-id -i /config/ssh_keys/id_rsa user@machinename, and enter the password when prompted.

Thanks for your reply! Yes sorry that was a typo.

Can you confirm, the

id_rsa

stored in

“/config/ssh_keys/id_rsa”

is the private key I generated on my Windows machine or is it the private key I generated on the Home Assistant? I’m assuming the latter since you said

Unfortunately

ssh-copy-id

isn’t supported on Windows. Unless there is another way of doing it other the manually putting the keys in the file?

When you’re connecting from your HA machine to your Windows machine, both the private and public keys come from HA. You specify the private key to ssh with -i /config/ssh_keys/id_rsa and you copy the public key to your Windows machine. That way, ssh ensures that the private key that you passed it matches with the public key on the remote server, which could have only gotten there by you logging into the remote server.

You run it on your HA instance where you’ve generated the keys, not on the Windows box.

Any reason you need or want to use SSH? As there is easier solutions to sleep and or shut down local PC via HA


This is the error I get when using ssh-sopy-id from HA to the windows machine. Also, shouldn’t I be copying the id_rsa.pub to the windows machine, not the id_rsa? I tried both and it didn’t work.

I tried putting the HA private key in

“/config/ssh_keys/id_rsa”

and I still got a Permission Denied error from the shell_command.
I couldn’t even get the

ssh -i /config/ssh_keys/id_rsa

line to work in the terminal, but without, just connecting with

ssh [email protected]

works fine and I connect without being prompted for a password. So why does it work from the HA terminal but no in the shell_command? Is it something to do with Home Assistant Containers or docker? I installed the Home Assistant OS image to my Pi assuming it didn’t use any containers?

What would you suggest is the easiest way to have commands to

  • Shutdown
  • Sleep
  • Wake on lan

And I would prefer to get it working over SSH because then I can run other commands over SSH like running scripts and backups, etc

Most folks use IOTLink for the stuff you’re doing.

It looks like the SSH server on your windows machine isn’t behaving as ssh-copy-id expects, so you’d have to copy the public key over manually (as you did before). As you can see from that output, you’re giving it the private key and it derived the name of the public key from it - id_rsa.pub - to copy over. It’s trivial for everything but, apparently, a Windows machine. The only other thing that I can think of is that you need to protect the .ssh folders on both the local and remote machines so that they’re only readable by the owner - chmod 700 in Unix/Linux/everything else speak. If that folder is too permissive, it will deny access.

If you’re able to run ssh [email protected] without pointing to the private key (id_rsa), that means that there’s a valid private key in /root/.ssh. You won’t have access to that directory from a Home Assistant shell command (it’s running in its own container), so that’s why you need to put it somewhere else (like /config/ssh_keys) and point to it with -i.

Home Assistant OS always uses containers, as do any addons that you install, including the SSH ones.

You can continue to play with it, but you may want to investigate IOTLink as an alternative.

I FINALLY FIGURED IT OUT!
Once I realized the Home Assistant OS runs on containers, i knew what to do… The issue is I’m generated the keys from the root OS, not from the docker container that the shell_command runs through. That’s why I can SSH without password from terminal but get errors on the shell_command. So you need to console into the Home Assistant Docker container and generate the keys from there, not from the Home Assistant OS Terminal. Here are the steps for anyone who is interested.

  1. Install Portainer on Home Assistant. This lets you access the HA Dockers Containers.
  2. Go to “Containers”, and under “Quick Actions”, open a console for “homeassistant”
  3. Generate you ssh-keys with
ssh-keygen

and save them to “/config/ssh_keys/id_rsa”
4. On your windows machine (the machine you want to connect to without a password), navigate to “\ProgramData\ssh” and create a file “administrators_authorized_keys” (I had to create it on my desktop and copy it in because of permissions)
5. Open the “/config/ssh_keys/id_rsa.pub” key that you generated on Home Assistant with File Editor and copy the key into “\ProgramData\ssh\administrators_authorized_keys”
6. Open a Powershell as Administrator and run the following to set the proper permissions to the keys file:

Get-Acl "$env:ProgramData\ssh\ssh_host_dsa_key" | Set-Acl $env:ProgramData\ssh\administrators_authorized_keys
  1. Open “\ProgramData\ssh\sshd_config” and change the following:
    -replace ‘#PubkeyAuthentication yes’ with ‘PubkeyAuthentication yes’
    -replace ‘#PasswordAuthentication yes’ with ‘PasswordAuthentication no’
    (This makes it so anyone connecting needs to have keys, it will no longer let you ssh in with a password)
  2. Restart the ssh service by running the following in Powershell
restart-service sshd

NOW when you create a shell_command, use the following SSH line:

ssh -i /config/ssh_keys/id_rsa -o StrictHostKeyChecking=no USERNAME@WINDOWS_IP

Following on from this, I then worked out I can install sshpass in the docker homeassistant docker container. So I have both options, and I think I will go with the simpler sshpass option so I don’t have to configure all this again in the future and then I can still ssh into my machine with a password.

Thanks for all your help @rccoleman for steering me on the right path.

1 Like

Glad you figured it out! You don’t need to shell into the HA container - you just need to put the keys in your HA config directory, which you can get to from /config from either SSH addon or from /mnt/data/supervisor/homeassistant from the console (where I guess you were).

I had to generate the keys from within the HA container, because the keys I generated from the HA Terminal where different to the keys I generated from within the container.

Little late but there is a community guide for this. It will also show how to get rid of StrictHostKeyChecking=no

Although I see you have solved the Issue, for anyone else that may want the answer of other (possibly easier) options:

https://github.com/sleevezipper/hass-workstation-service