HASSIO Shell Commands: Which user does Hassio run them as?

Tags: #<Tag:0x00007fc413923298>

I need to send commands to a remote machine using SSH. I’ve installed the SSH add-on in Hassio (w/ supervisor) and from their generated a public key pair and pushed the key over to the remote server (see steps 1 -2: https://app.getpocket.com/read/1778265189). I can now commit commands to the remote server from the SSH web terminal without issue.

I’ve done the same as the pi/rasbian level, and again can send & execute commands on the remote server via the the local ssh terminal.

However, if I add these commands to my Hassio instance as shell_commands then run those commands via a button on the web-ui these fail with error code 250 or 255 showing in the Hassio log. This error relates to invalid permissions/credentials to run the ssh tasks on the remote server.

So, it would appear that Hassio is using a different user to perform shell_commands than the web terminal add-on and the [email protected] os level user. Which user is Hassio using to perform the shell_commands and how can I generate & push the public keys necessary to perform remote ssh actions?

Here’s an example of the type of shell command that I need to run on the remote server:

reboot_intercom_pi: ‘ssh [email protected] /usr/bin/sudo /sbin/shutdown -r now’

Thanks.

Do you have the portainer add-on? I’ve found that extremely helpful when trying to get my own shell commands and command line sensors working.

If you open that add-on you can go to the homeassistant container and connect to its console. Anything I’ve got working there works seems to work the same when running from one of these integrations (give or take the restrictions imposed in shell command around piping and such).

I have a similar shell command and to get that working I logged on to portainer, did the keygen there and then pushed the public key to my remote server. After that I was able to use an ssh command from my shell command and sensor without issue.

2 Likes

Thanks for the response. I do have portainer but no real idea as to how to use it. But, I’ll be sure to give a go in the morning.

Thanks for the encouraging suggestion!

Yea I installed it initially and didn’t use it for a while either until I started trying to do some command line sensors, then it was a godsend. If you open it up you can click “containers” in the left side nav. After that look for the one called ‘homeassistant’ in the list:

That icon I highlighted launches straight into the console. You can also click on the name to see more details about the container, there’s a bunch of stats and things.

The little page icon 3 to left is also the logs for the docker container. That’s the other reason I use this add-on a lot, its the easiest way I’ve found to browse logs for add-ons since each add-on is a container it shows you the whole log with filtering tools.

1 Like

Thanks for the details. It sounds very promising.

EDIT: I just realised I can open a full terminal by just running the bash command that is shown as default when opening the terminal page.


I’ve just tried that but can’t get the key to push over to the remote server. I’ve tried with 2 remote servers without success.

I’m doing the following as root:

ss-keygen

works fine

ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]

However, the terminal window closes within seconds before I can see if there is any output. If I try logging in to the remote server I still get asked for the password. So, it appears that the ssh-copy-id hasn’t worked.

Any suggestions?

Thanks.

Actually, I’m still getting the same 255 error after doing that, when running the shell command via hassio

Did you run bash as root when copying your ssh key over?

Could you possibly let me see a couple of your shell_commands to a remote server? Maybe I’m doing something wrong when it come to running them in HA?

Thanks.

Hm so I only have one shell_command right now and it looks like this:

update_host: 'ssh [email protected]<local ip> ''sudo apt upgrade -y'''

Granted “remote” here is used liberally since this command is basically reaching back to the host its running on and telling it to upgrade its packages. But it does go back out to the network to do that so it is effectively remote. I use it in conjunction with this command line sensor that tells me when my host has updates to keep my HA host up to date:

sensor:
- platform: command_line
  name: Host updates
  scan_interval: 900
  command: 'ssh [email protected]<local ip> ''sudo apt update > /dev/null && sudo apt list --upgradeable'' | jq --raw-input --slurp ''{ "packages": split("\n") | del(.[] | select(. == "" or . == "Listing...")) }'''
  value_template: '{{ value_json.packages | length }}'
  json_attributes:
  - packages

Both of these work fine so I’m not sure what would be happening for you. If the issue is just with the ssh-copy-id maybe as a workaround you could just print out the public key to the terminal and copy it. Then you can push that over to your remote host without using portainer and dealing with the timeout.

For the terminal closing within seconds thing, it does auto close but usually for me its like 30 seconds. And it is based on activity so as long as I’m doing things it stays open. Sounds like its closing faster then that for you, not sure why that would be happening. I don’t see a setting for this in portainer either so I don’t know how to change that, hm…

Interesting… I see you’ve not had to do any of the workarounds using -o -i or -t flags.

The only difference I see is that you’ve wrapped your actual command in ‘’ which I haven’t. I’ll give that a go, but it’s odd that these same scripts worked when I was running homeassistant as a python venv rather than my current hassio/supervisor setup.

I’ll give those quotes a try and see what happens.

Thanks.

When you ran the ssh-keygen / ssh-copy commands were you doing that in the portainer shell as root or another user? Where did you store your rsa files?

If the issue is just with the ssh-copy-id maybe as a workaround you could just print out the public key to the terminal and copy it. Then you can push that over to your remote host without using portainer and dealing with the timeout.

There’s no issue there. I can ssh from portainer into the remote server(s) without a password once I’ve copied over the key. It just doesn’t work from the shell_command. It’s got to be some sort of authentication issue.

Root. You know until you just said that, I didn’t actually notice that option above the connect button to change the user. But yes, I ran it all as root so I would guess that means shell commands and command line sensors are also running their commands as root.

~/.ssh. Which according to pwd is /root/.ssh.

However I have to backtrack big time here. As I’m doing this investigation I’m realizing my sensor has been silently failing. I added it about a week ago and it definitely was working but now it is not. My speculation currently is that /root/.ssh is overwritten on update of HA.

So this all did work but now I’m a bit back to the drawing board since I have to figure out how to get this key to persist over updates and still be usable in this command.

I actually update today aswell. After reading your comment, I just went back to keygen and it ran as if it was the first time. So it does indeed seem that .ssh is overwritten on updates. unfortunately, the portainer shell doesn’t allow ‘dir’ so I can’t visually navigate the directory structure to find a better place to store the key. Ideally I’d want to place it somewhere that my shell_command / HASSIO can use directly.

Anyway, I’ll regenerate & update my keys then see if I can get my shell commands working.

So from within the container I see a few possible folders that I know are preserved.

  • /config is your HA config folder so that must be preserved from release to release
  • /share is a shared folder shared between all addons. Addons such as Mosquitto broker and Zigbee2MQTT put their config in there in order to make it easy for you to modify from the CLI so that also must be preserved
  • /ssl is where all SSL certificates get put for use in HA as well as its addons, like I can see the certificates for the lutron certificate addon, wireguard addon and nginx proxy manager addon in there so that also must be preserved through releases

So just now I created a .ssh folder in /config, re-ran ssh-keygen and then pushed my new public key over to my authorized_keys file on the host. Then I updated my sensor to the following:

sensor:
- platform: command_line
  name: Host updates
  scan_interval: 900
  command: 'ssh [email protected]<local ip> -i /config/.ssh/id_ed25519 ''sudo apt update > /dev/null && sudo apt list --upgradeable'' | jq --raw-input --slurp ''{ "packages": split("\n") | del(.[] | select(. == "" or . == "Listing...")) }'''
  value_template: '{{ value_json.packages | length }}'
  json_attributes:
  - packages

That now has it working again so I think this should be viable here.

I don’t know if /config is the proper place for something like this? But the .ssh folder is right next to all the .token files created created for the various integrations that support oauth and the .storage folder that has all sorts of auth information so it seems like the best place for the time being.

So what “file path” would we need to enter when running ssh-keygen inorder to “permanently” store the ssh keys in config?

Also… Isn’t “/config/” actually “homeassistant” on the server’s internal routing? eg: /usr/share/hassio/homeassistant" or something similar?

It looks like I’ve mostly got it working now. Just testing out some more of my shell_commands (I’ve quite a few), but it’s looking good.

Thanks for the help!