An open API service indexing awesome lists of open source software.

https://github.com/work-systems-ltd/freeradius-k8s-operator

Declarative FreeRADIUS in kubernetes for ISPs
https://github.com/work-systems-ltd/freeradius-k8s-operator

freeradius freeradius-kubernetes freeradius-server kubernetes kubernetes-operator radius radius-server

Last synced: 2 months ago
JSON representation

Declarative FreeRADIUS in kubernetes for ISPs

Awesome Lists containing this project

README

          


FreeRADIUS K8s Operator

# FreeRADIUS, the Kubernetes-native way.

A Kubernetes operator built for ISP BNG and broadband subscriber management at scale. It turns RADIUS clusters, NAS clients, and unlang policies into native custom resources — so the AAA layer behind your BNGs lives in Git, rolls out with `kubectl apply`, and scales like everything else in your cluster.

[![Go](https://img.shields.io/badge/Go-1.22+-00ADD8?logo=go&logoColor=white)](https://go.dev)
[![Kubernetes](https://img.shields.io/badge/Kubernetes-1.28+-326CE5?logo=kubernetes&logoColor=white)](https://kubernetes.io)
[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)
[![Docs](https://img.shields.io/badge/docs-GitHub_Pages-blue?logo=github)](https://Work-Systems-Ltd.github.io/freeradius-k8s-operator/)
[![Discord](https://img.shields.io/badge/Discord-join_chat-5865F2?logo=discord&logoColor=white)](https://discord.gg/gKQz4kpM)

[**Quick Start**](#quick-start) · [**Why?**](#why-this-exists) · [**Examples**](example/) · [**Docs**](https://Work-Systems-Ltd.github.io/freeradius-k8s-operator/)

---

> [!WARNING]
> This project is under active development and is **not yet production-ready**. APIs, CRD schemas, and behaviors may change without notice. Star the repo to follow along — we're close.

## How it works

```mermaid
flowchart LR
subgraph Git["GitOps / kubectl apply"]
CR["RadiusCluster
RadiusClient
RadiusPolicy"]
end

subgraph K8s["Kubernetes Cluster"]
OP["FreeRADIUS
Operator"]
CFG["Rendered ConfigMap
radiusd.conf
clients.conf
sites / modules"]
SEC[("Secrets
shared keys
DB creds
TLS certs")]
subgraph FR["FreeRADIUS Pods"]
P1["auth"]
P2["acct"]
P3["CoA"]
end
OBS["Metrics
ServiceMonitor
Alerts"]
end

subgraph Net["Network Edge"]
BNG["BNGs / OLTs
NAS devices
WiFi APs"]
SUB["Subscribers
PPPoE / IPoE / 802.1X"]
end

CR -->|watches| OP
OP -->|renders| CFG
OP -.->|mounts| SEC
CFG --> FR
SEC -.-> FR
OP -->|scrapes| OBS
FR <-->|RADIUS
auth / acct / CoA| BNG
SUB <--> BNG

classDef crd fill:#0c0c0f,stroke:#22c55e,stroke-width:1px,color:#fafafa
classDef op fill:#0c0c0f,stroke:#22c55e,stroke-width:2px,color:#fafafa
classDef pod fill:#0c0c0f,stroke:#a1a1aa,stroke-width:1px,color:#fafafa
classDef edge fill:#0c0c0f,stroke:#71717a,stroke-width:1px,color:#a1a1aa
class CR crd
class OP op
class CFG,SEC,OBS pod
class P1,P2,P3 pod
class BNG,SUB edge
```

You declare what you want in YAML. The operator watches your CRDs, renders a complete FreeRADIUS config (`radiusd.conf`, `clients.conf`, sites and modules), mounts secrets from Kubernetes Secrets, and rolls out pods behind split-mode Services for auth / accounting / CoA — all with HPA, PDBs, and Prometheus metrics wired up. Your BNGs and NAS devices talk to the resulting Service exactly like any other RADIUS server.

## Why this exists

RADIUS is the quiet workhorse behind every ISP on the planet. Every PPPoE session, every IPoE lease, every DHCP hand-off, every CoA bandwidth change — it all flows through RADIUS and into a BNG. And yet in 2026, running AAA for a BNG fleet still means SSH'ing into pet VMs to hand-edit `radiusd.conf`, copy-pasting `clients.conf` across replicas every time a new OLT shows up, and rolling shared secrets by restarting RADIUS servers one at a time. HA is whatever you cobble together with keepalived and cron. CoA for live PPPoE sessions is an afterthought.

Kubernetes solved this for web apps a decade ago. This operator brings the same experience to ISP-grade RADIUS: declarative specs, GitOps-friendly rollouts, automatic config rendering, secret mounting, HPA, PDBs, split auth/accounting/CoA services, and Prometheus metrics — all behind three simple CRDs purpose-built for BNG subscriber AAA.

```yaml
apiVersion: radius.operator.io/v1alpha1
kind: RadiusCluster
metadata:
name: bng-aaa
spec:
image: freeradius/freeradius-server:3.2.3
replicas: 6
autoscaling:
enabled: true
minReplicas: 6
maxReplicas: 30
modules:
- name: sql
type: rlm_sql
enabled: true
sql:
dialect: postgresql
server: postgres.aaa.svc.cluster.local
port: 5432
database: radius
login: radius
passwordRef:
name: sql-db-credentials
key: password
services:
auth: { type: LoadBalancer }
accounting: { type: LoadBalancer }
coa: { type: LoadBalancer } # scale each independently
```

`kubectl apply -f` and you have a scaled, self-healing, observable RADIUS tier sitting behind your BNGs.

## How it compares

| | Hand-rolled FreeRADIUS | Helm chart | **This operator** |
|---|:---:|:---:|:---:|
| Declarative clients & policies as CRDs | — | — | **Yes** |
| Automatic config rendering + rollout | — | partial | **Yes** |
| Structured unlang policy engine | — | — | **Yes** |
| Secrets from K8s Secrets (not ConfigMaps) | manual | partial | **Yes** |
| HPA, PDB, split-mode services | manual | partial | **Yes** |
| Prometheus exporter + ServiceMonitor + alerts | manual | — | **Yes** |
| GitOps-native | manual | **Yes** | **Yes** |

Every backend you actually use is supported out of the box: SQL (MySQL, PostgreSQL, SQLite, MSSQL, Oracle, Mongo), LDAP, REST, Redis, Files, and EAP (TLS/TTLS/PEAP) — with shared connection-pool tuning.

## Quick Start

```bash
# 1. Install the operator (chart ships the CRDs, RBAC, Deployment, and metrics Service)
helm install freeradius-operator ./charts/freeradius-operator \
--namespace freeradius-system --create-namespace

# 2. Deploy a FreeRADIUS instance — either with Helm...
helm install bng-prod ./charts/freeradius-cluster \
--namespace radius-prod --create-namespace

# ...or straight from a ready-to-apply example
kubectl apply -f example/basic/

# 3. Watch it come up
kubectl get radiusclusters,radiusclients,radiuspolicies -A
```

> CRDs are installed from the operator chart's `crds/` directory and are **not** upgraded by `helm upgrade`. To update CRDs, re-apply `config/crd/` or the chart's `crds/` directory with `kubectl apply -f`.

### Two charts, two jobs

| Chart | Installs | When to use |
|---|---|---|
| [`charts/freeradius-operator`](charts/freeradius-operator/) | CRDs, RBAC, operator Deployment, metrics Service | Once per cluster. Owns the controller that watches and reconciles RadiusCluster / RadiusClient / RadiusPolicy resources. |
| [`charts/freeradius-cluster`](charts/freeradius-cluster/) | A RadiusCluster + any number of RadiusClients, RadiusPolicies, and inline Secrets | Once per FreeRADIUS instance. Thin pass-through around the CRD specs — every field of `RadiusClusterSpec` is available under `cluster.spec` in values. |

The workload chart is optional. If you prefer plain manifests or GitOps with Kustomize, apply files from [`example/`](example/) directly and skip the second chart entirely.

Ready-to-apply examples live in [`example/`](example/), organized by scenario:

| Example | What it shows |
|---|---|
| [`basic/`](example/basic/) | Minimal files-backed auth with VLAN assignment policy |
| [`sql/`](example/sql/) | PostgreSQL-backed auth with a tuned `rlm_sql` connection pool |
| [`rest-api/`](example/rest-api/) | Authentication via an external REST API |
| [`ldap/`](example/ldap/) | LDAP / Active Directory authentication |
| [`ha-redundant/`](example/ha-redundant/) | Redundant SQL failover with autoscaling and PDB |
| [`split-mode/`](example/split-mode/) | Independent scaling for auth, accounting, and CoA |
| [`raw-override/`](example/raw-override/) | Escape hatch for custom modules and raw unlang |

For a full walkthrough — deploying, scaling, managing clients and policies, troubleshooting, and observability — see the **[documentation](https://Work-Systems-Ltd.github.io/freeradius-k8s-operator/)**.

## Who is this for?

- **ISPs running BNGs at scale** — PPPoE, IPoE, DHCP option-82, CoA bandwidth changes, subscriber accounting. The primary use case.
- **WISPs and altnets** managing hundreds of OLTs, BNGs, and edge NAS devices across regions and POPs.
- **Network teams** running campus WiFi, 802.1X, or guest portals and tired of hand-editing config files.
- **Platform engineers** bringing legacy carrier-grade AAA into a GitOps workflow.
- **Homelabbers** who want real RADIUS without pets.

## Community

- **[Documentation](https://Work-Systems-Ltd.github.io/freeradius-k8s-operator/)** — getting started, concepts, CRD reference, guides, troubleshooting
- **[Discord](https://discord.gg/gKQz4kpM)** — chat with the maintainers and other operators
- **[Issues](../../issues)** — bug reports and feature requests
- **[Discussions](../../discussions)** — questions, ideas, show-and-tell

If this project saved you an afternoon of `radiusd.conf` wrangling, **give it a star** — it's the single biggest thing you can do to help others find it.

## Contributing

Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for the development workflow, local kind setup, code standards, and PR guidelines. First-timers: look for issues labeled `good first issue`.

## License

Licensed under the [Apache License 2.0](LICENSE).

Built with care by [Work Systems Ltd](https://github.com/Work-Systems-Ltd) and contributors.