Net::SSH sudo command hangs after entering password

前端 未结 6 1492
囚心锁ツ
囚心锁ツ 2020-12-09 13:53

I\'ve been trying to write a small library using Thor to help assist me in quick creating new projects and sites. I wrote this small method:

def ssh(cmd)
           


        
相关标签:
6条回答
  • 2020-12-09 14:02

    Actually in the end, I did something very similar to Riba's suggestion (although his/her code is much better and smarter, I think)

    def ssh(env, cmd, opts={})
        Net::SSH.start( config[env]["ip"], config[env]["user"], :port => config[env]["port"]) do |session|
            cmd = "sudo #{cmd}" if opts[:sudo]
            print cmd
            session.exec cmd
        end
    end
    
    0 讨论(0)
  • 2020-12-09 14:04

    I cheated by doing adding this:

    sudouser  ALL=(ALL:ALL) NOPASSWD: ALL
    

    to /etc/sudoers

    Also, be sure to use visudo when editing!!!

    0 讨论(0)
  • 2020-12-09 14:07

    It's possible to set it up with net/ssh, but it's really too much effort, just execute ssh command like this:

    system("ssh", "-t", "#{user}@#{host}", "sudo cp #{file_from_path} #{file_to_path}")
    

    This -t means to allocate a tty. Without it it will still work, but your password will be seen in clear.

    (I assume you intend to type sudo password manually. If not, go the authorized keys way).

    0 讨论(0)
  • 2020-12-09 14:15

    Here is a possible solution :

    def ssh(cmd)
      Net::SSH.start( server_ip, user, :port => port) do |session|
        result = nil
        session.exec!(cmd) do |channel, stream, data|
          if data =~ /^\[sudo\] password for user:/
            channel.send_data 'your_sudo_password'
          else
            result << data
          end
        end
        result # content of 'cmd' result
      end
    end
    

    But with this solution, you have your root password writen in clear in a script file somewhere ...

    0 讨论(0)
  • 2020-12-09 14:17

    I hope this will help someone searching. I also needed to sudo during deployment (restarting thin instances)

    # deploy.rake
    require 'net/ssh'
    
    # INITIALIZE CONSTANTS HERE
    HOST = 'yourwebsite.com'
    USER = 'admin'
    PASSWORD = 'your server password' # or use ENV variables?
    # etc.
    
    namespace :deploy do 
      namespace :staging do  
        task :restart do
          commands = [
            "cd #{PATH_TO_STAGING_APP} && git checkout master",
            "git reset --hard HEAD",
            "git pull origin master",
            "bundle install --without test development",
            "sudo thin restart -C /etc/thin/#{STAGING_APP}.yml"
          ]
    
          Net::SSH.start(HOST, USER, :password => PASSWORD) do |ssh|
            ssh.open_channel do |channel|
              channel.request_pty do |ch, success|
                if success
                  puts "Successfully obtained pty"
                else
                  puts "Could not obtain pty"
                end
              end
    
              channel.exec(commands.join(';')) do |ch, success|
                abort "Could not execute commands!" unless success
    
                channel.on_data do |ch, data|
                  puts "#{data}"
                  channel.send_data "#{PASSWORD}\n" if data =~ /password/
                end
    
                channel.on_extended_data do |ch, type, data|
                  puts "stderr: #{data}"
                end
    
                channel.on_close do |ch|
                  puts "Channel is closing!"
                end
              end
            end
            ssh.loop
          end
        end
      end
    end
    

    Note that one channel can only execute one command. Hence I chained the commands together with commands.join(';')

    Reference: Net::SSH::Connection::Channel

    0 讨论(0)
  • 2020-12-09 14:18

    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.

    0 讨论(0)
提交回复
热议问题