Linux Guys - Why isn't this working? .SSH Auth keys for Pi

Let’s have a look at the Lua code, perhaps…

Here’s what I’m using to test, at the moment I’m just trying to capture any output, but I’m only seeing the command in the txt file.

local function sshexecute (command)
    p = io.popen (command)
    local out = p: read "*a"
	print(command)
	print(out)
	local f = assert(io.open("/www/popen.txt", "a"))
	f:write(out.. "", "\n")
	f:write(command.. "", "\n")
	f:close()
    p:close()
    print("-----------")
    return out
end

sshexecute("ssh -i /etc/dropbear/dropbear_rsa_host_key pi@192.168.102.37 'ls -l'")

No commands I send via Vera seem to be working, yet the very same command pasted directly at the command line works fine…

Can you be more specific? What’s the output logged? Where are you running this? Scene? Luatest (which gave you trouble before)?

I get the same result if I use Lua Test, or via Apps / Develop Apps / Test Code.

The output logged is below, and it’s simply the command I sent (which I had scripted it to do, ) along with the output/result


ssh -i /etc/dropbear/dropbear_rsa_host_key pi@192.168.102.37 'ls -l'

ssh -i /etc/dropbear/dropbear_rsa_host_key pi@192.168.102.37 'ls -l'

Try it again, dropping the word local from the function declaration. I suggest using Test Luup Code, and then go find the attempts in your LuaUPnP.log file and see if it’s saying anything useful.

Oh, and are you sure there’s something in the directory for it to list? Maybe use the date command instead.

Thanks, I updated the request to ‘date’ but sadly the output/response is still not being captured in the txt file and adding a luup.log entry to the code above

luup.log("sshexe" ..out)

There is only the following in the log file…

50	12/11/20 22:32:30.170	luup_log:0: sshexe <0x713d8520>
50	12/11/20 22:32:30.175	luup_log:0: LuaTest No errors<br>Runtime:  216.8 ms<br>Code returned: nil <0x713d8520>

Try adding -y after the ssh and before the -i

ssh -y -i /etc/dropbear...etc...

Wooahh that did it :laughing:! Thanks @rigpapa

Looking up that ‘-y’ option - https://linuxcommand.org/lc3_man_pages/ssh1.html

     -y      Send log information using the syslog(3) system module.  By
             default this information is sent to stderr.

I’m trying to work out what it does ? Does it make the output/response considered as a ‘standard error ‘ ?

Command options vary between implementations. The best way to figure out what a command or option does on a particular platform is to run the command on the platform and get its help (or get the man page on the platform, but Vera/OpenWrt does leave man pages in the firmeare image).

-y on OpenWrt’s SSH client means accept the remote host key without verifying. The fact that you were getting no output but also no runtime Lua errors suggested the script was OK but the command was failing. When I thought about reasons that it would fail, key failures are the most likely. Since we know the client was using a good key, that left the target, and turning off verification of the target seemed like a good first step. I’m sure if we had added redirection of stderr to stdout to the command, we would have seen an error message that led us to the same conclusion.

Thanks @rigpapa - I never stop learning !! :slight_smile:

Thanks to you, and this thread - I’ve been able to complete my little mini- project of taking 4 snapshots from 4 different cameras - place them in a grid and then email them out !! :partying_face:

1 Like

Nice. Also, to round out something from my last reply, you might try adding 2>&1 to the end of any command you run using io.popen(). This will ensure that any error output is redirected to the data stream and captured by the subsequent read() call, so you have a fighting chance of seeing an error if it occurs.

sshexecute( "ssh -y -i /etc/dropbearkey/dropbear_rsa_host_key user@host 'commandstring' 2>&1" )

Note that this will capture any status/progress output the command normally generates as well, so for some commands, you may need to find its “silent” option to avoid that status information being injected into and corrupting the data output stream (curl is famously chatty, for example, and can be silenced with its -s option).

Having decided to re-purpose an old Raspberry Pi, I thought I’d have a go at creating a new trusted link between my Vera and the Pi, leveraging the wise words and content from above from @rigpapa

I’ve placed this guide here all together mainly to remind me in the future :slight_smile: but also to help others as there were a number of different approaches used above influenced by how people were original set up…

On the Vera:
– Run this to copy the (Vera) system public key to the Pi:

dropbearkey -y -f /etc/dropbear/dropbear_rsa_host_key | grep -F ssh-rsa | ssh pi@192.168.102.42 'mkdir -p ~/.ssh ; cat >>~/.ssh/authorized_keys'

Which returned the following, and required me to confirm what I was doing and then put the password in for the Pi.

Host '192.168.102.42' is not in the trusted hosts file.
(ecdsa-sha2-nistp256 fingerprint sha1!! 38:3d:fe:fe:b6:bb:52:4e:1d:40:83:75:c5:03:43:ce:c4:7a:27:ce)
Do you want to continue connecting? (y/n) y
pi@192.168.102.42's password: 

Then, over on the Pi:
— Do the following…

chown -R pi:pi ~pi/.ssh/
chmod 640 ~pi/.ssh/authorized_keys
chmod 700 ~pi/.ssh

Then, back on the Vera,
— You should now be able to connect without providing a password by using the following…

ssh -i /etc/dropbear/dropbear_rsa_host_key pi@192.168.102.42

Hopefully I’ve captured everything correctly - if anyone notices anything wrong please let me know.




One question I do have is how to use this to reboot the remote Pi, as the following does not find the reboot command

ssh -i /etc/dropbear/dropbear_rsa_host_key pi@192.168.102.42 reboot
bash: reboot: command not found

I assume this is because the reboot command prompts you again for pi or root authorisation, is there a way around that?

That’s because you are logging in as user pi, which is not a privileged user, so two things are happening: (1) reboot lives in /sbin or /usr/sbin on most systems, which is not in the PATH for non-privileged users normally, and (2) even if you send [/usr]/sbin/reboot, it won’t work because you are not privileged.

You’ve added the public key to pi’s authorized_keys file in your example. You can do the same for the root user on the Pi (in /root/.ssh/authorized_keys). Then this should work:

 ssh -i /etc/dropbear/dropbear_rsa_host_key root@raspberry-pi /usr/sbin/reboot

Obviously, this opens a small security hole, but probably low risk. But anyone that can get root privileges on your Vera could then get root privileges on your Pi. If the former can actually happen, you’re already boiling in oil, and another ladel of it in the cauldron isn’t much of an insult.

1 Like

Thanks @rigpapa

I’ve tried to do then same thing again, this time for root but it keeps prompting me for the password, which I’ve set and reset multiple times so i know its’s right ?

Here’s what I did - - On the Pi.

pi@raspberrypi:~$ sudo su
root@raspberrypi:/home/pi# passwd root
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully
root@raspberrypi:/home/pi#

With a new root password set/reset, I then go on to my Vera and enter the following, however it won’t accept the password ?


dropbearkey -y -f /etc/dropbear/dropbear_rsa_host_key | grep -F ssh-rsa | ssh root@192.168.102.42 'mkdir -p ~/.ssh ; cat >>~/.ssh/authorized_keys'
root@192.168.102.42's password: 
root@192.168.102.42's password: 
root@192.168.102.42's password:

Any ideas ?

Most ssh daemons prohibit root login these days as a default (regardless of password). The Pi is no exception. So you can’t move the key over to it using ssh with root password. Your first step is getting the key over there another way, and I suggest since you’ve already done it for user pi, just copy it from there and fix the permissions for root. On the Pi:

sudo su -
mkdir -p /root/.ssh
cp ~pi/.ssh/authorized_keys /root/.ssh/
chown root:root /root/.ssh/authorized_keys
chmod 640 /root/.ssh/authorized_keys

Then try from the Vera:

 ssh -i /etc/dropbear/dropbear_rsa_host_key root@raspberry-pi /usr/sbin/reboot

If you are still prompted for the password, on the Pi open /etc/ssh/sshd_config file in your favorite editor (I’m a vi guy but I think nano is pre-installed on Raspbian), you may find a commented-out line:

#PermitRootLogin prohibit-password

Uncomment this line by removing the #. If the line is not there, add it (without the #). This sets up the ssh daemon on the Pi to allow public key auth for root (but still no root login using password).

Then restart the sshd service to make the change effective:

   sudo systemctl restart sshd

Then try the remote reboot command again. It should work if you’re on a recent Raspbian.

If that doesn’t get it, try changing the prohibit-password to yes, restart the sshd service, and try again.

Is there no end to your talents @rigpapa :slight_smile: Thanks so much,…

Thankfully all it needed was the first part and a slight change to the final reboot command…

sudo su -
mkdir -p /root/.ssh
cp ~pi/.ssh/authorized_keys /root/.ssh/
chown root:root /root/.ssh/authorized_keys
chmod 640 /root/.ssh/authorized_keys

Then from Vera…

 ssh -i /etc/dropbear/dropbear_rsa_host_key root@raspberry-pi reboot
1 Like

Hi @rigpapa

Entering the above directly into the Vera CLI it works fine, but trying to send it using Lua code it doesn’t - whether i try os.execute or `io.popen a…

os.execute("ssh -i /etc/dropbear/dropbear_rsa_host_key root@192.168.102.42 reboot)

Or

local command = io.popen("ssh -i /etc/dropbear/dropbear_rsa_host_key root@192.168.102.42 'reboot' 2>&1")
local response = command:read("*a")
print(response)

The latter of which returns this …

Host '192.168.102.42' is not in the trusted hosts file.
(ecdsa-sha2-nistp256 fingerprint sha1!! 37:3c:fe:fe:b6:bb:52:4e:1d:40:83:75:c5:03:22:ce:c4:7a:27:ce)
Do you want to continue connecting? (y/n) 
ssh: Connection to pi@192.168.102.42:22 exited: Didn't validate host key

Now I worked out that I can add -y to the start of the command in order to address the Do you want to continue.. prompt, like this…

local command = io.popen("ssh -y -i /etc/dropbear/dropbear_rsa_host_key root@192.168.102.42 'reboot' 2>&1")
local response = command:read("*a")
print(response)

Which returns this and seems to work !!! :tada:

ssh: 
Host '192.168.102.42' key accepted unconditionally.
(ecdsa-sha2-nistp256 fingerprint sha1!! 37:3c:fe:fe:b6:bb:52:4e:1d:40:83:75:c5:03:43:ce:c4:7a:27:ce)

ssh: Connection to root@192.168.102.42:22 exited: Remote closed the connection

Any ideas why there is this trusted host file challenge for @root when sending it via code, yet it doesn’t do that if i enter the command directly into the CLI of vera ?

I recall seeing this sort of thing occur before, but I don’t recall if it was ever answered, well i can’t find the answer….

Ok, in doing this testing for root, I think I’ve worked out a way to send the command programmatically as the pi user too.

local command = io.popen("ssh -y -i /etc/dropbear/dropbear_rsa_host_key pi@192.168.102.42 'sudo /sbin/reboot' 2>&1")
local response = command:read("*a")
print(response)

The above works too :grinning_face_with_smiling_eyes:

Has anyone tried exporting the public key from an Ezlo Plus controller ?

I just tried it with this command:

dropbearkey -y -f /etc/dropbear/dropbear_rsa_host_key | grep -F ssh-rsa | ssh myusername@192.168.0.37 'cat >>~/.ssh/authorized_keys'

But it says: dropbearkey: not found

image

I then typed “yes” to continue, it did create a new authorized_keys on the target Linux machine but its empty and contains no public key.

On the Ezlo Plus in WinSCP the public key is in the right folder.

image

The command “dropbearkey” seems to be inbuilt to the Vera firmware hubs. I don’t recall I install it myself. Where as on the Ezlo firmware hub “dropbearkey” command is not present and missing.

On an Ezlo Plus controller you can use this command instead ssh-keygen

It then created these new files:

image

I copied the contents of the id_rsa.pub file into the authorized_keys file on my other Linux Mini-PC.

I then created a new LUA script on the Ezlo Plus controller with the command to reboot the Mini-PC

os.execute ("ssh -i ~/.ssh/id_rsa myusername@192.168.1.101 sudo reboot")

IP 192.168.1.101 being the IP address of the Mini-PC.

image

Now when I run that LUA script my other Linux Mini-PC is rebooted.

I could now create a Meshbot Scene to run this LUA script in its Action etc

I could also maybe use that Meshbot in conjunction with a virtual switch in the rules trigger for ON / OFF action commands.

Or even with the Ezlo WOL & Ping plugin to send a OFF command like the one below.

To Shutdown the Mini-PC I could use this command in a LUA Script

("ssh -i ~/.ssh/id_rsa myusername@192.168.1.101 sudo poweroff")