Net::SSH sudo command hangs after entering password
The first thing you might want to try is using public keys instead of passwords to login. Then also try running the command from the interactive shell.
For example:
(This part really depends on the server/client software you have)
$ ssh-keygen
$ scp .ssh/id-dsa.pub server:
$ ssh server
server$ cat id-dsa.pub >> .ssh/authorizedkeys
$ scp -c "ls"
this should work without any prompts, if the key sharing was successful.
How to run commands by sudo and enter password by ssh .net c#
The most secure way to do it, as already mentioned by a comment, is to use CreateShellStream and just write the password directly to the stream after running the sudo command. The password gets sent just as if you had been using an interactive terminal. This might not be a convenient solution, though, if you don't want to be locked into using an endless stream for the rest of what you want to do. Example:
var promptRegex = new Regex(@"\][#$>]"); // regular expression for matching terminal prompt
var modes = new Dictionary<Renci.SshNet.Common.TerminalModes, uint>();
using (var stream = ssh.CreateShellStream("xterm", 255, 50, 800, 600, 1024, modes))
{
stream.Write("sudo iptables -L -n\n");
stream.Expect("password");
stream.Write("mypassword\n");
var output = stream.Expect(promptRegex);
}
The downside is that your output will include junk you don't really want: control characters, prompts, and everything else that gets sent over the stream.
If you want to avoid using a shell stream then you may be able to (depending on security settings) provide a password via stdin. THIS IS INSECURE because commands get logged in various places and you might be revealing your password to other users with root access. If you're the only user, or if you don't care that everybody else can see your password, then this might be more convenient for you.
Example:
using (var cmd = ssh.RunCommand("echo -e 'mypassword\n' | sudo -S iptables -L -n"))
{
if (cmd.ExitStatus == 0)
Console.WriteLine(cmd.Result);
else
Console.WriteLine(cmd.Error);
}
Finally, it's also possible to have a script print your password to stdin. This way your password won't get logged along with the rest of the command line; but this still isn't much more secure since anyone with root access could potentially read the script and see the password:
using (var cmd = ssh.RunCommand("~/printpasswd.sh | sudo -S iptables -L -n"))
{
if (cmd.ExitStatus == 0)
Console.WriteLine(cmd.Result);
else
Console.WriteLine(cmd.Error);
}
and inside printpasswd.sh:
#!/bin/bash
echo -e 'mypassword\n'
Scripting sudo via SSH behaves strangely when reading from file
You are redirecting stdin
inside your loop:
while read i
do
ssh -t -t $i "sudo ls /root"
done < ip.list
This means that (a) ssh
is no longer connected to your TTY, and (b) it's probably going to eat your input. Ideally, you would redirect input to ssh from /dev/null
and configure sudo
to not require a TTY. However, you can try:
ssh -t $i "sudo ls /root" < /dev/tty
Net::SSH: You must have a TTY to run sudo
This worked for me:
require 'net/ssh'
host = "your.host.com"
user = "user"
password = "your pass"
command = "ls"
Net::SSH.start(host, user, password) do |session|
session.open_channel do |channel|
channel.on_data do |ch, data|
puts "data received: #{data}"
end
channel.request_pty do |ch, success|
if success
puts "pty successfully obtained"
ch.exec(command)
else
puts "could not obtain pty"
end
end
end
session.loop
end
Scripting sudo via SSH behaves strangely when reading from file
You are redirecting stdin
inside your loop:
while read i
do
ssh -t -t $i "sudo ls /root"
done < ip.list
This means that (a) ssh
is no longer connected to your TTY, and (b) it's probably going to eat your input. Ideally, you would redirect input to ssh from /dev/null
and configure sudo
to not require a TTY. However, you can try:
ssh -t $i "sudo ls /root" < /dev/tty
Using the ruby gem net-ssh-multi to execute a sudo command on multiple servers at once
Can you try something like this:
channel.request_pty do |c, success|
if success
command = "sudo YOUR_COMMAND"
c.exec(command) do |c, success|
# Some processing
end
end
end
In this case 'sudo' is inside.
Related Topics
Nested Forms in Rails - Accessing Attribute in Has_Many Relation
How to Get Past "Http://Gems.Rubyforge.Org/ Does Not Appear to Be a Repository" Error Message
Calling Sinatra from Within Sinatra
How to Deal with Memory Leaks in Rmagick in Ruby
301 Moved Permanently After S3 Uploading
How Does Require Rubygems Help Find Rubygem Files
Unix Commands Work on Server But Not in Ruby Ssh Session
How to Get Ruby to Print a Full Backtrace Instead of a Truncated One
Switch Theme in an Existing Jekyll Installation
How to Add to a Serialized Array
How to Write Rake Task to Import Data to Rails App
The Compiler Failed to Generate an Executable File. (Runtimeerror)
How to Find Out Who Is Connected to Actioncable
Disable Sprockets Asset Caching in Development
Ruby: Intersection Between Two Ranges
Error: Failed to Build Gem Native Extension (Ruby Extconf.Rb): MAC Osx