Zero Trust Access to the Kubernetes API

Overview

In most environments, the K8S API is not exposed to the public internet. In such cases, you can use Banyan’s default Mutually Authenticated TLS (MTLS) flows for TCP services to provide your end users VPN-free Zero Trust access regardless of their network location. K8S API traffic flows through the Banyan Access Tier and is wrapped in a MTLS tunnel (shown in the diagram below).

We define the K8S API as a TCP Service (and not a Web Service) even though it uses the HTTP protocol because the K8S API is accessed via a CLI tool kubectl and not a web browser.

Banyan Kubernetes Authentication

Banyan’s default approach is to treat K8S like any other TCP service and be agnostic to the underlying K8S authentication method. You can retain your current K8S authentication mechanism - be it password, client cert, JWT tokens, etc. We strongly recommend using the Banyan OIDC provider which will allow access to your Kubernetes clusters using native K8S RBAC. Review our K8S OIDC Authentication capability to learn more.

Steps

Setting up VPN-free access to an K8S Cluster via the K8S API is the setup process followed to secure a TCP service, as described in Notes on Securing TCP Services.

In this article, we will create a Banyan Role (for employees with personal devices) and a Banyan Policy so only users on devices that meet the policy can gain to secure access to the Kubernetes API, using the following steps:

1. Create a Role for your End Users

In the Banyan Command Center, navigate to Secure Access > Roles and then click + Add Role. Create a User Role and select Role Attributes so that the role only applies to specific sets of users and devices.

2. Create a Policy for your Kubernetes Cluster

Now, create an access policy that uses the created role.

Navigate to Secure Access > Policies and then click Create Policy. Select the option Basic Authorization Policy for Users.

Be sure to select the option that specifies this policy is intended for TCP - for remote access using a TCP-based protocol.

3. Define a TCP Service for the Kubernetes Cluster

We strongly recommend using the Banyan OIDC provider which will allow access to your Kubernetes clusters using native K8S RBAC. If you are configuring OIDC authentication, select Kubernetes and review our K8S OIDC Authentication capability.

Then, configure a Hosted Service for Zero Trust access to your Kubernetes Cluster.

Navigate to Manage Services > Infrastructure and then click + Register Service. Select the option Other TCP Service.

Configure the service as shown below:

Assign a domain name for this service mykube.corp.example.com and leave the port as 8443; the banyanproxy will tunnel Kubernetes traffic over port 8443.

Set incoming connections to be proxied to the backend via Client specifies using HTTP Connect.

Enter the Kube API’s fully qualified domain name (FQDN) as a Backend Allowed Hostname.

In the Service Connection Settings, specify an Assigned Listen Port (in this example, we specify a listen port 8081) and optionally allow end users the ability to override these settings.

Please ensure you leave the Domains to Proxy field blank, otherwise banyanproxy will not start.

Attach the policy we had previously created and set enforcement mode to Enforcing.

4. Connect via the Banyan Desktop App

Ensure your end users install the latest Banyan Desktop App and register their device.

Once the Service is defined, your end users will see it in their Banyan Desktop App.

When the user clicks Connect, the Desktop App will launch the banyanproxy in HTTP_CONNECT_DAISY_CHAIN Mode, on the specified port.

Now, they can set the https_proxy environment variable before you call kubectl to automatically tunnel the session over the Mutual-Auth TLS channel set up by Banyan.

https_proxy=http://localhost:8081 kubectl get pods

If your end user is using kubectl v1.19+, they can add a proxy-url field directly to their ~/.kube/config file instead of specifying the https_proxy env var.

Verify that your output lists your running pods correctly.

NAME                    READY   STATUS    RESTARTS   AGE
podreader-default-pod   1/1     Running   0          35h
Last modified: Jun 17, 2021