Digging Tunnels in Three Directions
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
- Start
/opt/fixtures/nt-http/server.pyon port 9200, bound to127.0.0.1. This is the tunnel's destination. - With local forwarding, open a
19200→127.0.0.1:9200tunnel in the background, and save the result ofcurl -s http://127.0.0.1:19200/okto/root/tun/local.txt. - Check who opened
19200and save it to/root/tun/proof.txt.sshmust be visible in the process name. - With remote forwarding, open
19300on the SSH server side and send it to127.0.0.1:9200, and save the result ofcurl -s http://127.0.0.1:19300/okto/root/tun/remote.txt. - With dynamic forwarding (SOCKS), open
11080, and save the result of requestinghttp://127.0.0.1:9200/okthrough that proxy to/root/tun/socks.txt. - 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. - 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). - Make
/root/tun/report.txtwith the following 3 lines. Each value is the side where that option opens the port.L=local/R=remote/D=local
Notes
- You open a tunnel in the form
ssh -N -f -L 19200:127.0.0.1:9200 -p 2222 -i /root/.ssh/id_labhub root@127.0.0.1. - A request through SOCKS is
curl --socks5-hostname 127.0.0.1:11080 http://127.0.0.1:9200/ok. - For binding to all addresses, you add the address in front, like
-L 0.0.0.0:19201:127.0.0.1:9200. - Common mistake 1: if you open it without
-N, a remote shell attaches and stalls in the background. - Common mistake 2: if you leave out the bind address position of the local forwarding in step 6, it opens only on loopback and cannot be reached through the interface IP.
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.