TT Lab
Get started
Learn Learning paths Courses

SSH and File Transfer

Digging Tunnels in Three Directions

Continue in TT Lab

Goal

You build all three forwardings, -L, -R, and -D, and check for yourself where each tunnel opens its port.

Why it matters

Forwarding is all easy as long as you do not mix up the direction. -L opens a port on my side, -R opens a port on the other side, and -D sets up a SOCKS proxy on my side. And the host name in the middle of -L is resolved from the SSH server's point of view — it does not matter if the name does not resolve on my side. This one fact is nearly all of connecting through a bastion.

In this lab the SSH server is 127.0.0.1:2222. The server and client are the same host, so you can check the -R result right away.

Steps

  1. Start /opt/fixtures/nt-http/server.py on port 9200, bound to 127.0.0.1. This is the tunnel's destination.
  2. With local forwarding, open a 19200 → 127.0.0.1:9200 tunnel in the background, and save the result of curl -s http://127.0.0.1:19200/ok to /root/tun/local.txt.
  3. Check who opened 19200 and save it to /root/tun/proof.txt. ssh must be visible in the process name.
  4. With remote forwarding, open 19300 on the SSH server side and send it to 127.0.0.1:9200, and save the result of curl -s http://127.0.0.1:19300/ok to /root/tun/remote.txt.
  5. With dynamic forwarding (SOCKS), open 11080, and save the result of requesting http://127.0.0.1:9200/ok through that proxy to /root/tun/socks.txt.
  6. Open one more local forwarding, but this time bind to all addresses, send 19201 → 127.0.0.1:9200, and save the result of connecting through your own interface IP to /root/tun/gateway.txt.
  7. Save the command lines of the ssh tunnel processes currently running to /root/tun/inventory.txt. There must be at least 4 lines (two -L, one -R, and one -D).
  8. Make /root/tun/report.txt with the following 3 lines. Each value is the side where that option opens the port. L=local / R=remote / D=local

Notes

Starting the backend service

Start /opt/fixtures/nt-http/server.py on port 9200, bound to 127.0.0.1. This is the tunnel's destination.

You need a service to be the tunnel's destination. Even if you start it only on loopback, it is reachable through the tunnel.

Local forwarding

With local forwarding, open a 19200 → 127.0.0.1:9200 tunnel in the background, and save the result of curl -s http://127.0.0.1:19200/ok to /root/tun/local.txt.

After -L you write three values joined by colons. The host in the middle is resolved from the SSH server's point of view.

Checking the port the tunnel opened

Check who opened 19200 and save it to /root/tun/proof.txt. ssh must be visible in the process name.

If you look at the listening sockets with ss, the process name comes out. For a tunnel, the ssh process opens the port.

Remote forwarding

With remote forwarding, open 19300 on the SSH server side and send it to 127.0.0.1:9200, and save the result of curl -s http://127.0.0.1:19300/ok to /root/tun/remote.txt.

-R opens the port on the SSH server side. In this lab the server is the same host, so you can check the result right away.

SOCKS proxy

With dynamic forwarding (SOCKS), open 11080, and save the result of requesting http://127.0.0.1:9200/ok through that proxy to /root/tun/socks.txt.

-D takes just one port. curl has an option to specify a SOCKS5 proxy.

Binding to an outside address

Open one more local forwarding, but this time bind to all addresses, send 19201 → 127.0.0.1:9200, and save the result of connecting through your own interface IP to /root/tun/gateway.txt.

You can additionally write a bind address in front of -L. There is also a way using the -g option.

Organizing the tunnel list

Save the command lines of the ssh tunnel processes currently running to /root/tun/inventory.txt. There must be at least 4 lines (two -L, one -R, and one -D).

If you look at the command lines of the ssh processes currently running, you can tell the direction of each tunnel.

Three-direction comparison table

Make /root/tun/report.txt with the following 3 lines. Each value is the side where that option opens the port. L=local / R=remote / D=local

The key difference is where the port opens. Write the values as local or remote.