2012-03-23 21 views
3

私はリモートファイルの内容を読まなければなりません。(sudo)は cat、lessまたはtailで読み込む権限があります。ruby​​ Net :: SSHを使ってsudo経由でリモートファイルを読む

私はこれをRubyでやっているので、Net :: SSHを使っているはずです。

ファイルはログファイルなのでかなり大きい場合があります。

これは私が今しようとしているコードです:

require 'rubygems' 
require 'net/ssh' 

cmd = "sudo cat /var/logs/httpd/ACCESS_log.2012.03.23" 

Net::SSH.start("SERVER" , "USER", :password => "PASSWORD") do |ssh| 
    ssh.open_channel do |channel| 
    channel.request_pty 
    channel.exec(cmd); 

    channel.on_close do 
     puts "shell terminated" 
    end 
    channel.on_eof do |ch| 
     puts "remote end is done sending data" 
    end 
    channel.on_extended_data do |ch, type, data| 
     puts "got stderr: #{data.inspect}" 
    end 
    channel.on_data do |channel, data| 
     if data =~ /^\[sudo\] password for USER:/ 
     puts "data works" 
     channel.send_data 'PASSWORD' 
     end 
    channel.on_data do |ch,data| 
     puts "in third" 
     puts data.inspect 
    end 
    end 
    channel.on_process do |ch| 
    puts "in process" 
    end 
    ssh.loop 
    end 
end 

私は次の出力を得ることを実行すると:プロセスにプロセス でプロセス に

を データはプロセス で の作品プロセス 処理中 3番目 "リモート終了が完了しましたデータの送信 シェル終了

ログには実際には数千行のデータが含まれています。なぜなら、実際のサーバーからパテッティを読み取ることができるからです。

channel.on_dataからどのように取得できますか?

おかげ

+0

、それはプレビュー-on実際のユーザ – DGM

+0

に掛かって、rootユーザーとしてだった、私は自分のログファイルのいずれかでそれを走っていないし、それが正常に動作します...何の待ち時間最初にパスワードを送信するまでには長い時間がかかります。 – user254694

+0

特定のログファイルに内容があることを確認しましたか?あなたがsshを直接使用する場合、あなたは何を見ますか?ssh USER @ SERVER sudo cat/var/logs/httpd/ACCESS_log.2012.03.23' – dbenhur

答えて

1

送信するパスワードに\nを追加する必要があると思います。これは私のために働く。注:私がelse節をコメントアウトした場所では、そこから情報を取得することもできますが、パスワードとして\nをパスワードとして使用しても機能します。

 
require 'rubygems' 
require 'net/ssh' 

cmd = "sudo cat /var/log/mail.log" 
HOSTNAME = "myhost.example.com" 
USERNAME = "me" 
PASSWORD = "12345" 


Net::SSH.start(HOSTNAME , USERNAME, :password => PASSWORD) do |ssh| 
    ssh.open_channel do |channel| 
    channel.request_pty 
    channel.exec(cmd); 

    channel.on_close do 
     puts "shell terminated" 
    end 
    channel.on_eof do |ch| 
     puts "remote end is done sending data" 
    end 
    channel.on_extended_data do |ch, type, data| 
     puts "got stderr: #{data.inspect}" 
    end 
    channel.on_data do |channel, data| 
     if data =~ /^\[sudo\] password for #{USERNAME}:/ 
     puts "data works" 
     channel.send_data "#{PASSWORD}\n" 
     else 
     #puts "OUTPUT NOT MATCHED: #{data}" 
     end 
     channel.on_data do |ch,data| 
     puts "in third" 
     puts data.inspect 
     end 
    end 
    channel.on_process do |ch| 
    puts "in process" 
    end 
    ssh.loop 
    end 
end 
+0

私は@dbenhurに同意します。前のコードブロックを置き換えるので、on_dataを複数回呼び出すのは間違いありません。 。 – DGM

+0

@DGMのように見えますが、パスワードには "\ n"が必要です。私のテストで働いた – dbenhur

0

on_dataコールバックを実行しながら新しいon_dataコールバックを交換します。私はNet :: SSHの内部をspelunkしていないが、それは驚くべき振る舞いを生み出すことができる。

2つのon_dataコールバックのコードを1つに変更し、そのコードが役立つかどうかを確認してください。

channel.on_data do |channel, data| 
    if data =~ /^\[sudo\] password for USER:/ 
    puts "data works" 
    channel.send_data 'PASSWORD' 
    else 
    puts "in third" 
    puts data.inspect 
    if 
end 

ログを読むにはsudoが必要なので、誰かとそのサーバーは保護する価値があると思います。このRubyプログラムでは、サーバに特権アクセスするためのパスワードを埋め込んでいるようです。これは、プログラムを読むことができる誰もが同じ特権アクセスを得ることを意味します。あなたはこのプログラムのパスワードへのアクセスを制限するために何をしますか?

+0

パスワードを埋め込んでいます。でそのソリューションの結果: データプロセス におけるプロセス の処理においては、プロセス でプロセス でプロセス で を働かないし、何も。それは私がそれをそうするように導いた他のコードの例で、事の一つでした。それは再帰的でなければならないものです。 – user254694

-1
require 'net/ssh' 

Net::SSH.start('host', 'user', :password => "password") do |ssh| 
    # capture all stderr and stdout output from a remote process 
    output = ssh.exec!("hostname") 
    puts output 

    # capture only stdout matching a particular pattern 
    stdout = "" 
    ssh.exec!("ls -l /home/jamis") do |channel, stream, data| 
    stdout << data if stream == :stdout 
    end 
    puts stdout 

    # run multiple processes in parallel to completion 
    ssh.exec "sed ..." 
    ssh.exec "awk ..." 
    ssh.exec "rm -rf ..." 
    ssh.loop 

    # open a new channel and configure a minimal set of callbacks, then run 
    # the event loop until the channel finishes (closes) 
    channel = ssh.open_channel do |ch| 
    ch.exec "/usr/local/bin/ruby /path/to/file.rb" do |ch, success| 
     raise "could not execute command" unless success 

     # "on_data" is called when the process writes something to stdout 
     ch.on_data do |c, data| 
     $stdout.print data 
     end 

     # "on_extended_data" is called when the process writes something to stderr 
     ch.on_extended_data do |c, type, data| 
     $stderr.print data 
     end 

     ch.on_close { puts "done!" } 
    end 
    end 

    channel.wait 

    # forward connections on local port 1234 to port 80 of www.capify.org 
    ssh.forward.local(1234, "www.capify.org", 80) 
    ssh.loop { true } 
end 

Latest Document 17.11.25

関連する問題