¯\_(ツ)_/¯

thunder@home:~$

This is my home blog, mostly to share some useful info or code snippets
~ 2 mins

Heya,

I believe, everybody knows how to forward ports from another host in restricted network.

Simple well-known tunnel command

Like, running:

ssh -f -N -4 -L 2222:10.0.0.1:22 user@1.2.3.4

Where:

  • -f – Requests ssh to go to background just before command execution. This is useful if ssh is going to ask for passwords or passphrases, but the user wants it in the background
  • -N – Do not execute a remote command. This is useful for just forwarding ports.
  • -4 – Forces ssh to use IPv4 addresses only to bind local port.
  • -L – Specifies that connections to the given TCP port or Unix socket on the local (client) host are to be forwarded to the given host and port, or Unix socket, on the remote side.
  • 2222 – Local port
  • 10.0.0.1 – IP address of the host inside restricted network
  • 22 - Remote port on that host
  • user@1.2.3.4 – User and address of the host which we have remote access and which has access to the host inside remote network

Close opened tunnel

Use kill

To close this, in general, you need to kill process. To make this more conveninent, we can use this small script:

ps -lef | grep ssh | grep "2222" | awk "{print \$2}" | xargs kill

Use sockets

Run ssh command with:

ssh -f -N -M -S <path-to-socket> -L <port>:<host>:<port> <server>

And to close it, run:

ssh -S <path-to-socket> -O exit <server>

SSH config for this command and more

But I wanted to do the same configuration via SSH config. Here is how to do that.

Host my-remote-port-forward
  HostName 1.2.3.4
  User user
  IdentityFile ~/.ssh/user-private-key
  LocalForward 2222 10.0.0.1:22
  AddressFamily inet
  RequestTTY no
  RemoteCommand bash -c 'echo "Listening on 2222; Press ^C to stop."; read -r -d '' _'

Where:

  • Host my-remote-port-forward – Name our host for convenience :)
  • HostName 1.2.3.4 and User user – is the same as user@1.2.3.4
  • LocalForward 2222 10.0.0.1:22 – is the same as -L 2222:10.0.0.1:22
  • AddressFamily inet – is the same as -4

Regarding -f, I decided not to put this forward into background. Well, closing this background session looks bad for me personally :)

Regarding -N. According to the sources:

case 'N':
  no_shell_flag = 1;
  options.request_tty = REQUEST_TTY_NO;
  break;

this flag does two things:

  • the no_shell_flag only appears in ssh.c and is only enabled for the -W or -N options, otherwise it appears in some logic blocks related to ControlPersist and sanity checking involving background forks. I do not see a way an option could directly set it.
  • according to readconf.c the request_tty corresponds to the RequestTTY option detailed in ssh_config(5).

So, in .ssh/config we should define RequestTTY no and RemoteCommand.

Internets offers many options what to put into RemoteCommand. For example, running /bin/false, or /bin/cat. So, I decided to put following command:

RemoteCommand bash -c 'echo "Listening on 2222; Press ^C to stop."; read -r -d '' _'

It will print hardcoded, yes, message and will remain in foreground until we press Control-C.

And now, we can just run:

ssh my-remote-port-forward

Happy forwarding!

Thank You For Reading