6

I have some Juniper SSG firewalls which I need to manage, and I'd like to be able to send commands to them from some monitoring scripts. I configured SSH access using public keys, and I'm able to automatically login to the firewalls.

When I run SSH interactively, everything works fine:

$ssh <firewall IP>
FIREWALL-> <command>
<command output>
FIREWALL-> exit
Connection to <firewall IP> closed.
$

But when I try to run the command from the command line, it doesn't work:

$ssh <firewall IP> <command>
$

This, of course, works fine when sending a command to a remote Linux box:

$ssh <linux box IP> <command>
<command output>
$

Why is this happening? What is the difference between running SSH interactively and specifying the command to run on the SSH command line?


Update:

It also works fine with a Cisco router. Only these Juniper firewalls seem to behave this way.

From the debug output from SSH, it looks like the connection gets established correctly, but the Juniper box replies with an EOF when sending the command, while instead the Linux box replies with the actual command output:

Linux:

debug1: Authentication succeeded (publickey).
debug1: channel 0: new [client-session]
debug2: channel 0: send open
debug1: Entering interactive session.
debug2: callback start
debug2: client_session2_setup: id 0
debug1: Sending command: uptime
debug2: channel 0: request exec confirm 0
debug2: callback done
debug2: channel 0: open confirm rwindow 0 rmax 32768
debug2: channel 0: rcvd adjust 131072
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
 16:44:44 up 25 days,  1:06,  3 users,  load average: 0.08, 0.02, 0.01
debug2: channel 0: rcvd eof
debug2: channel 0: output open -> drain
debug2: channel 0: obuf empty
debug2: channel 0: close_write
debug2: channel 0: output drain -> closed
debug2: channel 0: rcvd close
debug2: channel 0: close_read
debug2: channel 0: input open -> closed
debug2: channel 0: almost dead
debug2: channel 0: gc: notify user
debug2: channel 0: gc: user detached
debug2: channel 0: send close
debug2: channel 0: is dead
debug2: channel 0: garbage collecting
debug1: channel 0: free: client-session, nchannels 1
debug1: Transferred: stdin 0, stdout 0, stderr 0 bytes in 0.1 seconds
debug1: Bytes per second: stdin 0.0, stdout 0.0, stderr 0.0
debug1: Exit status 0

Juniper:

debug1: Authentication succeeded (publickey).
debug1: channel 0: new [client-session]
debug2: channel 0: send open
debug1: Entering interactive session.
debug2: callback start
debug2: client_session2_setup: id 0
debug1: Sending environment.
debug1: Sending env LANG = en_US.UTF-8
debug2: channel 0: request env confirm 0
debug1: Sending command: get system
debug2: channel 0: request exec confirm 0
debug2: callback done
debug2: channel 0: open confirm rwindow 2048 rmax 1024
debug2: channel 0: rcvd eof
debug2: channel 0: output open -> drain
debug2: channel 0: obuf empty
debug2: channel 0: close_write
debug2: channel 0: output drain -> closed
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug2: channel 0: rcvd close
debug2: channel 0: close_read
debug2: channel 0: input open -> closed
debug2: channel 0: almost dead
debug2: channel 0: gc: notify user
debug2: channel 0: gc: user detached
debug2: channel 0: send close
debug2: channel 0: is dead
debug2: channel 0: garbage collecting
debug1: channel 0: free: client-session, nchannels 1
debug1: Transferred: stdin 0, stdout 0, stderr 0 bytes in 0.2 seconds
debug1: Bytes per second: stdin 0.0, stdout 0.0, stderr 0.0
debug1: Exit status 1
sendmoreinfo
  • 1,742
  • 12
  • 33
Massimo
  • 68,714
  • 56
  • 196
  • 319
  • I think you're assuming the Juniper ssh daemon will invoke a shell to run your commands. Given that it's a limited environment, that assumption may not be valid. – cjc Mar 08 '12 at 15:14
  • You are very probably right (it sure doesn't run a Unix-type shell), but I can run commands interactively, so why can't I do the same from the SSH command line? How is this different at all? – Massimo Mar 08 '12 at 15:16
  • 1
    Can you post the output of `ssh -v `? You can also compare it with the output from Linux box. – Khaled Mar 08 '12 at 15:18
  • @Massimo I don't the limited shell itself is the issue. I think it's more the ssh daemon on the router. There's no guarantee that you're running the equivalent of an OpenSSH sshd; whatever SSH server is running there probably only has the capability of providing you with the equivalent of a TTY, and not the capability of running commands in the shell. – cjc Mar 08 '12 at 15:24
  • How exactly does this affect the SSH client? What does SSH actually do when you specify a command to run on the command line? Doesn't it open a connection and run the command just like you would do interactively? – Massimo Mar 08 '12 at 15:49
  • @Massimo, it doesn't. The clients sends the command and it is up to the server side to decide how to interpret that command. – chutz Dec 16 '12 at 15:57

4 Answers4

1

SSH doesn't allocate a pseudo-TTY when you specify a command to run. Try adding "-t" option to override this.

sendmoreinfo
  • 1,742
  • 12
  • 33
0

Passing the command on the command line is not the same thing as typing commands in the shell. In the first case the shell needs to parse the arguments, and in the latter it needs to read lines from the standard input.

If it is a dumb (or limited, if you prefer to call it) interactive shell it may very well not have been coded to support both (I have seen this behavior in practice). However, since the shell obviously supports typed commands, you would probably have better luck if you just send all commands to its standard input. Like this:

echo command | ssh ...
chutz
  • 7,569
  • 1
  • 28
  • 57
0

Like somebody commented, try adding -t, or even -tt to force it. A similar issue was supposedly fixed with this workaround.

I'm having a related issue to this one in fact, except for me it's working from the CLI, but not working through cron.

vobelic
  • 183
  • 1
  • 5
  • 15
0

this works on an SRX240:

( echo 'sh conf|d s|n'; echo 'quit' ) | ssh root@192.168.1.1 "cli"

This can be further improved by making it use a bash heredoc so you could just paste complete statements in to it, but this example should sufficiently guide you for now.

sjas
  • 305
  • 1
  • 4
  • 12