How to access a Private EKS Cluster from your local machine without a VPN

There are many ways to access a Kubernetes private cluster. My preferred way is the GKE one, on which the API endpoint is public but you whitelist your machine to be able to connect to it.
You can do it with a simple gcloud command and that is it. You can even automate your pipelines to do it, then remove the whitelisted IP when ready.

Both Azure and AWS do not do it this way when you create a private cluster inside a Private Network, it is really private… and it becomes painful. Hey, in Azure I even think their own Azure Portal cannot see the workloads. WTF.

The most preferred-by-infosec way of doing it is by using a VPN. Which yes, works, yet is another thing to take care of and managed VPNs are not cheap.

The general popular idea is to set up a Bastion Host (usually a VM) which is exposed to the internet (hey, this sounds great!) and then you can SSH into the Bastion to run kubectl commands in there:

PLEASE, DON’T DO THIS. Why would you create a private cluster if you are going to put a freaking VM with port 22 open in front of it…
::insert-facepalm-emoji-here:: It is nonsense!!!

Yet many people do it.

There are options like gototeleport.io which allow you to securely SSH into the Bastion host with MFA, or even kubectl directly to the cluster, skipping the Bastion at all. But it is really expensive. (I save you the Google search, $100/m per cluster)

Couldn’t be worse eh?

It gets even worse. I’ve seen some architectures that looks like this:

So now you have two SSH jumps. One into the “public” JumpBox, then from there, you SSH into a Bastion host located inside the private network, from which you can run kubectl commands.

This architecture is bad for many reasons. First, you are still exposing a VM with port 22 open. It also promotes using the JumpBox and the Bastion as “trash boxes” where your Kubernetes YAML files will lie forever.
Finally, I certainly believe this architecture should not exist. The proper way of having a truly private cluster is to make it private first, then only access it by using pipelines. If you really need to kubectl into it, then it is a DEVELOPMENT cluster, and whitelisting IPs or using a VPN are the best options.

How to jump over the crap

Now, let’s return to the issue, the architecture exists, it is a development cluster, it is real, and it is my problem now. I want to run kubectl from my machine, where I have my IDE and my stuff.

THE problem

SSH and ~/.ssh/config to the rescue!

With SSH, you can create a proxy and forward all connections to a certain host, but in this case, we have a double SSH jump to do, so, in order to make it easy and readable, we can use the ~/.ssh/config file like this:

Host jumpbox
  HostName x.x.x.x    #[this is the public ip]   
  User myuser
  IdentityFile ~/.ssh/my-key.key

Host bastion
  HostName a.b.c.d    #[this is the private ip]
  User mybastionuser  #ec2-user in my case  
  ProxyJump jumpbox

Now, you can ssh bastion and you should be able to login to the Bastion server.

If you get a public_key denied message, make sure your machine’s public key is in the authorized_keys of the Bastion, not only on the JumpBox

How to make kubectl work over an SSH proxy?

In order to make kubectl work over a proxy, we need to do a few quick things:

  • Copy the ~/.kube/config data you need from the Bastion to your local machine.
  • If you are using AWS RBAC make sure aws cli is set up in your local machine, then follow this tutorial.
  • Create an SSH proxy with ssh -D 1080 -f bastion -N
    • -f will send ssh to the background
  • Force your current session to use that proxy for HTTPS with export HTTPS_PROXY=socks5://127.0.0.1:1080

Now, you can run kubectl get namespaces in your terminal and it will work!!!!

I know, it is not the easiest solution, but it is quite simple and transparent. I hope this will help someone!

Configurando un Reverse Proxy con Apache
6 November, 2013
Error: “Interfaz no compatible” en Windows 7 (No such interface supported)
17 April, 2010
Librería LCD para PIC 16F876A en el PORTB. PICC
30 August, 2011

Leave a Reply

Your email address will not be published. Required fields are marked *