Expose local services securely using authentik

Expose local services securely using authentik

This post will walk through my thoughts process to expose a service that runs on my local network

Premise

I already did expose service, which I have posted a bit from my previous blogs, quick recap on that:

You get the idea

while I can expose services with well-known good authentication (for example grafana or adguard-home) I can't expose services with no authentication (for example: dashy) and services with too basic authentication that it's insecure & easy to brute force (for example sonarr, radar, and qbittorrent)

The goal here is to have some authentication methods for all of my services so that we need authentication services

The Authentication Services

yes, I know the title already said that I use authentik, but the options for me are:

  • Setup Google login and protect anything insecure with Google auth proxy
  • Same as before, but instead of Google auth proxy, we use Pomerium
  • explore auth services like keycloak, authelia or authentik

Setup Google login + auth proxy may be the easiest way to do, I'm familiar with it, but the last time I check, I must provide every Google auth proxy for every service that I have, and I have many services to expose.. this option is something that easy in the beginning but don't scale very well

Another similar option is Pomerium, I've also pretty familiar with Pomerium, and I still can google login proxy with the better value from previous options with just one deployment for all services that I have

Then I find authentik, something that I haven't used before. From the documentation, I can have one login method for all services that I have, for example, if I have logged on to https://grafana.wibenson.cloud, I can open https://homepage.wibenson.cloud without login, authentik also have other security protocol that I'd like to explore in the future. Authentik also seems preferred on this Reddit thread

hot damn, I'm in

Authentik

The setup itself is quite simple, and the guide from the official docs is quite good, I won't rewrite that here because I believe it's subject of changes (or I'm lazy), here is the new diagram after we have Authentik

There are only one cloudflare and Caddy service, I split it up to 3 just to understand the flow of each services, authentik itself has a lot of documented integration with services on their documentation, but in short, authentik proxy provider will work with a lot of services, for some that already have "solid" authentication like grafana, we will just add antoher layer of authentication, so that the user will login twice, once for authentik and another for the app itself, so that's why services like grafana that support external OAuth, it's better to use Authentik Oauth Provider to simplify authentication

Epilogue

some noteworthy thing to mention is:

  1. Authentik needs a lot of memory, the docs state the minimum requirement is 2 core and 2 GB of memory, I use around 900++ mb of memory
➜  authentik docker stats | grep authentik
04e80aafca1c   authentik-worker-1            2.04%     240.6MiB / 7.506GiB   3.13%     332MB / 222MB     1.01MB / 0B       7
786fada5d82f   authentik-server-1            1.68%     570.7MiB / 7.506GiB   7.42%     120MB / 177MB     21.4MB / 0B       48
277d8712366d   authentik-postgresql-1        0.43%     78.05MiB / 7.506GiB   1.02%     93.4MB / 89.7MB   80.7MB / 326MB    10
9048807a0646   authentik-redis-1             0.38%     9.305MiB / 7.506GiB   0.12%     285MB / 347MB     3.99MB / 3.13GB   5

2. There's an integration with google login, and it does work. But to the point where this blog is written, I still have issue with how can I allow specific email to signup (or disable signup altogether).

3. Authentik does support authorization! it's really a nice feature that can be implemented in an organization, not really useful for self-hosted private projects because usually there's only one person accessing all this stuff.

note Synced via Generic OAuth

4. There's a point where suddenly I can't login into authentik without error message,  there's authentik log ERROR:  invalid input syntax for type inet: "172.70.142.146:56164" at character 491 which.. don't really tell anything, except that it seems like this wasn't the correct format for IP  address, hardcoding remove caddy's x-forwarded-for solve the issue for me (Cloudflare already provide correct x-forwarded-for), it was my mistake to overwrite it with remote_addr


Update 2023-07-28: Fix some wordings