| 3 min read

Photo of the Kubernetes logo showing on a smartphone
Piotr Swat/Shutterstock.com

NGINX Ingress is a popular Kubernetes ingress controller for routing traffic into your cluster. A standard Ingress resource lets you map HTTP requests to your Kubernetes services. Here’s how to protect your routes with HTTP Basic Authentication.

Creating an HTPasswd file

Make sure you’ve got an htpasswd file available before you tackle the Kubernetes configuration. You can create a new single user htpasswd in your terminal:

apt install apache2-utils
htpasswd -c auth example-user

You’ll be prompted to enter the password. A new file called auth will be created in your working directory.

Next you need to base64-encode your credentials string so it can be used as a value in a Kubernetes secret:

cat auth | base64

Copy the base64-encoded string to your clipboard. We’ll use it in the next section to create a Kubernetes secret containing your credentials.

Adding a Kubernetes Secret

NGINX Ingress references htpasswd files as Kubernetes secrets. The file’s content must be stored in the auth key of an Opaque secret. Kubernetes also has a built-in basic-auth secret type but this isn’t suitable for NGINX Ingress.

Create a new secret manifest and apply it to your cluster with Kubectl:

apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: htpasswd
data:
  auth: 

Add your base64-encoded htpasswd file as the value of the auth key.

Modifying Your Ingress

NGINX Ingress supports several custom annotations that let you attach extra behavior to your Ingress resources. To use HTTP Basic Authentication you need to set the auth-type annotation and supply a reference to your secret.

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: htpasswd
    nginx.ingress.kubernetes.io/auth-realm: "Enter your credentials"
spec:
  rules:
    - host: example.com
      http:
        paths:
         - path: /
           backend:
            serviceName: example-service
            servicePort: 80

The three annotations configure NGINX to require authentication on every request that’s matched by your Ingress resource. The basic authentication type is used with the credentials from the htpasswd secret created earlier. The auth-realm annotation defines the message displayed to users when they’re prompted to enter their credentials.

Requests matched by this Ingress will now require the user to login before they continue. The authentication challenge displays as a popup dialog in most web browsers. Enter the username and password supplied to the htpasswd command to authenticate yourself.

Alternative Secret Form

The secret shown above uses the auth-file format. This means it’s got an auth field containing base64-encoded output from the htpasswd command.

NGINX Ingress also supports another form termed auth-map. In this variation, the auth field is replaced by a set of keys that each provide the password for an individual user.

apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: htpasswd
data:
  user1: 
  user2: 

Add your usernames to the file, then use htpasswd to generate hashed credentials. Inspect the htpasswd output; it will have the following format:

username:

Take the password part, encode it with the base64 command, then add the result to your Kubernetes secret.

NGINX will accept logins from any valid username and password combination defined in the secret. This approach can make it easier to set up multiple user accounts and helps you see exactly who’s got access.

More Advanced Auth

NGINX Ingress can integrate with external authentication providers if you need more control but want a similarly straightforward set up experience. Using an external auth provider will redirect users to that site before they can access the Service behind your Ingress. This lets you enforce a full authentication routine without touching your backend code.

The nginx.ingress.kubernetes.io/auth-url annotation defines the URL of an external authentication service to use. Kubernetes will forward each incoming request to the service. Access will only be granted to the user when the service returns a 200 OK status code. The normal flow then continues with the request proceeding into your Kubernetes Service.

When the auth service indicates an error, users will be redirected to the page indicated by the nginx.ingress.kubernetes.io/auth-signin URL. This will receive the original URL to redirect back to after a successful authentication attempt as a URL parameter defined with the auth-signin-redirect-param annotation.

Several other annotations let you tweak NGINX’s behavior when communicating with the authentication platform. You can change the HTTP method used to make authentication requests, add additional headers, and setup caching for auth responses. The latter ensures you’re not continually hitting the external platform if a user makes several requests to your service in a short period of time.

Summary

HTTP Basic Authentication is the simplest way of protecting a website. It’s ideal for internal systems and staging sites where you’re working with a small list of users and don’t need centralized credential management.

Use Basic Auth with NGINX Ingress by supplying credentials in a Kubernetes secret and setting annotations on your Ingress resources. In a real-world use case, you shouldn’t hardcode credentials into your Kubernetes manifests. Either use Helm or a CI/CD system to safely supply values at the time you apply the resources to your cluster.

Read More

Leave a Reply

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