1
0
Fork 0
kubernetes/authelia
Dustin b07e141fa3 authelia: Convert to a stateless service
By default, Authelia uses a local SQLite database for persistent data
(e.g. authenticator keys, TOTP secrets, etc.) and keeps session data in
memory.  Together, these have some undesirable side effects.  First,
since needing access to the filesystem to store the SQLite database
means that the pod has to be managed by a StatefulSet.  Restarting
StatefulSet pods means stopping them all and then starting them back up,
which causes downtime.  Additionally, the SQLite database file needs to
be backed up, which I never got around to setting up.  Further, any time
the service is restarted, all sessions are invalidated, so users have to
sign back in.

All of these issues can be resolved by configuring Authelia to store all
of its state externally.  The persistent data can be stored in a
PostgreSQL database and the session state can be stored in Redis.  Using
a database managed by the existing Postgres Operator infrastructure
automaticaly enables high availability and backups as well.

To migrate the contents of the database, I used [pgloader].  With
Authelia shut down, I ran the migration job.  Authelia's database schema
is pretty simple, so there were no problems with the conversion.
Authelia started back up with the new database configuration without any
issues.

Session state are still stored only in memory of the Redis process.
This is probably fine, since Redis will not need restarted often, except
for updates.  At least restarting Authelia to adjust its configuration
will not log everyone out.

[pgloader]: https://pgloader.readthedocs.io/en/latest/ref/sqlite.html
2023-10-19 07:12:02 -05:00
..
README.md authelia: Set up OIDC for k8s API server 2023-04-22 21:37:23 -05:00
authelia.yaml authelia: Convert to a stateless service 2023-10-19 07:12:02 -05:00
configuration.yml authelia: Convert to a stateless service 2023-10-19 07:12:02 -05:00
kustomization.yaml authelia: Convert to a stateless service 2023-10-19 07:12:02 -05:00
migrate.yaml authelia: Convert to a stateless service 2023-10-19 07:12:02 -05:00
oidc-cluster-admin.yaml authelia: Set up OIDC for k8s API server 2023-04-22 21:37:23 -05:00
postgresql-ca.crt authelia: Convert to a stateless service 2023-10-19 07:12:02 -05:00
redis.yaml authelia: Convert to a stateless service 2023-10-19 07:12:02 -05:00
secrets.yaml authelia: Migrate to Sealed Secrets 2023-10-14 10:35:54 -05:00

README.md

Authelia

Authelia is an open-source authentication and authorization server and portal. It can operate as an OpenID Connect identity provider or as a proxy authorization subrequest handler (e.g. for nginx). It supports a built-in user database as well as LDAP, and various forms of second-factor authentication.

Installation

kubectl apply -k authelia

Configuration

Authelia is configured by the configuration.yml file. It is stored as a Kubernetes ConfigMap and mounted into the Authelia server container. See the Configuration section of the Authelia documentation for details.

Various secrets are used to secure Authelia. These are stored as Kubernetes Secret resources and mounted into the Authelia server container. Their contents originate from files such as jwt.secret, ldap.password, etc.

OpenID Connect

For applications that support it, OpenID Connect is usually a better option than proxy authorization subrequest. Each application needs to be defined in the identity_providers.oidc.clients list. At minimum, clients need an ID, description, and list of redirect URIs. Additionally, a client must either have a defined secret or be marked public.

Proxy Authorization Subrequest

Authellia's original purpose was to support the authorization subrequest feature of nginx and other reverse proxy solutions. When used in this way, Authelia can protect for applications that do not have a built-in authentication/authorization capabilities. For each incoming request, the proxy makes a subrequest to Authelia, passing along cookies, etc. from the original request. Authelia validates the session and indicates whether or not the request is allowed. If it is allowed, the proxy resumes processing the original request, forwarding it to the upstream server. If it is not allowed, the proxy returns a redirect response to the client, instructing the user agent to load the Authelia login page. Authelia then checks the user's credentials, optionally enforcing MFA validation (based on the configured access control policy), and creates a new session. It then redirects the user agent back to the resource requested initially.

Enabling the proxy authorization subrequest for applications hosted in Kubernetes is very straightforward. The ingress-nginx Ingress controller supports configuring it via the nginx.ingress.kubernetes.io/auth-url, et al. annotations. Adding authentication to an Ingress resource is therefore as simple as adding a few annotations:

metadata:
  annotations:
    nginx.ingress.kubernetes.io/auth-method: GET
    nginx.ingress.kubernetes.io/auth-url: http://authelia.authelia.svc.cluster.local:9091/api/verify
    nginx.ingress.kubernetes.io/auth-signin: https://auth.pyrocufflink.blue/?rm=$request_method
    nginx.ingress.kubernetes.io/auth-response-headers: Remote-User,Remote-Name,Remote-Groups,Remote-Email
    nginx.ingress.kubernetes.io/auth-snippet: |
      proxy_set_header X-Forwarded-Method $request_method;      

Note that the value of the auth-url contains the internal URL for Authelia, while the auth-signin value is the external URL.

OpenID Connect for Kubernetes API

The Kubernetes API server can be configured to authorize client requests using OpenID Connect. The relevant settings are provided as command-line arguments to the server process. For clusters managed by kubeadm, the arguments can be added to the ClusterConfiguration setting in the kubeadm-config ConfigMap:

ClusterConfiguration: |
  apiServer:
    extraArgs:
      oidc-client-id: kubernetes
      oidc-groups-claim: '["groups"]'
      oidc-groups-prefix: 'oidc:'
      oidc-issuer-url: https://auth.pyrocufflink.blue
      oidc-username-claim: preferred_username
      oidc-username-prefix: 'oidc:'  

Clients need to be specifically configured to use OIDC. For kubectl, the kubelogin plugin provides the necessary functionality. With the kubelogin binary installed, and a symbolic link to it named kubectl-oidc_login created, the client kubeconfig needs to specify an exec option for obtaining the authorization token:

users:
- name: dustin
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1beta1
      command: kubectl
      args:
      - oidc-login
      - get-token
      - --oidc-issuer-url=https://auth.pyrocufflink.blue
      - --oidc-client-id=kubernetes
      - --oidc-extra-scope=profile
      - --oidc-extra-scope=groups
      provideClusterInfo: false