Airlock Microgateway
Airlock Microgateway is a Kubernetes-native web application firewall (WAF) that protects your workloads against common web attacks. On the Nine Kubernetes Engine we run the Airlock Microgateway operator for you and expose one or more Kubernetes Gateways that you attach your applications to using the standard Kubernetes Gateway API.
Airlock Microgateway on NKE is in an early stage. To get it set up on your cluster, contact our support. This article covers the basics and will be extended over time.
Availability
Airlock Microgateway is available as an optional service for NKE clusters. It is not self-service yet: contact us and we will install the operator and create the Gateways on your cluster.
The Airlock Microgateway operator is a cluster-wide component, so there is one operator per NKE cluster. That single operator can back multiple Gateways, so you can request as many Gateways as you need on the same cluster.
How It Works
Once you request Airlock Microgateway for a cluster, we:
- Install the Airlock Microgateway operator on your NKE cluster.
- Create one or more Gateways in the Nine-managed
nine-systemnamespace. Each Gateway gets its own load balancer with a public IP address and a stable hostname (for exampleproduction.<hash>.airlockgateway.nineapis.ch) that you can point your own domains to. - Set up Let's Encrypt
ClusterIssuerresources so that certificates for your domains are issued and renewed automatically.
You then attach your own Gateway API resources (ListenerSet, HTTPRoute) in
your application namespaces to route traffic through the Gateway.
Why the Gateway API
Airlock Microgateway is configured exclusively through the Kubernetes Gateway
API. It does not work with the Ingress resources used elsewhere on
NKE. The Gateway API deliberately splits responsibilities: Nine owns the shared
infrastructure (the Gateway and its load balancer), while you own the per-app
routing and security resources (ListenerSet, HTTPRoute, and the Airlock
policies) in your own namespaces. This split is what lets us run and secure the
Gateway for you while you keep full control over how your traffic is routed and
protected.
Usage
The following examples assume a Gateway named airlock-production was created
for you in the nine-system namespace, and that your application runs in the
my-app namespace.
Add an HTTPS Listener With Automatic TLS
Create a ListenerSet in your application namespace to add an HTTPS listener to
the Gateway. When the cert-manager.io/cluster-issuer annotation is present,
cert-manager automatically issues and renews the certificate for the given
hostname.
apiVersion: gateway.networking.k8s.io/v1
kind: ListenerSet
metadata:
name: my-listeners
namespace: my-app
annotations:
cert-manager.io/cluster-issuer: airlock-letsencrypt-production
spec:
parentRef:
name: airlock-production
namespace: nine-system
listeners:
- name: https
hostname: "myapp.example.com"
port: 443
protocol: HTTPS
tls:
mode: Terminate
certificateRefs:
- name: myapp-tls
namespace: my-app
allowedRoutes:
namespaces:
from: Same
Use the airlock-letsencrypt-staging issuer while testing to avoid the Let's
Encrypt rate limits, then switch to airlock-letsencrypt-production for real
certificates.
Route Traffic to a Backend
Attach an HTTPRoute to the listener to forward requests to your backend
service:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: my-app-route
namespace: my-app
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: ListenerSet
name: my-listeners
namespace: my-app
sectionName: https
hostnames:
- "myapp.example.com"
rules:
- backendRefs:
- name: my-app-service
port: 8080
Plain HTTP Traffic
Each Gateway comes with a built-in HTTP listener on port 80, which is also used
to solve Let's Encrypt HTTP01 challenges. For plain-HTTP traffic you can attach
an HTTPRoute directly to the Gateway, without a ListenerSet:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: my-app-http
namespace: my-app
spec:
parentRefs:
- name: airlock-production
namespace: nine-system
sectionName: http
hostnames:
- "myapp.example.com"
rules:
- backendRefs:
- name: my-app-service
port: 8080
You can test reachability before setting up DNS by sending the hostname as a
Host header:
curl -H "Host: myapp.example.com" http://<gateway-ip>/
Point Your Domain at the Gateway
To serve production traffic, create a CNAME record for your domain that points to the Gateway's hostname:
myapp.example.com. CNAME production.<hash>.airlockgateway.nineapis.ch.
We provide the exact hostname for your Gateway when it is set up.
Customize Error Responses
Airlock Microgateway can replace the responses your clients see, for example the
error page returned when a request is blocked or when your backend returns an
error. First define the content with a CustomResponse:
apiVersion: microgateway.airlock.com/v1alpha1
kind: CustomResponse
metadata:
name: custom-404
namespace: my-app
spec:
statusCode: 404
content:
- contentType: text/html
body:
value: "<h1>Page not found</h1>"
Then attach a CustomResponsePolicy to your HTTPRoute to serve that response
for matching status codes:
apiVersion: microgateway.airlock.com/v1alpha1
kind: CustomResponsePolicy
metadata:
name: my-app-custom-responses
namespace: my-app
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: my-app-route
policies:
local:
- responses:
- statusCodeCondition:
matcher:
exact: 404
customResponseRef:
name: custom-404
The CustomResponse, the CustomResponsePolicy, and the HTTPRoute they
reference must all be in the same namespace. Airlock offers many more policies,
such as traffic filtering, header rewriting, and rate limiting. See the
Airlock Microgateway CRD reference
for the full list.
View Access Logs
The Gateway logs every request as structured JSON. Each entry includes a request
ID (the http.request.id field) that you can use to trace a single request end
to end, along with the matched route and whether Airlock allowed or blocked it:
{
"http": { "request": { "id": "4cddf510-516c-4cda-9066-3809dad0b249" } },
"airlock": { "summary": { "action": "allowed" } }
}
When Loki is enabled on your cluster, these access logs are collected automatically and you can search them by request ID in Grafana.