Let me take you on an adventure.

Today I needed to access a service inside a corporate network, but the service is firewalled from external use, and also from access via the VPN.

The suggestion was to use a machine already internal to the network and some port forwarding to get around this restriction. Ahah, I can get around this with a small container on the OpenShift cluster I thought.

So I need a tiny container just for forwarding ports. Google turned up - https://github.com/derkork/socat-openshift.

A quick check of the Dockerfile to make sure there is nothing malicious and lets give it a try:

oc new-app derkork/socat-openshift --name=test-uat-vpn -e TARGET_HOST=the-host -e TARGET_PORT=443

Thats up and running in no time. Now to try the port forward:

oc port-forward dc/test-uat-vpn 8888:8888

Lets try it out/at least confirm connectivity:

nc -n -v 127.0.0.1 8888

Yep, looks like connection established, time to try from within the test container as it will do proper https which netcat is not doing.

Google divulges that we could test with ssl doing something like:

printf 'GET / HTTP/1.1\r\nHost: the-host\r\n\r\n' | openssl s_client -connect 172.0.0.1:8888

But.. Ahhh darn. Its not possible to use 127.0.0.1 from inside the container, that wont work.

Google shows that kubectl supports an --address parameter since late 2018, lets try that.
First, update kubectl as my version was a bit old:

curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl
mv kubectl ~/bin/
chmod +x ~/bin/kubectl

Then just quickly listen on all interfaces, that should work:

kubectl port-forward --address 0.0.0.0 dc/test-uat-vpn 8888:8888

Gah, kubectl doesn't understand OpenShift deployment config syntax, finding the pods will need the OpenShift's oc command. I'll include that in the command:

kubectl port-forward --address 0.0.0.0 $(oc get pods -l app=test-uat-vpn -o name) 8888:8888

That looks fine, now to test from within the local container and confirm its listening with nc again, it is, woohoo.

Next, change the configuration of the app to point to the docker ip, which is easily available to local docker instances as 172.17.0.1:8888 and test it out.

Rejected! Ooooh, the middleware doesn't like raw ip addresses. Bah!

Outside of docker, I would just add a host to /etc/hosts, but that's trickier in a docker container.

Argh.. will need to do it in the docker-composer^H file.

Google reveals https://docs.docker.com/compose/compose-file/#extra_hosts

Ok, adding something like this should work:

extra_hosts:
  the-host: 172.17.0.1

Stop and restart the docker compose stack, change the app config to point to the the-host:8888 and test.

Bingo! successfully working around a firewall restriction that was blocking working via the VPN.

Phew.. that was harder than expected!