Can I make SSH fail when a port forwarding fails?

39

5

If I do a remote port forward, a la -R 3690:localhost:3690 when a binding already exists on the port on the remote host, I get this warning:

Warning: remote port forwarding failed for listen port 3690

Is there a way to have ssh fail (i.e. exit with a nonzero return code), rather than just emit a warning?

Matt Joiner

Posted 2011-10-31T01:13:46.077

Reputation: 825

Do you actually need to make a terminal channel as well, or just the forwarding? – Ignacio Vazquez-Abrams – 2011-10-31T01:16:28.103

1@IgnacioVazquez-Abrams: Just the forwarding. – Matt Joiner – 2011-11-07T23:37:19.430

Answers

64

Run

ssh -o "ExitOnForwardFailure yes" ...

or put

ExitOnForwardFailure yes

into ~/.ssh/config. See man ssh_config for details.

Andrew Schulman

Posted 2011-10-31T01:13:46.077

Reputation: 2 696

Be aware that if you don't explicitly specify the bind_address then ssh might still not fail. For example if another user is already listening on ipv6 localhost [::1]:3690 then ssh may bind only ipv4 127.0.0.1:3690 and does not complain. But your svn client would probably prefer the ipv6 socket (of the attacker). To be safe better use -R [::1]:3690:localhost:3690 -R 127.0.0.1:3690:localhost:3690 – rudimeier – 2016-12-22T10:24:30.590

3One can also use ssh -o ExitOnForwardFailure=yes to avoid whitespace and the need for quoting. – freespace – 2019-01-29T07:17:35.800

Unfortunately I have OpenSSH 4. Can you tell me when this feature was added? – Matt Joiner – 2011-11-01T01:14:35.257

2

No, I don't know that. It may be a version 5 feature. But version 4 must be many years old now, and there are security fixes all the time. If you can't upgrade the server yourself, you may want to ask your server admin if s/he thinks it's safe to keep using that version.

– Andrew Schulman – 2011-11-01T06:23:08.953

1

I use bash script on the target host to make sure the forwarding was opened correctly. The SSH connection will run this and exit if there's a problem with the port forwarding, e.g.

client side script: ( this uses .ssh/config for port forwarding settings )

#!/bin/bash    

while true; do
    echo -n starting at : "
    date
    ssh user@server bin/sshloop.sh
    echo "got back, sleeping 17 "
    sleep 17
done 

server side script ( bin/sshloop.sh )

#!/bin/bash

while true; do 
  echo $(date)" : SSH Reverse 1090:80, 1232:22 From Server to Client"
  sleep 17
  if ! netstat -an | grep -q ":::1090 " ; then
     echo "1090 forward missing, bailing out"
     exit
  fi
done

Maybe even run the client side script under screen with -dmS

Antti Rytsölä

Posted 2011-10-31T01:13:46.077

Reputation: 329

@AnttiRytsöläCirclesConsult: Note that you might need to check the process ID, as e.g. matching on "ssh" as process name still doesn't tell you which of the SSH clients is currently forwarding that port. – Piskvor left the building – 2019-03-18T13:11:10.967

2The case I'm trying to avoid is that a port forward already exists, and a warning is given. I think this script will treat an existing binding to the port as success, rather than failure. – Matt Joiner – 2011-11-04T11:43:39.870

1This is true. My problem was with the same script holding the port open for a few minutes before timing out. Thsi script would exit and rerun a few times after which the port would be open again. If you need to know for sure who owns the port you could try running netstat -anp with sudo and grepping that. – Antti Rytsölä – 2011-11-07T17:28:17.450