56

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?

2
  • Do you actually need to make a terminal channel as well, or just the forwarding? Oct 31, 2011 at 1:16
  • 1
    @IgnacioVazquez-Abrams: Just the forwarding. Nov 7, 2011 at 23:37

2 Answers 2

93

Run

ssh -o ExitOnForwardFailure=yes ...

or put

ExitOnForwardFailure yes

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

4
  • Unfortunately I have OpenSSH 4. Can you tell me when this feature was added? Nov 1, 2011 at 1:14
  • 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. Nov 1, 2011 at 6:23
  • 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
    Dec 22, 2016 at 10:24
  • 3
    One can also use ssh -o ExitOnForwardFailure=yes to avoid whitespace and the need for quoting.
    – freespace
    Jan 29, 2019 at 7:17
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

3
  • 2
    The 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. Nov 4, 2011 at 11:43
  • 1
    This 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. Nov 7, 2011 at 17:28
  • @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. Mar 18, 2019 at 13:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .