feat: authentik
This commit is contained in:
67
hosts/m3-atlas/services/containers/authentik.nix
Normal file
67
hosts/m3-atlas/services/containers/authentik.nix
Normal file
@@ -0,0 +1,67 @@
|
||||
{config, ...}: let
|
||||
image = "ghcr.io/goauthentik/server:2026.2.0";
|
||||
|
||||
serverIp = "10.89.0.22";
|
||||
workerIp = "10.89.0.23";
|
||||
|
||||
postgresHost = "10.89.0.1";
|
||||
postgresPort = config.m3ta.ports.get "postgres";
|
||||
authentikPort = config.m3ta.ports.get "authentik";
|
||||
|
||||
sharedEnv = {
|
||||
AUTHENTIK_POSTGRESQL__HOST = postgresHost;
|
||||
AUTHENTIK_POSTGRESQL__PORT = toString postgresPort;
|
||||
AUTHENTIK_POSTGRESQL__USER = "authentik";
|
||||
AUTHENTIK_POSTGRESQL__NAME = "authentik";
|
||||
};
|
||||
in {
|
||||
virtualisation.oci-containers.containers = {
|
||||
"authentik-server" = {
|
||||
inherit image;
|
||||
cmd = ["server"];
|
||||
environment = sharedEnv;
|
||||
environmentFiles = [config.age.secrets.authentik-env.path];
|
||||
ports = ["127.0.0.1:${toString authentikPort}:9000"];
|
||||
volumes = [
|
||||
"authentik_media:/media"
|
||||
"authentik_templates:/templates"
|
||||
];
|
||||
extraOptions = [
|
||||
"--add-host=postgres:${postgresHost}"
|
||||
"--ip=${serverIp}"
|
||||
"--network=web"
|
||||
];
|
||||
};
|
||||
|
||||
"authentik-worker" = {
|
||||
inherit image;
|
||||
cmd = ["worker"];
|
||||
user = "root";
|
||||
environment = sharedEnv;
|
||||
environmentFiles = [config.age.secrets.authentik-env.path];
|
||||
volumes = [
|
||||
"authentik_media:/media"
|
||||
"authentik_certs:/certs"
|
||||
"authentik_templates:/templates"
|
||||
];
|
||||
extraOptions = [
|
||||
"--add-host=postgres:${postgresHost}"
|
||||
"--ip=${workerIp}"
|
||||
"--network=web"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
services.traefik.dynamicConfigOptions.http = {
|
||||
services.authentik.loadBalancer.servers = [
|
||||
{url = "http://localhost:${toString authentikPort}/";}
|
||||
];
|
||||
|
||||
routers.authentik = {
|
||||
rule = "Host(`auth.m3ta.dev`)";
|
||||
tls = {certResolver = "godaddy";};
|
||||
service = "authentik";
|
||||
entrypoints = "websecure";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
./restreamer.nix
|
||||
./slash.nix
|
||||
./slash-nemoti.nix
|
||||
./authentik.nix
|
||||
];
|
||||
system.activationScripts.createPodmanNetworkWeb = lib.mkAfter ''
|
||||
if ! /run/current-system/sw/bin/podman network exists web; then
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
@@ -42,7 +41,7 @@
|
||||
|
||||
auth = {
|
||||
issuer = "https://${domain}/oauth2";
|
||||
# localAuthDisabled = true;
|
||||
localAuthDisabled = true;
|
||||
signKeyRefreshEnabled = true;
|
||||
dashboardRedirectURIs = [
|
||||
"https://${domain}/nb-auth"
|
||||
|
||||
@@ -1,211 +0,0 @@
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
# Define the Pangolin configuration as a Nix attribute set
|
||||
pangolinConfig = {
|
||||
app = {
|
||||
dashboard_url = "https://vpn.m3tam3re.com";
|
||||
log_level = "info";
|
||||
save_logs = false;
|
||||
};
|
||||
|
||||
domains = {
|
||||
vpn = {
|
||||
base_domain = "m3tam3re.com";
|
||||
cert_resolver = "godaddy";
|
||||
prefer_wildcard_cert = false;
|
||||
};
|
||||
};
|
||||
|
||||
server = {
|
||||
external_port = 3000;
|
||||
internal_port = 3001;
|
||||
next_port = 3002;
|
||||
internal_hostname = "pangolin";
|
||||
session_cookie_name = "p_session_token";
|
||||
resource_access_token_param = "p_token";
|
||||
resource_session_request_param = "p_session_request";
|
||||
};
|
||||
|
||||
traefik = {
|
||||
cert_resolver = "godaddy";
|
||||
http_entrypoint = "web";
|
||||
https_entrypoint = "websecure";
|
||||
};
|
||||
|
||||
gerbil = {
|
||||
start_port = 51820;
|
||||
base_endpoint = "vpn.m3tam3re.com";
|
||||
use_subdomain = false;
|
||||
block_size = 24;
|
||||
site_block_size = 30;
|
||||
subnet_group = "100.89.137.0/20";
|
||||
};
|
||||
|
||||
rate_limits = {
|
||||
global = {
|
||||
window_minutes = 1;
|
||||
max_requests = 100;
|
||||
};
|
||||
};
|
||||
|
||||
email = {
|
||||
smtp_host = config.age.secrets.smtp-host.path;
|
||||
smtp_port = 587;
|
||||
smtp_user = config.age.secrets.smtp-user.path;
|
||||
smtp_pass = config.age.secrets.smtp-pass.path;
|
||||
no_reply = config.age.secrets.smtp-user.path;
|
||||
};
|
||||
|
||||
users = {
|
||||
server_admin = {
|
||||
email = "admin@m3tam3re.com";
|
||||
password = config.age.secrets.pangolin-admin-password.path;
|
||||
};
|
||||
};
|
||||
|
||||
flags = {
|
||||
require_email_verification = true;
|
||||
disable_signup_without_invite = true;
|
||||
disable_user_create_org = true;
|
||||
allow_raw_resources = true;
|
||||
allow_base_domain_resources = true;
|
||||
};
|
||||
};
|
||||
|
||||
# Convert Nix attribute set to YAML using a simpler approach
|
||||
pangolinConfigYaml = pkgs.writeTextFile {
|
||||
name = "config.yml";
|
||||
text = lib.generators.toYAML {} pangolinConfig;
|
||||
};
|
||||
in {
|
||||
# Define the containers
|
||||
virtualisation.oci-containers.containers = {
|
||||
"pangolin" = {
|
||||
image = "fosrl/pangolin:1.1.0";
|
||||
autoStart = true;
|
||||
volumes = [
|
||||
"${pangolinConfigYaml}:/app/config/config.yml:ro" # Mount the config file directly
|
||||
"pangolin_config:/app/config/data" # Volume for persistent data
|
||||
];
|
||||
ports = [
|
||||
"127.0.0.1:3020:3001" # API server
|
||||
"127.0.0.1:3021:3002" # Next.js server
|
||||
"127.0.0.1:3022:3000" # API/WebSocket server
|
||||
];
|
||||
extraOptions = ["--ip=10.89.0.20" "--network=web"];
|
||||
};
|
||||
|
||||
"gerbil" = {
|
||||
image = "fosrl/gerbil:1.0.0";
|
||||
autoStart = true;
|
||||
volumes = [
|
||||
"pangolin_config:/var/config" # Share the volume for persistent data
|
||||
];
|
||||
cmd = [
|
||||
"--reachableAt=http://gerbil:3003"
|
||||
"--generateAndSaveKeyTo=/var/config/key"
|
||||
"--remoteConfig=http://pangolin:3001/api/v1/gerbil/get-config"
|
||||
"--reportBandwidthTo=http://pangolin:3001/api/v1/gerbil/receive-bandwidth"
|
||||
];
|
||||
ports = [
|
||||
"51820:51820/udp" # WireGuard port
|
||||
];
|
||||
extraOptions = [
|
||||
"--ip=10.89.0.21"
|
||||
"--network=web"
|
||||
"--cap-add=NET_ADMIN"
|
||||
"--cap-add=SYS_MODULE"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
# Secrets for Pangolin
|
||||
# age.secrets = {
|
||||
# "smtp-host" = {
|
||||
# file = ../secrets/smtp-host.age;
|
||||
# owner = "root";
|
||||
# group = "root";
|
||||
# mode = "0400";
|
||||
# };
|
||||
# "smtp-user" = {
|
||||
# file = ../secrets/smtp-user.age;
|
||||
# owner = "root";
|
||||
# group = "root";
|
||||
# mode = "0400";
|
||||
# };
|
||||
# "smtp-pass" = {
|
||||
# file = ../secrets/smtp-pass.age;
|
||||
# owner = "root";
|
||||
# group = "root";
|
||||
# mode = "0400";
|
||||
# };
|
||||
# "pangolin-admin-password" = {
|
||||
# file = ../secrets/pangolin-admin-password.age;
|
||||
# owner = "root";
|
||||
# group = "root";
|
||||
# mode = "0400";
|
||||
# };
|
||||
# };
|
||||
|
||||
# Traefik configuration for Pangolin
|
||||
services.traefik.dynamicConfigOptions = {
|
||||
http = {
|
||||
# Next.js service (front-end)
|
||||
services.pangolin-next-service.loadBalancer.servers = [
|
||||
{url = "http://localhost:3021";}
|
||||
];
|
||||
|
||||
# API service
|
||||
services.pangolin-api-service.loadBalancer.servers = [
|
||||
{url = "http://localhost:3022";}
|
||||
];
|
||||
|
||||
# Routers
|
||||
routers = {
|
||||
# Next.js router (handles everything except API paths)
|
||||
"pangolin-next" = {
|
||||
rule = "Host(`vpn.m3tam3re.com`) && !PathPrefix(`/api/v1`)";
|
||||
service = "pangolin-next-service";
|
||||
entrypoints = ["websecure"];
|
||||
tls = {
|
||||
certResolver = "godaddy";
|
||||
};
|
||||
};
|
||||
|
||||
# API router
|
||||
"pangolin-api" = {
|
||||
rule = "Host(`vpn.m3tam3re.com`) && PathPrefix(`/api/v1`)";
|
||||
service = "pangolin-api-service";
|
||||
entrypoints = ["websecure"];
|
||||
tls = {
|
||||
certResolver = "godaddy";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Add HTTP provider to Traefik for dynamic configuration from Pangolin
|
||||
services.traefik.staticConfigOptions.providers.http = {
|
||||
endpoint = "http://localhost:3020/api/v1/traefik-config";
|
||||
pollInterval = "5s";
|
||||
};
|
||||
|
||||
# Add experimental section for Badger plugin
|
||||
services.traefik.staticConfigOptions.experimental = {
|
||||
plugins = {
|
||||
#TODO create an overlay for the plugin
|
||||
badger = {
|
||||
moduleName = "github.com/fosrl/badger";
|
||||
version = "v1.0.0";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Firewall configuration for WireGuard
|
||||
networking.firewall.allowedUDPPorts = [51820]; # WireGuard port
|
||||
}
|
||||
Reference in New Issue
Block a user