Today I spent too much time debugging an SSH tunnel problem. Thus I decided to browse through my shell history and gather my ssh tunnel know-how.
Access an intranet resource from remote
In the following simplified example we access an internally hosted git repository from outside the intranet.
We use the
-L option of ssh to “Specifies that the given port on the local (client) host is to be forwarded to the given host and port on the remote side”.
The syntax is
With the following command you can access the git repository at
$ ssh -L localhost:54321:gitblit.server:12345 devop@remote-gateway
This scenario has been described previously in Accessing a Git Repository through multiple Remotes.
Create a SOCKS proxy
If you ask wikipedia - a SOCKS server proxies TCP connections to an arbitrary IP address, and provides a means for UDP packets to be forwarded.
The following command starts a SOCKS proxy on port
$ ssh -D 8124 devop@<gateway-server> -N
Given you configure your browser (or OS) to use the SOCKS proxy created above your would have access to the wiki in your intranet…
Exposing an SSH tunnel to the public network interface of a remote server
Finally, the scenario that motivated this post… I wanted to expose a service running on my developer machine to a static public IP address backed by a server running in the wild.
Usually our services regardless of production, staging or development are running behind an Nginx. But this use-case was special. I wanted to create a tunnel that exposes a port from my developer machine to a publicly available network interface.
Starting from my shell history I created a tunnel using the
This option specifies that the given port on the remote (server) host is to be forwarded to the given host and port on the local side.
The syntax is
I wanted to demo a service running locally via a publicly available server:
$ ssh -R remote-gateway:10080:localhost:8080 devop@remote-gateway -N
No success. The tunnel is bound to the loopback address of the server.
Finally I found the missing piece in this post: How to make ssh tunnel open to public?
sshd(8) (the SSH server) binds remote port forwardings to the loopback address.
Without changing the server side configuration there is no way for the client to create a tunnel exposed to the open.
A reasonable default on second thought.
This behaviour can be changed with the option
…and restarting the ssh service:
service ssh restart.
clientspecifiedallows the client to select the address to which the forwarding is bound.
For more details use
man sshd_config locally or check the man page online at SSHD_CONFIG(5).
Let’s check the tunnel with
$ netstat -tlpn | grep 10080 tcp 0 0 <public_ip remote-gateway>:10080 0.0.0.0:* LISTEN -
A special thanks goes to Markus for helping me on this one with his
netstat know-how and patience!
Add and list a private key to the authentication agent
Just provide the private key to add to the tool
$ ssh-add .ssh/id_rsa
-l as only parameter to list currently available keys:
$ ssh-add -l
Validate local keys against GitHub deploy keys
$ ssh-add -l -E MD5 4096 MD5:01:23:45:67:89:ab:cd:ef:gh:01:23:45:67:89:ab:cd /Users/devop/.ssh/my_build_rsa (RSA)
Last, but not least a nice tool to manage ssh tunnels: Coccinellida - is A Simple SSH Tunnel Manager written in Cocoa for Mac OS X.
It uses Mac OS X system provided ssh client to create secured tunnel connections to remote servers