R - Connect via ssh and execute a command - r

I would like to connect via ssh to certain equipment in a network.
The requisites are:
It must run a command and capture the output of the ssh session in R (or in bash, or any other programming language, but I would prefer it in R language)
It must enter a plain-text password (as this equipment hasn't been accessed before, and can't be changed with a rsa keypair), so the ssh.utils package doesn't meet this requirement
sshpass can't be used, as I have noticed that it doesn't work for some devices I tested.
I've read all this posts but I can't find an effective way to perform it: link 1, link 2, link 3, link 4
I know the requirements are hard to accomplish, but thank you for your effort!
EDIT:
Sorry if I didn't make myself understandable. I mean I work locally in R and I want to connect to +3000 devices in all of my network via ssh. It is Ubiquiti equipment, and the only open ports are 80 and 22.
If ssh doesn't work, I will use the RSelenium package for R and extract info from port 80. But first I will try with ssh pory 22 as it is a lot more efficient than opening an emulated browser.
The big problem in all these Ubiquiti equipment is that they have a password to log in. That's why requisite No.2 is needed. When I must enter a server that I know, I spend time setting up the rsa keypair so that I don't have to enter a password everytime I connect to a specific server, but it's impossible (or at least, for me it's impossible) to configure all +3000 Ubiquiti equipment with these keypairs.
That's why I don't use snmp, for example, as this equipment maybe they have it activated or not, or the snmp configuration is mistaken. I mean, I have to use something that's activated by default, and in a way, ordered. And only port 80 and port 22 are activated and I know all the user's and password's equipment.
And sshpass is an utility in UNIX/Linux like this link explains that works for servers but doesn't work for Ubiquiti equipment, as long as I've tested it. So I can't use it.
The command I need to extract the output from is mca-status. Simply by entering that into the console makes it print some stats I will like to get from the Ubiquiti equipment.
Correct me, please, if I am wrong in something I've posted. Thanks.

I think you have this wrong. I also have no idea what you are trying to say in point 2, and I have not idea what point 3 is supposed to say.
Now: ssh is a authentication mechanism allowing you (trusted) access to another machine and the ability to run a command. This can be as simple as
edd#max:~$ ssh bud Rscript -e '2+2'
[1] 4
edd#max:~$
where I invoke R (or rather, Rscript) on the machine 'bud' (my desktop) from a session on the machine 'max' (my server). That command could be anything including something which writes to temporary or permanent files. You can then retrieve those files via scp.
Authentication is handled independently -- on Unix we often use ssh-agent which run in the background and against you authenticate on login.

Finally I solved it using the rPython package and the python's paramiko module, as there was no way to do it purely via R.
library(rPython)
python.exec(python.code = c("import paramiko",
"ssh = paramiko.SSHClient()",
"ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())",
sprintf('ssh.connect("%s", username="USER", password="PASSWORD") ', IP),
'stdin, stdout, stderr = ssh.exec_command("mca-status")',
'stats = stdout.readlines()'))

Related

Problem communicating over a local area network (LAN) with ROS on WSL2

I am a developer of ROS projects. Recently I am trying using ROS(melodic) on WSL2(Windows Subsystem for Linux), and all things works just great. But I got some trouble when I want to use another PC which also in the same local area network(LAN) to communicate with. Before setting the environment variables like "ROS_MASTER_URI, ROS_IP", I know that since WSL 2 work on Hyper-V so the IP show on WSL2 is not the one in the real LAN. I have to do some command like below in order to make everyone in LAN communicate with the specific host:PORT on WSL2.
netsh interface portproxy delete v4tov4 listenport=$port listenaddress=$addr
But here comes a new question:
The nodes which use TCPROS to communicate with each other have a random PORT every time I launch the file.
How can I handle this kind of problem?
Or is there any information on the internet that I can have a look?
Thank you.
The root problem is described in WSL issue #4150. To quote from that thread,
WSL 2 seems to NAT it's virtual network, instead of making it bridged
to the host NIC.
Option 1 - Port forwarding script on login
Note: From #kraego's comment (and the edited question, which I'm just seeing based on the comment), this is probably not a good option for ROS, since the port numbers are randomly assigned. This makes port forwarding something that would have to be dynamically done.
There are a number of workarounds described in that issue, for which you've already figured out the first part (the port forwarding). The primary technique seems to be to create a PowerShell script to detect the IP address and create the port forwarding rules that runs upon Windows login. This particular comment near the top of the thread seems to be the canonical go-to answer, although many people have posted their tweaks or alternatives throughout the very long thread.
One downside - I believe the script that is mentioned there needs to be run at logon since the WSL subsystem seems to only want to run when a user is logged in. I've found that attempting to run a WSL service or instance through Windows OpenSSH results in that instance/service shutting down soon after the SSH session is closed, unless the user is already logged into Windows with a WSL instance opened.
Option 2 - WSL1
I would also propose that, assuming it fits your workflow and if the ROS works on it (it may not, given the device access you need, but not sure), you can simply use WSL1 instead of WSL2 to avoid this. You can try this out by:
Backing up your existing distro (from PowerShell or cmd, use wsl --export <DistroName> <FileName>
Import the backup into a new WSL1 instance with wsl --import <NewDistroName> <InstallLocation> <FileNameOfBackup> --version 1
It's possible to simply change versions in place, but I tend to like to have a backup anyway before doing it, and as long as you are backing up, you may as well leave the original in place.

phpseclib - SSH_AUTH_SOCK not found

I work with another company that is moving from regular FTP to SFTP for their connections. They have informed me that my existing username and password are the same, but that I now need to connect via SFTP on port 22. I have a couple of PHP scripts that do some basic things, like connect to their site, get a directory listing, and upload and download a file each day. Those all work fine on FTP, so I need to just swap out the protocol to SFTP.
After doing some research, the consensus seems to be that phpseclib is the easiest and most robust way to perform SFTP using PHP. My server is running Linux and Apache. I downloaded the library and tried to run just the basic example given by phpseclib, but I get an error:
Notice: SSH_AUTH_SOCK not found in System/SSH/Agent.php on line 244
When I look at Agent.php, I see that the script is looking for SSH_AUTH_SOCK to be defined in either $_SERVER or $_ENV. I must be missing something obvious, but I have no idea how to get past this error.
You are trying to connect to SSH authentication agent (ssh-agent).
When the agent is run, it exports the SSH_AUTH_SOCK environment variable.
What is obviously not happening in your case.
But you didn't tell us, why are you trying to use the agent, if at all. And what did you do to set it up, if anything. So it's difficult to give you a more concrete advice.
See also How is SSH_AUTH_SOCK setup and used by ssh-agent?
Run the bellow command:
eval ssh-agent -s
It works fine for me.

Running remote R session from the local instance of vim

I am using vim-r-plugin to send commands from vim to a running R session (and get back info about object list and auto-completions).
My aim is to get communication between local vim and remote session of R. I manged to send commands to R with screen.vim plugin. However this type of communication was one-way only.
For a while I thought that this is not really possible (or at least not very easy to achieve) however I discovered one site: http://manuals.bioinformatics.ucr.edu/home/programming-in-r/vim-r
The author there mentions accessing remote R sessions from local vim multiple times:
"Flexible code sending options from local vim instances to R sessions on remote machines or among remote machines."
"The vim session can run on a local computer, while the R session can run on the same or a remote system."
However nowhere on that site is there any description telling how to achieve this exactly.
I also asked the same question directly on the gougle-group of vim-r-plugin, and the author replied with an option to run everything remotely: https://groups.google.com/forum/#!topic/vim-r-plugin/293VyyQntZ0 . I managed to do that, but it's not what I am after and I didn't want to bother him any further.
So my question: is it possible? If not directly - maybe there are work-arounds of not having to duplicate my vim configuration on all the remote servers I am using?
Reply after more than half of a year!
I tend to agree with others that it is a better idea to run everything remotely. However, this vimdoc may give what you want to achieve:

Using Erlang SSH Application to execute commands on remote UNIX Servers

I have always used the os:cmd/1 method to call operating system routines. Now, i know that erlang has an ssh application. I would like to know how i can use this module to ssh into a SOLARIS server, run a command and collect the reply. I believe that such an operation would be handled asynchronously. I need an example using the ssh application built into Erlang doing this:
Now, at times we setup SSH KEYS between servers to prevent password prompt especially if one is using a script to execute tasks on remote servers. i am intending to write many Erlang programs or escripts that will interact with many remote servers within our environment. i need a complete example and explanation on how ssh with and/or without password prompt can be handled using erlang ssh application. NOTE: In the screen shot above, the two servers had SSH KEYS set up and so there is no password prompt when ssh is initiated from any of the two.
The correct erlang native API to achieve this is not ssh, which only implements a user-interactive shell for ssh, but instead use ssh_connection. Take a look at ssh_connection:exec/4
To be more complete, use ssh:connect to establish a connection and then using the handler returned from it to connect with ssh_connection:exec/4
I didn't try it myself and can't provide a complete example but the documentation seems to be a good starting point.

What is the best way to change a user-password remotely in Unix?

What is the best way to change a user-password remotely in Unix?
This must be performed by the user, in a Web-app or Windows-App, without using SSH or any direct connection between the user and the server (direct command line not allowed).
Thanks
Webmin seemed to be a good application to do that, but I found it extremely hard to configure it right. My Unix users are unable to login to Webmin or Usermin.
Do you know any other alternatives to Webmin and Usermin?
Thanks
Use Webmin (more specifically the UserMin module).
Webmin provides a mini webserver, so you just need to install and configure it slightly. You'll get a lot more than just password-changing, and you can remove functionality you don't want the user to have.
#Rich Bradshaw
Just make sure you don't introduce security issues. The solution should use https encryption (the password should be never sent in clear text). It should be protected against shell injection attacks (strip any newlines from input, escape it properly etc). More details depend on choosen implementation.
I've done this in the past to change passwords on several servers at once by using a script written in Expect. It's perfect for the job but you will need the servers to be listening via SSH.
Once written, the script will execute on your local workstation and will connect to the remote host, do the interaction you've scripted, and then you should be gold. All the while, using the encryption you're already trusting if you're running SSH. Just don't save the passwords in your script: you should be able to prompt yourself for them (even taking them by command line argument is generally considered poor practice.)
Expect is a great language too: lots of fun!
You could write a server side script that ran passwd, you could do that in any language that allows shell commands to be run.

Resources