Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

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
share|improve this question
    
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 8 '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 8 '12 at 15:16
1  
Can you post the output of ssh -v <firewall_IP> <command>? You can also compare it with the output from Linux box. –  Khaled Mar 8 '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 8 '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 8 '12 at 15:49
show 1 more comment

2 Answers

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

share|improve this answer
add comment

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 ...
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.