Is there luup code for sending ssh commands to a server?

I would like to shutdown my server at a specific moment by using an ssh command.
Looks like : ssh user@remote_computer sudo poweroff
Is this possible?

You can run any shell command from Lua with

os.execute("command")

The main trick with scripting SSH is that you have to make it non-interactive. Practise first from the Vera command line, and when you can make it work without prompting for passwords, then put it into the Lua snippet above in a scene.

You’ll also need to take a few other things into consideration. Since the command most likely will prompt you twice for a password. First one when doing the ssh command and the second for the sudo command. You have a few options:

1.1 Enable root on the linux box and allow root ssh access.
1.2 Create a ssh key (with no password) for vera and add it to linux box root’s authorized key list file.
1.3 Add additional security measures to the authorized key file for only allowing vera’s ip address access via the ssh key,
also only allowing vera to issue the poweroff command only.

2.1 Do step 1.2 but for the user’s account on the linux box.
2.2 Also follow step 1.3
2.3 Allow the poweroff command to be run as you with out requiring sudo.

Option 2 is more secure as it does not gain vera root access and you can keep root locked down.

  • Garrett

I hope the topicstarter would like to share the code he’s making so others can learn from it :slight_smile:

Passwords offcourse should be left out of it :wink:

hi
@ deursen : do you have any success with your server?

because i’m trying to do same thing but with sudo zmpkg.pl

thanks for your attention

Most of the time sudo requires keyboard interaction. In order to issue commands with out having to type a password in and have it work automatically would to create an ssh key with no password for the appropriate account that has access to run the commands that you want. As a safety measure it would be wise to lock down the use of the ssh key either by ip address, command or both. There are many guides available on the net that explains how to issue commands over ssh and how to secure it.

  • Garrett

thank for you answer

i’m thinking that not easy for me but i will try.

Sounds easy (not) but… What do I do after the key is added :-\

Sounds easy (not) but… What do I do after the key is added :-[/quote]
The steps below only allow you to send commands via SSH. This doesn’t give you sudo access (unless you do it at the root user, which I wouldn’t recommend. Also, I tested these with my Vera and a Mac, running 10.8.

  1. Generate SSH key
dropbearkey -t rsa -f ~/.ssh/id_dss
  1. View SSH public key
dropbearkey -y -f ~/.ssh/id_dss
  1. Copy the following from the above to a new line in " ~/.ssh/authorized_keys2" on your Linux box (should be one long line, similar to below, but the “…xxx…” is seemingly random characters):

ssh-rsa Axxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxE= root@MiOS_12345678
NOTE: the “…xxxx…” is your key…do NOT share that!! Well, it is your public key, but I still wouldn’t do posting it around the forum, in case you mistakenly grab your private key.

  1. Now test that you can SSH from Vera to your Linux box.
ssh -i ~/.ssh/id_dss -l <USER> <HOST>

Note: You’ll need to say “y” to accept the remote box key fingerprint.

  1. Now you can send a command via SSH from Vera (change the path/filename):
ssh -i ~/.ssh/id_dss -l <USER> <HOST> 'touch /path/to/dir/touchTest.txt'
  1. You should a new (empty) file created with the “touch” command at the location specified.

Once I do this, I can send a “sleep” command to my Mac OS X box. That doesn’t require sudo, so I don’t have any issues with privilege escalation. I would use the command:

ssh -i ~/.ssh/id_dss -l <USER> <HOST> 'pmset sleepnow'

I just realized I forgot to describe how I tied this all together with LUUP.

With Vera, I had issues sending the SSH command directly from LUUP. I believe since the SSH handshake takes a little while, I think the LUUP code would give up and kill it before it worked.

So I worked around that by having a separate script that ran every minute looking for a specific file. If it found that file, it would issue the sleep command, and delete the file.

Then I had LUUP code do a “touch” on that file when needed.

The effects were not immediate, but close enough. You can make the script run more often if you wanted. I haven’t tried with my Vera3, nor did I explore it that far with Vera2. My file solution worked well enough for me at the time.

Sounds easy (not) but… What do I do after the key is added :-[/quote]
The steps below only allow you to send commands via SSH. This doesn’t give you sudo access (unless you do it at the root user, which I wouldn’t recommend. Also, I tested these with my Vera and a Mac, running 10.8. [/quote]

The only reason I suggested root is that the poster is using sudo and is required to power off the box. By allowing access to root via the ssh key you do have some security risks. But there are a few things to secure it more:

When adding the see key to the root’s ~/.ssh/authorized_keys2 file you can add the following to the beginning of the key:

from="192.168.1.100" no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty,command= "/sbin/poweroff" ssh-rsa Axxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxE= root@MiOS_12345678

A brake down of the extra arguments:

from=192.168.1.100 This is the ip address that is only allowed to use this key (you would use your vera’s ip address.
no-port-forwarding This tells ssh not to allow port forwarding
no-X11-forwarding This tells ssh not to allow x11 forwarding
no-agent-forwarding This tells ssh not to allow agent forwarding
no-pty This tells ssh not to allow terminal access
command=“/sbin/poweroff” The command part tells ssh that the specified command is the only command allowed to run. In this case the poweroff command.

  • Garrett

p.s. forgot to add that you can bypass root for the poweroff command by giving the user you are ssh’ing as permission to run the poweroff command.

The original idea was really pleasant, but the solution seems sooooo complicated …
Isn’t there any easier way to shutdown a Synology NAS with Vera?

Yep … put it on a Z-Wave swith
Or a network controlled switch like: [url=http://www.digital-loggers.com/lpc.html]http://www.digital-loggers.com/lpc.html[/url]

@garrettwp has built a nice little plugin for the latter.

[quote=“RichardTSchaefer, post:13, topic:172513”]Yep … put it on a Z-Wave swith
Or a network controlled switch like: [url=http://www.digital-loggers.com/lpc.html]http://www.digital-loggers.com/lpc.html[/url]

@garrettwp has built a nice little plugin for the latter.[/quote]

not sure it’s a good idea to turn off a NAS by abruptly shutting its power ??? expect file corruptions

Hi guys

Thanks for the lines.
I added a ssh key from my Vera to my Synology NAS.
If i use the terminal i can shut it down using this code

ssh -i ~/.ssh/id_dss -l <USER> <HOST> 'poweroff'

Any idea how about to do that in a luup scene?

I tried os.execute("ssh -i ~/.ssh/id_dss -l root xxx.xxx.x.xxx 'poweroff'") but seems not to be the good way…

Thank you very much for your help.

I also wanted to execute a command on a remote server using SSH from Luup code and a search led me to this thread.

I got as far as @milillicuti but could not get the os.execute command to work either even though everything worked correctly from the command line. After some investigation, I figured out what was wrong and how to fix it.

The problem appears to be a quirk in the Vera environment. When you SSH into Vera the home directory is “/root” as you would expect. But when Luup code is running, the home directory is “/”. And since SSH reads and writes files in a special “.ssh” directory under the home directory, it’s working with two totally different directories when running from the command line versus running from Luup code (“/root/.ssh” vs. “/.ssh”).

The solution is easy: Create a symlink from “/.ssh” to “/root/.ssh” so the two different environments will always use the same directory. This is done by running the following two commands at the Vera command line. The first command deletes the existing “/.ssh” directory, so you may want to look at the contents first to make sure nothing important will be destroyed. Mine contained only an empty known_hosts file, so destroying it was OK.

rm -rf /.ssh
ln -s /root/.ssh /.ssh

With that symlink in place, if you can connect to your remote server successfully from the command line without using a password, then it should also work successfully from within Luup code.

So I can shutdown my server with this Luup code:

os.execute("ssh -y -i ~/.ssh/id_rsa <user>@<server> sudo /sbin/poweroff")

The remote machine also has to be set up properly so the given command can be executed without needing a password. For my remote machine (which is a Linux box), I did this with a sudo config file for the “vera” user. I created the “vera” user specifically so I can control the environment and what commands can be executed when connecting from Vera. I agree with @garrettwp that access should be tightly controlled.

The user-specific sudo config file is “/etc/sudoers.d/vera”:

Defaults:vera !authenticate
vera <your_hostname>=/sbin/reboot,/sbin/poweroff

As a side note, these are the commands I used on Vera to generate the private and public key files:

dropbearkey -t rsa -s 2048 -f ~/.ssh/id_rsa | grep ^ssh-rsa > ~/.ssh/id_rsa.pub
chmod 400 ~/.ssh/id_rsa
chmod 400 ~/.ssh/id_rsa.pub

Then the contents of the public key file “~/.ssh/id_rsa.pub” must be appended to the “~/.ssh/authorized_keys” file on the remote machine.

I have the following command, which when I run it on vera directly suspends my pc without having to enter a password:

ssh -i ~/.ssh/id_dss -l USER IP 'bash -ic suspendnow'

However, when I try this from a scene, it doesn’t work. Any ideas?

os.execute("ssh -i ~/.ssh/id_dss -l USER IP 'bash -ic suspendnow'")

I setup an alias on my linux machine, the “bash -ic” makes this work over ssh.

See microcode’s remark above about home directories.

Hmm, I don’t know how I missed that. Thanks for pointing it out again!

I know this is an old thread but… everyone is still around, sooooo…

I am following this and generated a public key on Vera, VI authorized_keys2 … that create a new file, is that right … I have an authorized_keys file already in /.ssh

… pasted in: (using my generated key and my vera’s MiOS_xxxxx)
ssh-rsa Axxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxE= root@MiOS_12345678

but still my Linux machine is asking for a Password.