I needed to get some work done on a jenkins server that unfortunately was behind a firewall, and was inaccessible even with my VPN turned on.
Fortunately I had SSH access to a machine inside the firewall that also had SSH access to the jenkins server. So I knew that there was a way to use SSH tunnelling to get to the jenkins server.
First I created an SSH tunnel between my local machine and the machine inside the firewall.
SSH -L 8884:localhost:8883 nodeA
So as you can see I am forwarding packets from nodeA's 8883 port to my local's 8884 port.
(Note that I've set up a ~/.ssh/config
file with the details on how to access
nodeA so that I do not have to be overly verbose.)
I can verify that my tunnel is working with curl:
curl https://localhost:8884
> curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to localhost:8884
Thus, the connection is working but there is no output on the local 8884 port yet because whatever is connected to nodeA's 8883 port does not know how to respond to an HTTP client. (Nothing is connected to that port, so the result is making sense).
Now I need to create a connection between my jenkins server on nodeB to my access machine (nodeA) in order to close the loop.
To do this I need to open up another terminal window and ssh into nodeA. From nodeA I create a connection to nodeB.
SSH -L 8883:locahost:443 nodeB
This is doing exactly what we did on our local. However testing with curl from within NodeA we will see that there is a response.
curl https://localhost:8883
curl -I -L https://localhost:8883/jenkins/login -k
HTTP/1.1 200 OK
Great so we are getting somewhere. Whatever is connected to localhost:8883 on nodeA knows how to respond to an HTTP client.
If we test from our localhost we should see a response too.
curl https://localhost:8884
curl -I -L https://localhost:8883/jenkins/login -k
HTTP/1.1 200 OK
Sweet. So now we can interact with our jenkins server via localhost:8883
In my usecase there was a caveat. Although I could get to the jenkins server this way there was a road block. We had set up Google Auth for logging in and this required access to https://nodeB because of a hard coded redirect from the Google Auth Service. My options where to turn of security on the jenkins server or figure out how to access nodeB on port 443 locally.
Forwarding my local 443 to my local 8884 port should do the trick; However, I don't have SSH access enabled for my local computer.
sudo ssh -L 443:localhost:8884 localhost
ssh: connect to host localhost port 22: Connection refused
So that's not an option.
But then I learned it's possible to redirect packets on MacOsX: https://salferrarello.com/mac-pfctl-port-forwarding
echo "rdr pass inet proto tcp from any to any port 443 -> 127.0.0.1 port 8443" | sudo pfctl -ef -
And that did the trick
curl https://localhost/jenkins/login -I -k -L
HTTP/1.1 200 OK
I finished up by adding the following line to my /etc/hosts
file:
127.0.0.1 nodeB
Now Accessing the jenkins server on nodeB from my local works as expected:
curl https://nodeB/jenkins/login -I -k -L
HTTP/1.1 200 OK
Later I may want to undo all these changes.
sudo pfctl -F all -f /etc/pf.conf