When a http(s) connection is made to a balena public URL like https://uuid.balena-devices.com, it first reaches the balena cloud and it is then tunnelled over a VPN to the device. On the device, a process named ‘balena-engine-proxy’ (balena’s counterpart to ‘docker-proxy’) receives the traffic on port 80, as can be seen by running the commands
ps on a host OS terminal:
$ lsof -i :80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
balena-en 1189 root 6u IPv6 16338 0t0 TCP *:http (LISTEN)
$ ps | grep 1189
1189 root 844m S /usr/bin/balena-engine-proxy -proto tcp -host-ip 0.0.0.0 -host-port 80 -container-ip 172.19.0.2 -container-port 80
The app container to which traffic is forwarded by ‘balena-engine-proxy’ depends on the docker-compose.yml ‘ports’ instruction:
Your best bet is probably to have ssh to listen on port 80 in an appropriately configured app container, rather than on the host OS. This is also more flexible because you have more control over what gets installed and run in an app container, compared to the host OS. Inside the app container, a useful Linux command to inspect the listening ports is
netstat. In one of my app containers, I get:
$ netstat -ant
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
tcp 0 0 172.19.0.2:80 188.8.131.52:52670 ESTABLISHED
The output above shows that a process is listening on port 80 – in my case a web server, but it could be the ssh process in your case – and ‘184.108.40.206’ is one of the balena cloud IP addresses for the public URL VPN tunnel.
If the explanation above hasn’t revealed why your setup isn’t working, I would need to understand a bit more about what exactly you are running:
- What are your port forwarding endpoints? A command like:
ssh -L 123:someDestination.com:456 user@someIntermediate.com
involves 3 (end)points, so to speak:
- The machine/device where the ssh command is run, where a socket listens on port 123;
- The “intermediate” machine/device (‘someIntermediate.com’) that runs the ssh server;
- The port forwarding destination (‘someDestination.com’ port 456) to which traffic from port 123 is forwarded via the intermediate machine/device.
- The various web frontends you mentioned, are they all running inside a single app container in the balena device? Or each web frontend in a separate app container? Or maybe the web frontends are not running on the device?
- When you say that “remote port forwarding to a public server works fine”, what are the 3 endpoints as described above?
Having said all that, I would also suggest that you to consider running a haproxy container as an alternative to ssh port forwarding, as done in the following sample project:
This has the advantage that you could run several web frontends simultaneously, rather than one at a time, disambiguating through URL paths. Thanks to balena’s platform, proxy config changes are only a ‘git push’ away!