Simple docker image binds local ports proxied to remote host/ports. This can be useful to be able to expose ports to a docker network for development, and also just as a general-purpose persistent port proxy. The system supports proxying to both hosts/ports which are directly accessible, as well as to remote hosts/ports via SSH tunnels.
The container expects to be called with one or more proxy/port arguments of the form:
<BIND_PORT>:<HOSTNAME>:<PORT>
Where <BIND_PORT>
is the port to bind/listen to on the local container
and <HOSTNAME>:<PORT>
is the remote host and port to proxy to. This is
just based on the format of ssh port forwards (which is what is used internally).
The <HOSTNAME>
value can also reference a remote SSH server to login to. This
is specified with the special extended proxy/port argument format:
<BIND_PORT>:<USER>@<SSH_HOST>/<SSH_PORT>^<FAR_HOSTNAME>:<PORT>
Starting in version 0.4, the bind port may be on the remote host instead of the local host (i.e. SSH remote port forward) using this further extended format:
<REMOTE_BIND_ADDR>~<REMOTE_BIND_PORT>:<USER>@<SSH_HOST>/<SSH_PORT>^<FAR_HOSTNAME>:<PORT>
See the remote bind ports section below for further details.
In order for this format to work, you must also supply a valid SSH private key which can be used to login to the remote SSH server. See the remote SSH ports section below for details.
This example command will bind port 2222
on the local docker host to
port 22
on the remote host some-host
:
docker run -it --rm -p 2222:2222 rapi/proxy-hub 2222:some-host:22
This is just like setting up an SSH tunnel, except you don't need to login to anything and it will stay up as long as the container is running.
This allows you to expose proxied ports as a service, for example:
docker create \
--name proxy-svc --hostname=proxy-svc --restart=always \
-p 2222:2222 -p 3309:3309 -p 3389:3389 \
rapi/proxy-hub \
2222:some-host:22 3309:10.23.56.8:3306 3389:windows-box:3389
docker start proxy-svc && docker logs --follow proxy-svc
You can also use this image to glue-in ports to a docker network to be accessible from other containers running in that network. For example:
docker create \
--name dbhost --hostname=dbhost --restart=always \
--net mynet \
rapi/proxy-hub 3306:mysql-server:3306
docker start dbhost
This will allow other containers running in the mynet
docker network to
access the proxied mysql server via the native hostname dbhost
It is also possible to proxy ports via tunnels to remote SSH servers. This is done by suppling the remote hostname in the extended format:
<BIND_PORT>:<USER>@<SSH_HOST>^<FAR_HOSTNAME>:<PORT>
This tells the system to use <SSH_HOST>
as the intermediary to get to the
<FAR_HOSTNAME>
. By default the system will attempt to connect to the ssh server
on the default port 22
, but a different port (<SSH_PORT>
) can also be supplied:
<BIND_PORT>:<USER>@<SSH_HOST>/<SSH_PORT>^<FAR_HOSTNAME>:<PORT>
This also requires supplying an SSH key which can be used to authenticate with the remote
server (as <USER>
) which is be done by mounting the SSH key file (i.e. an identity
file generated by ssh-keygen
) under the /opt/ids/
directory. For example:
docker run -it --rm \
-p 3389:3389 \
-v ~/.ssh/id_rsa:/opt/ids/id_rsa \
rapi/proxy-hub \
3389:root@ssh-host^win-box:3389
The special remote hostname format is triggered by the presence of an @
in the
middle field, with the remote hostname (i.e. the address which can be accessed from the
remote ssh host) following the ^
character.
The system will use all valid SSH keys found under /opt/ids/
to attempt to
authenticate with the remote ssh server. Multiple key files can be supplied as well as
multiple remote forwards. The filenames don't matter. The system will simply try all
available keys on all remote hosts specified. These can be mounted with multiple -v
options, or a whole directory of key files can be mounted on /opt/ids
directly.
For each remote proxy argument setup, the system will fork a separate thread and attempt
to connect to it continuously. This design allows for the possibility of setting up multiple
layers of remote forwards at once. For instance, let's say the box win-box
is accessible
only from the SSH host priv-gateway
which is intern accessible from the SSH host
pub-gateway
. Assuming you have valid SSH keys for both priv-gateway
and
pub-gateway
, you could proxy port 3389
all the way to win-box
like this:
docker run -it --rm \
-p 3389:3389 \
-v /path/to/pub-gateway_id:/opt/ids/pub-gateway_id \
-v /path/to/priv-gateway_id:/opt/ids/priv-gateway_id \
rapi/proxy-hub \
2222:root@pub-gateway^priv-gateway:22 \
3389:root@localhost/2222^win-box:3389
In this case, root@localhost/2222
is actually the SSH server at priv-gateway
which
we mapped locally on 2222
in the previous remote proxy argument. The tunnel for port
3389
won't be able to come up unless and until the port 2222
tunnel does. Because
all tunnels continuously try to up themselves in a loop, it doesn't matter what order this
happens in.
New in version 0.4.
SSH remote port forwards are also supported by supplying the special tilde (~) delimiter in
the <BIND_PORT>
in the format <REMOTE_BIND_ADDR>~<REMOTE_BIND_PORT>
.
For example:
docker run -it --rm \
-v /path/to/near_host_id:/opt/ids/id_rsa \
rapi/proxy-hub \
*~2224:root@near-host^far-host:22 \
This example command will bind port 2224
of all IP addresses on near-host
to port 22
of far-host
. Note that in this case, far-host
is resolved and connected to from near-host
not from the local host. far-host
need not be accessible from the local system as long as
it is accessible from near
. Also, note that since in this example we are only doing a remote
port forward, there is no need to supply a -p
argument to open the port on the local docker
host.
Instead of binding the wildcard address on near-host
we could also bind to a specific IP
address on near-host
like this: 10.0.0.5~2224:root@near-host^far-host:22
. Again, in this
example, 10.0.0.5 must be a valid IP address on near-host
. Additionally, the remote bind
address can be omitted altogether in which case the wildcard *
denoting all addresses will
be used: ~2224:root@near-host^far-host:22
If set to true, the internal ssh commands will be run with debug messages enabled.
New in version 0.4 - allows setting a specific debug level for the ssh command, between 0 and 3.
For example, if set to 1
the argument -v
is passed to the ssh command, if set to 3
the
argument -vvv
is used. Any value greater than 0
implies DEBUG=1