Update
This commit is contained in:
@@ -7,11 +7,12 @@
|
|||||||
firewall = {
|
firewall = {
|
||||||
enable = true;
|
enable = true;
|
||||||
allowedUDPPorts =
|
allowedUDPPorts =
|
||||||
(if config.syscfg.server ? wireguard then [ 1515 ] else [ ]) ++
|
(if config.syscfg.server && config.syscfg.server.wireguard then [ 1515 ] else [ ]) ++
|
||||||
|
(if config.syscfg.server && config.syscfg.server.web then [ 80 443 22 ] else [ ]) ++
|
||||||
[ ];
|
[ ];
|
||||||
|
|
||||||
allowedTCPPorts =
|
allowedTCPPorts =
|
||||||
(if config.syscfg.server ? web then [ 80 443 22 ] else [ ]) ++
|
(if config.syscfg.server && config.syscfg.server.web then [ 80 443 22 ] else [ ]) ++
|
||||||
[ ];
|
[ ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ let
|
|||||||
builder =
|
builder =
|
||||||
{ image, secret ? ""
|
{ image, secret ? ""
|
||||||
, subdomain ? "", ip ? "", port ? 0
|
, subdomain ? "", ip ? "", port ? 0
|
||||||
, extraEnv ? { }, extraLabels ? { }
|
, extraEnv ? { }, extraLabels ? { }, extraOptions ? [ ]
|
||||||
, overrides ? { }
|
, overrides ? { }
|
||||||
}:
|
}:
|
||||||
let base = {
|
let base = {
|
||||||
@@ -23,7 +23,7 @@ let
|
|||||||
"traefik.enable" = "false";
|
"traefik.enable" = "false";
|
||||||
} // extraLabels;
|
} // extraLabels;
|
||||||
|
|
||||||
extraOptions = [
|
extraOptions = extraOptions ++ [
|
||||||
"--add-host=host.containers.internal:host-gateway"
|
"--add-host=host.containers.internal:host-gateway"
|
||||||
] ++ lib.optional (ip != "") "--ip=${ip}";
|
] ++ lib.optional (ip != "") "--ip=${ip}";
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{ config, containerCfg, pkgs, lib, builder, ... }:
|
{ config, containerCfg, pkgs, lib, builder, ... }:
|
||||||
let
|
let
|
||||||
|
version = "2026.2.2";
|
||||||
serverCfg = config.syscfg.server;
|
serverCfg = config.syscfg.server;
|
||||||
in {
|
in {
|
||||||
paths = [{
|
paths = [{
|
||||||
@@ -15,7 +16,7 @@ in {
|
|||||||
containers = {
|
containers = {
|
||||||
server = builder.mkContainer {
|
server = builder.mkContainer {
|
||||||
subdomain = containerCfg.subdomain;
|
subdomain = containerCfg.subdomain;
|
||||||
image = "ghcr.io/goauthentik/server:latest";
|
image = "ghcr.io/goauthentik/server:${version}";
|
||||||
port = containerCfg.port;
|
port = containerCfg.port;
|
||||||
ip = containerCfg.ip;
|
ip = containerCfg.ip;
|
||||||
secret = "authentik";
|
secret = "authentik";
|
||||||
@@ -31,10 +32,12 @@ in {
|
|||||||
"AUTHENTIK_EMAIL__USE_SSL" = "false";
|
"AUTHENTIK_EMAIL__USE_SSL" = "false";
|
||||||
"AUTHENTIK_EMAIL__TIMEOUT" = "10";
|
"AUTHENTIK_EMAIL__TIMEOUT" = "10";
|
||||||
"AUTHENTIK_EMAIL__FROM" = "sso@noreply.${serverCfg.hostDomain}";
|
"AUTHENTIK_EMAIL__FROM" = "sso@noreply.${serverCfg.hostDomain}";
|
||||||
|
"AUTHENTIK_DISABLE_UPDATE_CHECK" = "true";
|
||||||
|
"AUTHENTIK_POSTGRESQL__SSLMODE" = "disable";
|
||||||
};
|
};
|
||||||
overrides = {
|
overrides = {
|
||||||
cmd = [ "server" ];
|
cmd = [ "server" ];
|
||||||
ports = [ "9999:${toString containerCfg.port}" ];
|
ports = if containerCfg.pubPort != 0 && containerCfg.port != 0 then [ "${toString containerCfg.pubPort}:${toString containerCfg.port}" ] else [];
|
||||||
volumes = [
|
volumes = [
|
||||||
"${serverCfg.dataPath}/authentik/media:/media"
|
"${serverCfg.dataPath}/authentik/media:/media"
|
||||||
"${serverCfg.dataPath}/authentik/templates:/templates"
|
"${serverCfg.dataPath}/authentik/templates:/templates"
|
||||||
@@ -43,20 +46,23 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
worker = builder.mkContainer {
|
worker = builder.mkContainer {
|
||||||
image = "ghcr.io/goauthentik/server:latest";
|
image = "ghcr.io/goauthentik/server:${version}";
|
||||||
secret = "authentik";
|
secret = "authentik";
|
||||||
extraEnv = {
|
extraEnv = {
|
||||||
"AUTHENTIK_REDIS__HOST" = builder.host;
|
"AUTHENTIK_REDIS__HOST" = builder.host;
|
||||||
"AUTHENTIK_POSTGRESQL__HOST" = builder.host;
|
"AUTHENTIK_POSTGRESQL__HOST" = builder.host;
|
||||||
"AUTHENTIK_POSTGRESQL__USER" = "authentik_user";
|
"AUTHENTIK_POSTGRESQL__USER" = "authentik_user";
|
||||||
"AUTHENTIK_POSTGRESQL__NAME" = "authentik_db";
|
"AUTHENTIK_POSTGRESQL__NAME" = "authentik_db";
|
||||||
|
"AUTHENTIK_DISABLE_UPDATE_CHECK" = "true";
|
||||||
|
"AUTHENTIK_POSTGRESQL__SSLMODE" = "disable";
|
||||||
};
|
};
|
||||||
|
extraOptions = [ "--user=:994" ]; #PODMAN GROUP FOR SOCKET ACCESS
|
||||||
overrides = {
|
overrides = {
|
||||||
cmd = [ "worker" ];
|
cmd = [ "worker" ];
|
||||||
volumes = [
|
volumes = [
|
||||||
"${serverCfg.dataPath}/authentik/media:/media"
|
"${serverCfg.dataPath}/authentik/media:/media"
|
||||||
"${serverCfg.dataPath}/authentik/templates:/templates"
|
"${serverCfg.dataPath}/authentik/templates:/templates"
|
||||||
"/var/run/docker.sock:/var/run/docker.sock"
|
"/var/run/podman/podman.sock:/var/run/docker.sock" #PODMAN GROUP FOR SOCKET ACCESS
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
{ config, pkgs, lib, ... }:{
|
{ config, pkgs, lib, ... }:{
|
||||||
imports = [ ./containers ./database ./nftables ./openssh ./sops ];
|
imports = [ ./containers ./database ./nftables ./nginx ./openssh ./sops ];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
{ config, lib, ... }:{
|
{ config, lib, ... }:{
|
||||||
config = lib.mkIf (config.syscfg.server.nftables.enable) {
|
config = lib.mkIf (config.syscfg.server.nftables.enable) {
|
||||||
boot.kernel.sysctl = {
|
boot.kernel.sysctl = {
|
||||||
@@ -11,8 +9,12 @@
|
|||||||
networking.nftables.ruleset = ''
|
networking.nftables.ruleset = ''
|
||||||
table inet filter {
|
table inet filter {
|
||||||
chain input {
|
chain input {
|
||||||
type filter hook input priority filter; policy accept;
|
type filter hook input priority filter; policy drop;
|
||||||
|
ct state established,related accept
|
||||||
|
iifname "lo" accept
|
||||||
tcp dport {5432, 6379} ip saddr { 10.0.0.0/8 169.254.0.0/16 } accept
|
tcp dport {5432, 6379} ip saddr { 10.0.0.0/8 169.254.0.0/16 } accept
|
||||||
|
tcp dport {80, 443, 22} accept
|
||||||
|
udp dport {80, 443, 22} accept
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,45 +1,133 @@
|
|||||||
{ config, lib, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
let
|
let
|
||||||
cfg = config.syscfg.server;
|
cfg = config.syscfg.server;
|
||||||
containers = cfg.containers;
|
containers = cfg.containers;
|
||||||
|
faviconOverride = {
|
||||||
# Function to convert your container config into an NGINX vhost
|
" ~* /favicon\.(ico|png|svg|jpg)$" = {
|
||||||
mkVhost = name: container: {
|
extraConfig = ''
|
||||||
forceSSL = true;
|
add_header Content-Type image/svg+xml;
|
||||||
useACMEHost = "${cfg.hostDomain}";
|
return 200 '<svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" data-name="Layer 1" viewBox="0 0 50 50"><defs><style>.cls-1{fill:#fd4b2d;}</style></defs><path class="cls-1" d="M30.83,5A23.23,23.23,0,0,0,10.41,67.13h10.8C26,63,32.94,61.8,38,67.13H49.39C44.93,61.09,38.24,55,30.83,55Z"/><path class="cls-1" d="M46.25,28.11c-14.89,31.15-41,4.6-25-11H10.41c-8.47,14.76,3.24,34.68,20.42,34.23,13.28,0,24.24-19.72,24.24-23.21,0-1.54-2.14-6.25-5.68-11H38A40.52,40.52,0,0,1,46.25,78.11Zm.4-.91Z"/></svg>';
|
||||||
locations."/" = {
|
'';
|
||||||
proxyPass = "http://${container.ip}:${toString container.port}";
|
# proxyPass = "http://127.0.0.1:9000";
|
||||||
proxyWebsockets = true; # Recommended for modern apps
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
# Function to convert your container config into an NGINX vhost
|
||||||
|
mkVhost = container: {
|
||||||
|
forceSSL = true;
|
||||||
|
# quic = true;
|
||||||
|
# http3 = true;
|
||||||
|
useACMEHost = "${cfg.hostDomain}";
|
||||||
|
locations = faviconOverride // {
|
||||||
|
"/" = {
|
||||||
|
proxyPass = "http://${container.ip}:${toString container.port}";
|
||||||
|
proxyWebsockets = true; # Recommended for modern apps
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
in {
|
in {
|
||||||
|
config = lib.mkIf ( config.syscfg.server.web) {
|
||||||
|
security.acme = {
|
||||||
|
acceptTerms = true;
|
||||||
|
defaults.email = "admin@domain.org";
|
||||||
|
|
||||||
|
certs."${cfg.hostDomain}" = {
|
||||||
|
domain = "*.${cfg.hostDomain}";
|
||||||
|
extraDomainNames = [ "${cfg.hostDomain}" ]; # Adds the root too
|
||||||
|
dnsProvider = "infomaniak";
|
||||||
|
credentialsFile = config.sops.secrets."INFOMANIAK_API_KEY".path; # File containing your API token (e.g. CLOUDFLARE_DNS_API_TOKEN=...)
|
||||||
|
group = "nginx";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
security.acme = {
|
services.nginx = {
|
||||||
acceptTerms = true;
|
enable = true;
|
||||||
defaults.email = "admin@domain.org";
|
recommendedProxySettings = true;
|
||||||
|
recommendedTlsSettings = true;
|
||||||
|
recommendedGzipSettings = true;
|
||||||
|
|
||||||
certs."${cfg.hostDomain}" = {
|
# appendHttpConfig = ''
|
||||||
domain = "*.${cfg.hostDomain}";
|
# add_header Alt-Svc 'h3=":443"; ma=86400';
|
||||||
extraDomainNames = [ "${cfg.hostDomain}" ]; # Adds the root too
|
# '';
|
||||||
dnsProvider = "cloudflare"; # Change to your provider
|
commonHttpConfig = ''
|
||||||
# File containing your API token (e.g. CLOUDFLARE_DNS_API_TOKEN=...)
|
proxy_buffer_size 32k;
|
||||||
credentialsFile = "/var/lib/secrets/acme-dns.env";
|
proxy_buffers 8 16k;
|
||||||
group = "nginx";
|
proxy_busy_buffers_size 48k;
|
||||||
|
port_in_redirect off;
|
||||||
|
'';
|
||||||
|
|
||||||
|
virtualHosts = {
|
||||||
|
"_" = {
|
||||||
|
default = true;
|
||||||
|
forceSSL = true;
|
||||||
|
# quic = true;
|
||||||
|
# http3 = true;
|
||||||
|
useACMEHost = "${cfg.hostDomain}";
|
||||||
|
|
||||||
|
locations = {
|
||||||
|
"/" = {
|
||||||
|
extraConfig = ''
|
||||||
|
return 404;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
"sec.localhost" = {
|
||||||
|
forceSSL = true;
|
||||||
|
# quic = true;
|
||||||
|
# http3 = true;
|
||||||
|
useACMEHost = "${cfg.hostDomain}";
|
||||||
|
|
||||||
|
locations = {
|
||||||
|
"/" = {
|
||||||
|
extraConfig = ''
|
||||||
|
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
|
||||||
|
proxy_set_header X-Original-URI $scheme://$http_host$request_uri;
|
||||||
|
auth_request /outpost.goauthentik.io/auth/nginx;
|
||||||
|
error_page 401 = @goauthentik_proxy_signin;
|
||||||
|
auth_request_set $auth_cookie $upstream_http_set_cookie;
|
||||||
|
add_header Set-Cookie $auth_cookie;
|
||||||
|
|
||||||
|
auth_request_set $authentik_username $upstream_http_x_authentik_username;
|
||||||
|
auth_request_set $authentik_groups $upstream_http_x_authentik_groups;
|
||||||
|
auth_request_set $authentik_entitlements $upstream_http_x_authentik_entitlements;
|
||||||
|
auth_request_set $authentik_email $upstream_http_x_authentik_email;
|
||||||
|
auth_request_set $authentik_name $upstream_http_x_authentik_name;
|
||||||
|
auth_request_set $authentik_uid $upstream_http_x_authentik_uid;
|
||||||
|
|
||||||
|
proxy_set_header X-authentik-username $authentik_username;
|
||||||
|
proxy_set_header X-authentik-groups $authentik_groups;
|
||||||
|
proxy_set_header X-authentik-entitlements $authentik_entitlements;
|
||||||
|
proxy_set_header X-authentik-email $authentik_email;
|
||||||
|
proxy_set_header X-authentik-name $authentik_name;
|
||||||
|
proxy_set_header X-authentik-uid $authentik_uid;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
"/outpost.goauthentik.io" = {
|
||||||
|
proxyPass = "http://${config.syscfg.server.containers.authentik.ip}:${toString config.syscfg.server.containers.authentik.port}/outpost.goauthentik.io";
|
||||||
|
extraConfig = ''
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
|
||||||
|
proxy_set_header X-Original-URI $scheme://$http_host$request_uri;
|
||||||
|
add_header Set-Cookie $auth_cookie;
|
||||||
|
auth_request_set $auth_cookie $upstream_http_set_cookie;
|
||||||
|
proxy_pass_request_body off;
|
||||||
|
proxy_set_header Content-Length "";
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
extraConfig = ''
|
||||||
|
location @goauthentik_proxy_signin {
|
||||||
|
internal;
|
||||||
|
add_header Set-Cookie $auth_cookie;
|
||||||
|
return 302 https://sso.localhost/outpost.goauthentik.io/start?rd=$scheme://$http_host$request_uri;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
} //lib.mapAttrs' (name: v:
|
||||||
|
lib.nameValuePair "${v.subdomain}.${cfg.hostDomain}" (mkVhost v)
|
||||||
|
) containers;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
services.nginx = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
recommendedProxySettings = true;
|
|
||||||
recommendedTlsSettings = true;
|
|
||||||
|
|
||||||
virtualHosts = lib.mapAttrs' (name: value:
|
|
||||||
lib.nameValuePair "${value.subdomain}.${cfg.hostDomain}" (mkVhost name value)
|
|
||||||
) cfg;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Open the firewall
|
|
||||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
|
||||||
}
|
|
||||||
@@ -107,8 +107,10 @@ let
|
|||||||
options = {
|
options = {
|
||||||
enable = mkOption { type = types.bool;default = false; };
|
enable = mkOption { type = types.bool;default = false; };
|
||||||
db = mkOption { type = types.bool;default = false; };
|
db = mkOption { type = types.bool;default = false; };
|
||||||
ip = mkOption { type = types.str; };
|
ip = mkOption { type = types.nullOr types.str; default = null;};
|
||||||
port = mkOption { type = types.port; };
|
subdomain = mkOption { type = types.nullOr types.str; default=null;};
|
||||||
|
port = mkOption { type = types.port; default = 0; };
|
||||||
|
pubPort = mkOption { type = types.port; default = 0; };
|
||||||
extraParam = mkOption { type = types.str; default = ""; };
|
extraParam = mkOption { type = types.str; default = ""; };
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user