Alexandre Ardhuin Alexandre Ardhuin - 2 months ago 12
Linux Question

How to access a host port (bind with ssh -R) from a container?

Using Docker 1.12.1, I face a strange behaviour trying to access a host port created with

ssh -R
.

Basically I try to access a service running on port 12345 on my local machine from a docker container running on a server.

I opened a ssh connection with
ssh -R *:12345:localhost:12345 user@server
to open a port
12345
on
server
that forwards to port
12345
on my local machine.

Now when I try
curl https://172.17.42.1:12345
inside the container (
172.17.42.1
is the IP to access the docker host from the docker container) I get :

root@f6873fe1109b:/# curl https://172.17.42.1:12345
curl: (7) Failed to connect to 172.17.42.1 port 12345: Connection refused


But on
server
the command
curl http://localhost:12345
succeeds (eg. no Connection refused)

server$ curl http://localhost:12345
curl: (52) Empty reply from server


I don't really understand how the port binding done with ssh differs from a test with
nc
on server (it works) :

# on server
nc -l -p 12345
# inside a container
root@f6873fe1109b:/# curl http://172.17.42.1:12345
curl: (52) Empty reply from server


NB: the container was started with
docker run -it --rm maven:3-jdk-8 bash
.

What can I do to allow my container to access the host port corresponding to a ssh binding ?

Answer

From man ssh:

-R [...]

... Specifying a remote bind_address will only succeed if the server's GatewayPorts option is enabled

And man sshd_config:

GatewayPorts

Specifies whether remote hosts are allowed to connect to ports forwarded for the client. By default, sshd(8) binds remote port forwardings to the loopback address. This prevents other remote hosts from connecting to forwarded ports. GatewayPorts can be used to specify that sshd should allow remote port forwardings to bind to non-loopback addresses, thus allowing other hosts to connect. The argument may be “no” to force remote port forwardings to be available to the local host only, “yes” to force remote port forwardings to bind to the wildcard address, or “clientspecified” to allow the client to select the address to which the forwarding is bound. The default is “no”.

This means that a default sshd server installation only allows to create forwards that bind to the local interface. If you want to allow forwards to other interfaces then loopback, you need to set the GatewayPorts option to yes or clientspecified in your /etc/ssh/sshd_config