1

I'm executing remote commands using Net::OpenSSH using a web frontend. My commands return without failure on the command line, but I get nothing in a web browser. I've done a couple hour research to no avail--any ideas?

Here is some code to give you an example (some removed for obvious reasons).

#!/usr/bin/perl -w
use strict;
use CGI ':standard';
use Net::OpenSSH;
# Here in the code is just the header and standard tags
print "1";
print "2"; # both display
my $ssh = Net::OpenSSH->new($host, user => $uname, key_path => $key); # all works
$ssh- error and die "Can't ssh to host" . $ssh->error;
print "3";
$ssh->system("uname -a") or
die "remote command failed: " . $ssh->error;
my @lsa = $ssh->capture("ls -a");
$ssh->error and
die "remote ls command failed: ". $ssh->error;

print "4";
print "5"; 
print @lsa; # won't display in browser, just terminal/CLI

Cheers!

3
  • 1
    $ssh- error and die ? typo in the sample or worse? :) Commented Aug 8, 2012 at 16:10
  • Also, what does server error log say? Commented Aug 8, 2012 at 16:11
  • And what is the server and OS? Commented Aug 8, 2012 at 16:12

3 Answers 3

1

I maintain CGI.pm. I recommend these additions to your simple script:

  1. Before you print anything else, print the standard HTTP header: print header();
  2. Add this after the use CGI line: use CGI::Carp qw(fatalsToBrowser); ... that will display any run-time problems in the browser. If you don't get any output after these changes, check that the script compiles with perl -cw script.pl
Sign up to request clarification or add additional context in comments.

Comments

0

Below is about the minimum Perl code that worked for me on Debian machine. I suggest you go through it and compare it to your actual code.

However, it did not work out-of-the box on my Debian, I had make some decisions most of which probably aren't very safe, but that's more about specific environment:

  • make home for user that server runs writable (/var/www)
  • add host to ~/.ssh/known_hosts beforehand
  • use the strict_mode => 0 to bypass Net::OpenSSH's security checks instead of finding proper ctl_dir (Net::OpenSSH requires that the folder and all above folders are 0755 or more strict, so /tmp I used is normally not good enough)

I believe there are much safer practices than that, but as I said, that's specific to environment.

So the code:

#!/usr/bin/perl
use strict;
use warnings;

use Net::OpenSSH;
use File::Temp qw/ tempdir /;

# necessary minimum for CGI
print "Content-type: text/plain\n\n";

# prepare temp dir
my $temp = tempdir("/tmp/sshme.pl-XXXXXXXX", CLEANUP => 1);

# open SSH session
my %opts = (
    user        => "user",
    password    => "password",
    ctl_dir     => $temp,
    strict_mode => 0            ## NOT recommended - see my comments
);
my $ssh = Net::OpenSSH->new("host", %opts);
$ssh->error
    and die "Couldn't establish SSH connection: ". $ssh->error;

# perform command and print output
my @lines = $ssh->capture("ls")
    or die "remote command failed: " . $ssh->error;
print @lines;

Comments

0

Perhaps your errors get directed to standard error, not standard output. In that case, they'll usually end up in the server log, not the browser window. Perhaps you can use POSIX::dup2 to avoid this:

use POSIX;

# Make sure to send HTTP headers before redirecting streams!

POSIX::close(2);  # close original stderr stream. No more output to apache logs!!!
POSIX::dup2(1,2); # redirect error stream to standard output, so errors will appear in browser.

Processes launched by perl, like e.g. some ssh binary, will inherit these streams.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.