SSH'ing from a command line sensor or shell command

Meanwhile I figured out it´s because of the PasswordAuthentication no. I temporarily changed it to yes and could access the remote host from Home Assistant.

So my task to accomplish (if possible) is to add the existing private key of the SSH remote host to Home Assistant, as password authentication is disabled for security reasons (and therefore I can´t go through the steps to enable password-less login).

It all comes back to :frowning:

Meanwhile I figured out it´s because of the PasswordAuthentication no. I temporarily changed it to yes and could access the remote host from Home Assistant.

So my task to accomplish (if possible) is to add the existing private key of the SSH remote host to Home Assistant, as password authentication is disabled for security reasons (and therefore I can´t go through the steps to enable password-less login).

It all comes back to… :frowning:

So probably not but its worth noting why this is difficult. Your commands must be non-interactive to work from shell commands and command line sensors and SSH doesn’t want you to use a password in non-interactive sessions for pretty valid reasons:

  1. It doesn’t want you to store the password in clear-text in a file (which you’ll have to do here)
  2. It doesn’t want anyone on the system to be able to see the password with a simple ps

That being said, if you’re comfortable with these risks I have an idea. With some searching I found that the go to tool for this task is one called sshpass. It accepts the password as a command line argument and uses it to start an SSH session as if it was entered interactively.

Now you can’t install anything in the Home Assistant container since any environment changes like that won’t be persistent. But sshpass is available as an alpine package which means you can add it to the list of alpine packages to install in the SSH & Web Terminal addon. Then what you should be able to do is essentially nest your SSH commands. First go password-less ssh to the addon then use sshpass to go from there to your remote server.

I want to be clear, I have not tested this as I use password-less SSH everywhere myself. But figured I’d throw it out there as it seems like it should work.

When you say server here, do you mean the remote machine? Cause I think that kind of depends on how it is configured? Like I certainly can, I simply generated pub/priv keys without a passphrase and that’s what I use. Is your server running software that requires a passphrase for private keys?

Interesting.

I´m currently one small step ahead: storing the private key of the existing server (remote host) public/private key pair in /config/.ssh/remote_private.txt and accessing the remote host from HA using “ssh -i /config/.ssh/remote_private.txt [email protected]” works. But it still asks for the password the private key is encrypted with.

I´ll try to provide a separate key pair on the remote host without a private key password, exclusively for the home assistant machine.

In the end we want to ssh into the remote host without the need of providing an additional password, right? If it´s okay to not just “ssh …” but “ssh -i /provide/path/to/private/key” for further usage that would be my favorite path to go. What do you think?

Question 1: Yes, remote machine.
Question 2: It´s a pretty well secured host (obviously) for good reasons. Therefore currently password for private key and PasswordAuthentication no set.

Update: Oh man… need more sleep. As I was sticking closely to How to Setup SSH Passwordless Login in Linux I always tried ssh [email protected] from the HA SSH Addon. But as stated later (a few steps later unfortunately…) in your post we need to use ssh [email protected] -i /config/.ssh/id_rsa !

So between the link here

and the first appearence of the -i parameter for ssh command here (even in a screenshot before)

the confusion happened for me.

Long story short: everything working as expected, my fault. Possibly the initial post would be bullet proof when noting to provide the custom path with the -i parameter when testing the SSH login. Standard links like the (basically good one) provided don´t fit the custom stuff we need to do here afterwards :smiley:

Additionally I used public/private keys a bit different over the years:
server → ONE key pair → use private key on all clients to access server

With the expansion of authorized_keys it´s possible to basically “vice versa whitelist” any client (its key). That approach was new to me, so learned a bit of basic Linux stuff before now turning to command line sensor and shell command fun with Home Assistant :slight_smile:

2 Likes

I want to achieve the following:

  1. Create command_line sensor which connects to another docker container (running on the same host homeassistant container is running (HASS OS)) and gets some information

How can I do this? I used this guide to remotely access other SSH servers.
This time everything happens on the same host.

Can homeassistant containers SSH and root SSH be configured so homeassistant container can password-less login to root SSH (host SSH)? From a security point of view not the best way to go I guess.

command: "docker exec addon_a0d7b954_influxdb du -shm /data/influxdb/data/homeassistant | cut -f1"
→ This fails as it is run from HA in homeassistant container - where even no docker command exists. This command works on the root SSH very well.

Workflow I´m thinking about would look like:
HA container → SSH to host → login to another docker container → get information → done

(background: Unreliable InfluxDB size sensor - #34 by e-raser)

Oh wait, I see the problem. You said SSH so I assumed you had a container running an SSH service but that’s not it. You don’t actually want to SSH, you want to docker exec into a container.

As you noted the HA container does not have access to the docker CLI so that command won’t work from a commandline sensor. You will need to SSH from HA into somewhere else with docker CLI access and then execute that from there. Since it looks like you are running the InfluxDB add-on I would think that you have two options here:

  1. The workflow you outlined (SSH to host, run the docker exec command from there)
  2. Use the SSH & Web Terminal add-on (the community one) with protection mode turned off, that has access to the Docker CLI when you do that. Then use this workflow:
    • HA container → SSH to SSH & Web Terminal Add-on → login to another docker container → get information → done

Followed this example, but I am still getting:

Failed to add the host to the list of known hosts (/config/.ssh/known_hosts).

Did you create the /config/.ssh folder first? I tested just now and I am able to reproduce this error when the folder I want to put my known_hosts file in does not exist. As long as I make the folder first then it works without error.

That solved it. Wow, the .ssh folder permissions are really touchy! Thank you again.

1 Like

Hi @all, I could use some help with this.

I’m running HA core on Proxmox (LXC) and also have a RPi with 7" touchscreen that I use as a dashboard (running Raspbian desktop).
I would like to be able to switch the touchscreen on/off from HA when nobody is home & overnight.

From the HA shell I can achieve this with:

 ssh rpi 'echo 1 | tee /sys/class/backlight/rpi_backlight/bl_power'

and

 ssh rpi 'echo 0 | tee /sys/class/backlight/rpi_backlight/bl_power'

I have created this switch:

- platform: command_line
  switches:
    rpi_screen:
      command_off: "ssh rpi echo 1 | tee /sys/class/backlight/rpi_backlight/bl_power"
      command_on: "ssh rpi echo 0 | tee /sys/class/backlight/rpi_backlight/bl_power"

But this doesn’t work.
Don’t know if this is of any importance: in HA I’m logged with my own name, the command on the shell is as root.

Any idea what might be wrong?
Thanks for looking at this.

  1. Did you generate an SSH key and save it somewhere in the /config directory, preferably /config/.ssh/
  2. Did you use ssh-copy-id to copy the key to the Pi you want to control?
  3. Did you verify that you can definitely SSH in to Pi by pointing to the key (using -i ) in the SSH command, and ensure that it connects without asking for a password?
1 Like

Hi @mobile.andrew.jones, thanks for helping out!

I don’t understand what is happening:

root@v-hass:/config/.ssh# ls -l
total 9
-rw------- 1 root root 1876 Dec 18 23:46 id_rsa
-rw-r--r-- 1 root root  393 Dec 18 23:46 id_rsa.pub
root@v-hass:/config/.ssh# ssh-copy-id [email protected]
/usr/bin/ssh-copy-id: ERROR: No identities found
root@v-hass:/config/.ssh# ls
id_rsa  id_rsa.pub
root@v-hass:/config/.ssh# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): /config/.ssh/id_rsa
/config/.ssh/id_rsa already exists.
Overwrite (y/n)? y
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /config/.ssh/id_rsa.
Your public key has been saved in /config/.ssh/id_rsa.pub.
...
root@v-hass:/config/.ssh# ssh-copy-id [email protected]
/usr/bin/ssh-copy-id: ERROR: No identities found

Right so the first problem is that just like you need to use the -i flag to point to the identity file when you use the ssh command, you ALSO have to do the same with the ssh-copy-id command, otherwise it is trying to find the key inside the docker container.

So:

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

(Also I hope that you didn’t enter a passphrase when generating the key, otherwise it can’t be used in a command line)

1 Like

I did enter a password initially, did it again without.

root@v-hass:/config/.ssh# ssh-copy-id [email protected] -i /config/.ssh/id_rsa
/usr/bin/ssh-copy-id: ERROR: no ID file found

I’m not following you where you say using the -i flag when using the ssh command
Do you mean in the config of my command line switch?

Yes, the -i flag must need to go first, that’s fine:

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

You will need to edit your ssh commandlines to look like this:

"ssh -i /config/.ssh/id_rsa pi@rpi echo 1 | tee /sys/class/backlight/rpi_backlight/bl_power"
1 Like

Thanks for sticking with me man!

The key is not copied to the remote /config/.ssh

root@v-hass:/config# ssh-copy-id -i /config/.ssh/id_rsa [email protected]
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/config/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
[email protected]'s password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh '[email protected]'"
and check to make sure that only the key(s) you wanted were added.

When I try to login to the RPi, it asks me to enter a password.
(gotta go now, will check back later)

You probably typed the command it suggested you type:

ssh [email protected]

But as I previously indicated - you need to use the -i flag and tell it where to find the identity file:

ssh -i /config/.ssh/id_rsa [email protected]

that should not ask you for the password, hopefully :slight_smile:

1 Like

Just an FYI you’re commenting on a guide that essentially explains the issues you’re facing, did you read it? For example:

Since you told the command to generate the key file inan unusual location (/config/.ssh) then you need to tell it where it is for all future ssh commands with -i. That includes ssh-copy-id as Andrew noted.

In addition I notice on your commands you don’t seem to be specifying -o UserKnownHostsFile or -o StrictHostKeyChecking=no on your command. Which means your command will work for now but break next time you update since the known_hosts file is in /root. Would recommend reading the section called “Handling the known_hosts file” for why that’s an issue and the options to fix it.

Don’t do this.

  1. It doesn’t do what you think it does. There’s a user with the id “all”. You pinged them.
  2. If it did do what you thought it did (pinged everyone) a moderator would certainly be here warning you to never do that again.

Replying on a post notifies everyone that follows that post, you don’t have to @ anyone for that. Just for future reference.

1 Like

Hi @CentralCommand, thanks for stepping in and rubbing my nose in it! :blush:

I started over, but still not working.
This is what I did:

  1. generated the key, stored in /config/.ssh/id_rsa with no password
  2. copied the key with ‘ssh-copy-id -i /config/.ssh/id_rsa [email protected]
    If I understand it correctly: the -i /config/.ssh/id_rsa in the above command searches in that spot for the key.
    What about the remote directory, is that of any importance?
  3. Tested with ‘ssh -i /config/.ssh/id_rsa [email protected]’ which let’s me connect without asking a password.

When I try the command form HA shell:

root@v-hass:~# "ssh -i /config/.ssh/id_rsa [email protected] echo 1 | tee /sys/class/backlight/rpi_backlight/bl_power"
-bash: ssh -i /config/.ssh/id_rsa [email protected] echo 1 | tee /sys/class/backlight/rpi_backlight/bl_power: No such file or directory

and

root@v-hass:~# ssh -i /config/.ssh/id_rsa [email protected] echo 1 | tee /sys/class/backlight/rpi_backlight/bl_power
tee: /sys/class/backlight/rpi_backlight/bl_power: No such file or directory
1

and

root@v-hass:~# ssh -i /config/.ssh/id_rsa [email protected] 'echo 0 | tee /sys/class/backlight/rpi_backlight/bl_power'
0
tee: /sys/class/backlight/rpi_backlight/bl_power: Permission denied


So I don’t know if it’s a matter of syntax or something else.