How to run the commands in Ruby as a root - ruby-on-rails

I am using net/ssh gem in Ruby.
By the following code I can enter into the server from my local machine. But I want to execute the commands on the server by entering as a ROOT.
Normally, I enter into the server as a ROOT by the command
sudo su -
Following is my code.
require 'rubygems'
require 'net/ssh'
list_of_servers = "servers.csv"
username="XYZ"
IO.readlines(list_of_servers).each do |line|
line.chomp!
server = line.split(',')[0]
password = line.split(',')[1]
puts "---- " + server
Net::SSH.start(server, username, :password => password,:verbose => Logger::DEBUG) do |ssh|
result=ssh.exec!("sudo su -")
puts result
end
end
Output I get after entering into server.
D, [2015-11-21T21:48:26.005576 #56654] DEBUG -- io[3fce29cc9548]: received packet nr 15 type 97 len 12
I, [2015-11-21T21:48:26.005628 #56654] INFO -- net.ssh.connection.session[3fce29ce9834]: channel_close: 0
D, [2015-11-21T21:48:26.005796 #56654] DEBUG -- io[3fce29cc9548]: queueing packet nr 11 type 97 len 28
sudo: no tty present and no askpass program specified
Note:
I can successfully log into the server from my local machine but I cannot run the ROOT command (sudo su -).

You have to start tty for that
scenario = []
scenario << ""
scenario << "su"
#session = Net::SSH.start(ip , user,
:password => pass,
:auth_methods => ['password'],
:timeout => 10
)
#session.open_channel do |channel|
channel.request_pty do |ch, success|
ch.send_channel_request("shell") do |shell, success|
shell.on_data do |c, data|
#output << data
end
scenario.each do |s|
cmd = "#{s}\r\n"
shell.send_data(cmd)
end
end
end
end

According to man sudo, if you specify -S before the command, sudo takes the password from stdin.
I tried this both on a terminal and from ruby with success:
(insert your password, and the command you wish to run in the generic example below.)
echo "password" | sudo -S "command"
works for me.

Related

Remote Execute Command using SSH from Rails Application

I have a Rails Application from which I will call one Ruby Definition in the controller, like this.
ssh root#host "uptime" >> /tmp/output
When I doing this, only the /tmp/output is created but not the content.
When I running the same from simple Ruby script its working fine.
my controller definition
def chefclient1
`ssh root#host "uptime" >> /tmp/output`
#time = Time.now
end
my view
= link_to('Start uptime', host_chefclient1_path)
You can use net-ssh gem to access remote host via ssh fo a ruby app. Set your environment up to:
HOSTNAME = 'host'
USER = 'root'
PASS = 'password'
Add to your_helper.rb: something like:
def chefclient1
result = nil
Net::SSH.start( ENV[ 'HOSTNAME' ], ENV[ 'USER' ], :password => ENV[ 'PASS' ] ) do| ssh |
result = ssh.exec! 'uptime'
puts result
end
File.open( '/tmp/output', 'w' ) {| f | f.puts result }
end
And use the helper method as you with from a view.

run the shell script from rails application after login to the remote system

I want to run a shell script from my Rails application. The script is started on the remote server via the net-ssh Gem. Here is my code:
Net::SSH.start('localhost', 'user', :password => '1234', :port => port) do |session|
session.exec!("#{Rails.root}/script/myscript")
end
I have checked that the script is present in my local application. Script is taking about 1 hour for completion. I have two questions:
Is this the right way for doing this?
How can I run the script in the background?
The sample doc says that the simple, and quite proper way to run the Net::SSH session is the following:
HOST = '192.168.1.113'
USER = 'username'
PASS = 'password'
Net::SSH.start( HOST, USER, :password => PASS ) do| ssh |
result = ssh.exec! 'ls'
puts result
end
I recomment to pass at least password argument via shell environment to don't store it in the script plainly. Also you could use micro-optparse gem to pass other argument via command line. So it could be as follows:
require 'micro-optparse'
options = Parser.new do |p|
p.banner = "This is a fancy script, for usage see below"
p.version = "fancy script 0.0 alpha"
p.option :host, "set host", :default => 'localhost'
p.option :host, "set user", :default => ''
end.parse!
Net::SSH.start( options[ :host ], options[ :user ], :password => ENV[ 'PASSWORD' ] ) do| ssh |
result = ssh.exec! 'ls'
puts result
end
And run from command line:
$ bundle exec ./1.rb --host=111.ru --user=user
{:host=>"111.ru", :user=>"user"}
Of course the support for :port argument can be added in the same manner.
Use nohup or screen utitilies to run a script as a service in linux:
result = ssh.exec! "nohup #{Rails.root}/script/myscript"
Why shouldn't it be the right way?
To run a shell script in the background, append & to the command
For example:
session.exec!("#{Rails.root}/script/myscript&")

ssh connection over ruby script

hy
i try to connect in the new server by ruby script
> 1.9.2p320 :038 > Net::SSH.start('192.168.10.80', 'root', :password => 'xxxxx')
> Net::SSH::AuthenticationFailed: root
> from /home/zyriuse/.rvm/gems/ruby-1.9.2-p320/gems/net-ssh-2.7.0/lib/net/ssh.rb:215:in > `start'
> from (irb):38
> from /home/zyriuse/.rvm/rubies/ruby-1.9.2-p320/bin/irb:16:in `<main>'
i dont understand why i get this error because when i try manually everything it's working
i try a lot of thing
require 'net/ssh'
require 'logger'
Net::SSH.start(
'localhost', 'zyriuse',
:keys => [ "~/.ssh/id_dsa.pub" ],
) do |session|
puts "hello "
end
~
zyriuse (Net::SSH::AuthenticationFailed)
Net::SSH.start( 'host',
:password=>'passord',
:port=>22,
:username=>'zyriuse',
... ) do |session|
puts "hello wordl"
end
`start': Net::SSH::AuthenticationFailed
i dont understand why i get all the time the same error
Make sure:
The account is correct
The password is correct
The IP is correct
that ssh root#192.168.10.80 works from your machine, typing the password
The error AuthenticationFailed means just that.

Using Smpp in Ruby on Rails

The need to send and receive SMS messages via Smpp, Register Number, received systemID and password, but fails to connect. Connected to the project gem 'ruby-smpp', to use the example of the getaway this, it only changed the values ​​systemID and password.
in the logs:
<- (BindTransceiver) len = 37 cmd = 9 status = 0 seq = 1364360797 (<systemID><password>)
Hex dump follows:
<- 00000000: 0000 0025 0000 0009 0000 0000 5152 7e5d | ...% ........ QR ~]
<- 00000010: 3531 3639 3030 0068 4649 6b4b 7d7d 7a00 | <systemID>.<password>.
<- 00000020: 0034 0001 00 | .4 ...
Starting enquire link timer (with 10s interval)
Delegate: transceiver unbound
in the console:
Connecting to SMSC ...
MT: Disconnected. Reconnecting in 5 seconds ..
MT: Disconnected. Reconnecting in 5 seconds ..
MT: Disconnected. Reconnecting in 5 seconds ..
MT: Disconnected. Reconnecting in 5 seconds ..
MT: Disconnected. Reconnecting in 5 seconds ..
Tell me, please, I do not, maybe in the config to something else to add or change? And smpp connection, as I understand, it works only with a specific IP-address, but the logs on the server and on the local machine are the same
class Gateway
include KeyboardHandler
# MT id counter.
##mt_id = 0
# expose SMPP transceiver's send_mt method
def self.send_mt(*args)
##mt_id += 1
##tx.send_mt(##mt_id, *args)
end
def logger
Smpp::Base.logger
end
def start(config)
# The transceiver sends MT messages to the SMSC. It needs a storage with Hash-like
# semantics to map SMSC message IDs to your own message IDs.
pdr_storage = {}
# Run EventMachine in loop so we can reconnect when the SMSC drops our connection.
puts "Connecting to SMSC..."
loop do
EventMachine::run do
##tx = EventMachine::connect(
config[:host],
config[:port],
Smpp::Transceiver,
config,
self # delegate that will receive callbacks on MOs and DRs and other events
)
print "MT: "
$stdout.flush
# Start consuming MT messages (in this case, from the console)
# Normally, you'd hook this up to a message queue such as Starling
# or ActiveMQ via STOMP.
EventMachine::open_keyboard(KeyboardHandler)
end
puts "Disconnected. Reconnecting in 5 seconds.."
sleep 5
end
end
# ruby-smpp delegate methods
def mo_received(transceiver, pdu)
logger.info "Delegate: mo_received: from #{pdu.source_addr} to #{pdu.destination_addr}: #{pdu.short_message}"
end
def delivery_report_received(transceiver, pdu)
logger.info "Delegate: delivery_report_received: ref #{pdu.msg_reference} stat #{pdu.stat}"
end
def message_accepted(transceiver, mt_message_id, pdu)
logger.info "Delegate: message_accepted: id #{mt_message_id} smsc ref id: #{pdu.message_id}"
end
def message_rejected(transceiver, mt_message_id, pdu)
logger.info "Delegate: message_rejected: id #{mt_message_id} smsc ref id: #{pdu.message_id}"
end
def bound(transceiver)
logger.info "Delegate: transceiver bound"
end
def unbound(transceiver)
logger.info "Delegate: transceiver unbound"
EventMachine::stop_event_loop
end
end
module KeyboardHandler
include EventMachine::Protocols::LineText2
def receive_line(data)
sender, receiver, *body_parts = data.split
unless sender && receiver && body_parts.size > 0
puts "Syntax: <sender> <receiver> <message body>"
else
body = body_parts.join(' ')
puts "Sending MT from #{sender} to #{receiver}: #{body}"
SampleGateway.send_mt(sender, receiver, body)
end
prompt
end
def prompt
print "MT: "
$stdout.flush
end
end
/initializers
require 'eventmachine'
require 'smpp'
LOGFILE = Rails.root + "log/sms_gateway.log"
Smpp::Base.logger = Logger.new(LOGFILE)
/script
puts "Starting SMS Gateway. Please check the log at #{LOGFILE}"
config = {
:host => '127.0.0.1',
:port => 6000,
:system_id => <SystemID>,
:password => <Password>,
:system_type => '', # default given according to SMPP 3.4 Spec
:interface_version => 52,
:source_ton => 0,
:source_npi => 1,
:destination_ton => 1,
:destination_npi => 1,
:source_address_range => '',
:destination_address_range => '',
:enquire_link_delay_secs => 10
}
gw = Gateway.new
gw.start(config)
file from the script / run through the rails runner
Problem solved. Initially were incorrectly specified host and port, as smpp-server was not on the same machine as the RoR-application. As for encoding, sending in Russian layout should be
message = text.encode ("UTF-16BE"). force_encoding ("BINARY")
Gateway.send_mt (sender, receiver, message, data_coding: 8)
To receive a form in the right
message = pdu.short_message.force_encoding ('UTF-16BE'). encode ('UTF-8')

Delayed_Job executing rake not redirecting output

I have a class which is currently being executed via delayed job. One of the tasks is to execute "rake spec" and redirect the output.
I do this as such:
class Executor
def execute_command(cmd, &block)
STDOUT.sync = true # That's all it takes...
IO.popen(cmd + " 2>&1") do |pipe| # Redirection is performed using operators
pipe.sync = true
while str = pipe.gets
block.call str # This is synchronous!
end
end
return $?.success?
end
end
However, none of the output appears and it doesn't even aware to execute the unit tests correctly.
Capistrano works and it works on OSX. My server is Ubuntu running Passenger.
Anyone have any ideas why the output wouldn't be redirecting?
Thanks
Ben
Try without the STDFDES redirection on cmd
here is what i used and what i get.
class Executor
def execute_command(cmd, &block)
STDOUT.sync = true # That's all it takes...
IO.popen(cmd) do |pipe| # Redirection is performed using operators
pipe.sync = true
while str = pipe.gets
block.call str # This is synchronous!
end
end
return $?.success?
end
end
Tested with:
ex = Executor.new
ex.execute_command "ps aux" do |str|
p str
end
result:
"USER PID %CPU %MEM VSZ RSS TT STAT STARTED
TIME COMMAND\n" "mitch 423 3.4 1.0 2750692 159552 ??
S 23Apr12 19:41.59 /Users/mitch/iTerm.app/Contents/MacOS/iTerm
-psn_0_40970\n" "_windowserver 90 3.1 1.8 3395124 301576 ?? Ss 20Apr12 75:19.86
/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Resources/WindowServer
-daemon\n" "mitch 78896 2.0 0.8 1067248 136088 ?? R Thu03PM 37:46.59 /Applications/Spotify.app/Contents/MacOS/Spotify
-psn_0_4900012\n" "mitch 436 1.8 1.0 1063952 169320 ?? S 23Apr12 100:23.87
/Applications/Skype.app/Contents/MacOS/Skype -psn_0_90134\n"

Resources