mirror of
https://github.com/Swarsel/.dotfiles.git
synced 2025-12-06 00:57:22 +01:00
feat[work,server,client]: add opkssh
Some checks failed
Flake check / Check flake (push) Has been cancelled
Some checks failed
Flake check / Check flake (push) Has been cancelled
This commit is contained in:
parent
3b368ec8de
commit
c9e7e493d8
14 changed files with 604 additions and 340 deletions
|
|
@ -437,8 +437,8 @@ A short overview over each input and what it does:
|
|||
swarsel-modules.url = "github:Swarsel/swarsel-modules/main";
|
||||
swarsel-nix.url = "github:Swarsel/swarsel-nix/main";
|
||||
home-manager = {
|
||||
url = "github:nix-community/home-manager";
|
||||
# url = "github:Swarsel/home-manager/main";
|
||||
# url = "github:nix-community/home-manager";
|
||||
url = "github:Swarsel/home-manager/main";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
swarsel.url = "github:Swarsel/.dotfiles";
|
||||
|
|
@ -2472,6 +2472,7 @@ This is my main server that I run at home. It handles most tasks that require bi
|
|||
ankisync = lib.mkDefault true;
|
||||
# snipeit = lib.mkDefault false;
|
||||
homebox = lib.mkDefault true;
|
||||
opkssh = lib.mkDefault true;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -8788,317 +8789,335 @@ A stupid (but simple) way to get the =originUrl= is to simply set any URL there
|
|||
To get other URLs (token, etc.), use https://<kanidmDomain>/oauth2/openid/<clientID>/.well-known/oauth-authorization-server, e.g. https://<kanidmDomain>/oauth2/openid/nextcloud/.well-known/oauth-authorization-server, with clienID being the client name as specified in kanidm.
|
||||
|
||||
#+begin_src nix-ts :tangle modules/nixos/server/kanidm.nix
|
||||
{ self, lib, pkgs, config, globals, ... }:
|
||||
let
|
||||
certsSopsFile = self + /secrets/certs/secrets.yaml;
|
||||
inherit (config.swarselsystems) sopsFile;
|
||||
{ self, lib, pkgs, config, globals, ... }:
|
||||
let
|
||||
certsSopsFile = self + /secrets/certs/secrets.yaml;
|
||||
inherit (config.swarselsystems) sopsFile;
|
||||
|
||||
servicePort = 8300;
|
||||
serviceUser = "kanidm";
|
||||
serviceGroup = serviceUser;
|
||||
serviceName = "kanidm";
|
||||
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
|
||||
serviceAddress = globals.hosts.winters.ipv4;
|
||||
servicePort = 8300;
|
||||
serviceUser = "kanidm";
|
||||
serviceGroup = serviceUser;
|
||||
serviceName = "kanidm";
|
||||
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
|
||||
serviceAddress = globals.hosts.winters.ipv4;
|
||||
|
||||
oauth2ProxyDomain = globals.services.oauth2Proxy.domain;
|
||||
immichDomain = globals.services.immich.domain;
|
||||
paperlessDomain = globals.services.paperless.domain;
|
||||
forgejoDomain = globals.services.forgejo.domain;
|
||||
grafanaDomain = globals.services.grafana.domain;
|
||||
nextcloudDomain = globals.services.nextcloud.domain;
|
||||
oauth2ProxyDomain = globals.services.oauth2Proxy.domain;
|
||||
immichDomain = globals.services.immich.domain;
|
||||
paperlessDomain = globals.services.paperless.domain;
|
||||
forgejoDomain = globals.services.forgejo.domain;
|
||||
grafanaDomain = globals.services.grafana.domain;
|
||||
nextcloudDomain = globals.services.nextcloud.domain;
|
||||
|
||||
certBase = "/etc/ssl";
|
||||
certsDir = "${certBase}/certs";
|
||||
privateDir = "${certBase}/private";
|
||||
certPath = "${certsDir}/${serviceName}.crt";
|
||||
keyPath = "${privateDir}/${serviceName}.key";
|
||||
in
|
||||
{
|
||||
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
|
||||
config = lib.mkIf config.swarselmodules.server.${serviceName} {
|
||||
certBase = "/etc/ssl";
|
||||
certsDir = "${certBase}/certs";
|
||||
privateDir = "${certBase}/private";
|
||||
certPath = "${certsDir}/${serviceName}.crt";
|
||||
keyPath = "${privateDir}/${serviceName}.key";
|
||||
in
|
||||
{
|
||||
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
|
||||
config = lib.mkIf config.swarselmodules.server.${serviceName} {
|
||||
|
||||
users.users.${serviceUser} = {
|
||||
group = serviceGroup;
|
||||
isSystemUser = true;
|
||||
};
|
||||
|
||||
users.groups.${serviceGroup} = { };
|
||||
|
||||
sops = {
|
||||
secrets = {
|
||||
"kanidm-self-signed-crt" = { sopsFile = certsSopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-self-signed-key" = { sopsFile = certsSopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-admin-pw" = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-idm-admin-pw" = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-immich" = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-paperless" = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-forgejo" = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-grafana" = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-nextcloud" = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-freshrss" = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-oauth2-proxy" = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
users.users.${serviceUser} = {
|
||||
group = serviceGroup;
|
||||
isSystemUser = true;
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ servicePort ];
|
||||
users.groups.${serviceGroup} = { };
|
||||
|
||||
globals.services.${serviceName}.domain = serviceDomain;
|
||||
sops = {
|
||||
secrets = {
|
||||
"kanidm-self-signed-crt" = { sopsFile = certsSopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-self-signed-key" = { sopsFile = certsSopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-admin-pw" = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-idm-admin-pw" = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-immich" = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-paperless" = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-forgejo" = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-grafana" = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-nextcloud" = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-freshrss" = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-oauth2-proxy" = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
};
|
||||
};
|
||||
|
||||
system.activationScripts."generateSSLCert-${serviceName}" =
|
||||
let
|
||||
daysValid = 3650;
|
||||
renewBeforeDays = 365;
|
||||
in
|
||||
{
|
||||
text = ''
|
||||
set -eu
|
||||
networking.firewall.allowedTCPPorts = [ servicePort ];
|
||||
|
||||
${pkgs.coreutils}/bin/install -d -m 0755 ${certsDir}
|
||||
${pkgs.coreutils}/bin/install -d -m 0750 ${privateDir}
|
||||
globals.services.${serviceName}.domain = serviceDomain;
|
||||
|
||||
need_gen=0
|
||||
if [ ! -f "${certPath}" ] || [ ! -f "${keyPath}" ]; then
|
||||
need_gen=1
|
||||
else
|
||||
enddate="$(${pkgs.openssl}/bin/openssl x509 -noout -enddate -in "${certPath}" | cut -d= -f2)"
|
||||
end_epoch="$(${pkgs.coreutils}/bin/date -d "$enddate" +%s)"
|
||||
now_epoch="$(${pkgs.coreutils}/bin/date +%s)"
|
||||
seconds_left=$(( end_epoch - now_epoch ))
|
||||
days_left=$(( seconds_left / 86400 ))
|
||||
if [ "$days_left" -lt ${toString renewBeforeDays} ]; then
|
||||
system.activationScripts."generateSSLCert-${serviceName}" =
|
||||
let
|
||||
daysValid = 3650;
|
||||
renewBeforeDays = 365;
|
||||
in
|
||||
{
|
||||
text = ''
|
||||
set -eu
|
||||
|
||||
${pkgs.coreutils}/bin/install -d -m 0755 ${certsDir}
|
||||
${pkgs.coreutils}/bin/install -d -m 0750 ${privateDir}
|
||||
|
||||
need_gen=0
|
||||
if [ ! -f "${certPath}" ] || [ ! -f "${keyPath}" ]; then
|
||||
need_gen=1
|
||||
else
|
||||
enddate="$(${pkgs.openssl}/bin/openssl x509 -noout -enddate -in "${certPath}" | cut -d= -f2)"
|
||||
end_epoch="$(${pkgs.coreutils}/bin/date -d "$enddate" +%s)"
|
||||
now_epoch="$(${pkgs.coreutils}/bin/date +%s)"
|
||||
seconds_left=$(( end_epoch - now_epoch ))
|
||||
days_left=$(( seconds_left / 86400 ))
|
||||
if [ "$days_left" -lt ${toString renewBeforeDays} ]; then
|
||||
need_gen=1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$need_gen" -eq 1 ]; then
|
||||
${pkgs.openssl}/bin/openssl req -x509 -nodes -days ${toString daysValid} -newkey rsa:4096 -sha256 \
|
||||
-keyout "${keyPath}" \
|
||||
-out "${certPath}" \
|
||||
-subj "/CN=${serviceDomain}" \
|
||||
-addext "subjectAltName=DNS:${serviceDomain}"
|
||||
if [ "$need_gen" -eq 1 ]; then
|
||||
${pkgs.openssl}/bin/openssl req -x509 -nodes -days ${toString daysValid} -newkey rsa:4096 -sha256 \
|
||||
-keyout "${keyPath}" \
|
||||
-out "${certPath}" \
|
||||
-subj "/CN=${serviceDomain}" \
|
||||
-addext "subjectAltName=DNS:${serviceDomain}"
|
||||
|
||||
chmod 0644 "${certPath}"
|
||||
chmod 0600 "${keyPath}"
|
||||
chown ${serviceUser}:${serviceGroup} "${certPath}" "${keyPath}"
|
||||
fi
|
||||
'';
|
||||
deps = [ "etc" ];
|
||||
};
|
||||
|
||||
services = {
|
||||
${serviceName} = {
|
||||
package = pkgs.kanidmWithSecretProvisioning_1_7;
|
||||
enableServer = true;
|
||||
serverSettings = {
|
||||
domain = serviceDomain;
|
||||
origin = "https://${serviceDomain}";
|
||||
# tls_chain = config.sops.secrets.kanidm-self-signed-crt.path;
|
||||
tls_chain = certPath;
|
||||
# tls_key = config.sops.secrets.kanidm-self-signed-key.path;
|
||||
tls_key = keyPath;
|
||||
bindaddress = "0.0.0.0:${toString servicePort}";
|
||||
trust_x_forward_for = true;
|
||||
};
|
||||
enableClient = true;
|
||||
clientSettings = {
|
||||
uri = config.services.kanidm.serverSettings.origin;
|
||||
verify_ca = true;
|
||||
verify_hostnames = true;
|
||||
};
|
||||
provision = {
|
||||
enable = true;
|
||||
adminPasswordFile = config.sops.secrets.kanidm-admin-pw.path;
|
||||
idmAdminPasswordFile = config.sops.secrets.kanidm-idm-admin-pw.path;
|
||||
groups = {
|
||||
"immich.access" = { };
|
||||
"paperless.access" = { };
|
||||
"forgejo.access" = { };
|
||||
"forgejo.admins" = { };
|
||||
"grafana.access" = { };
|
||||
"grafana.editors" = { };
|
||||
"grafana.admins" = { };
|
||||
"grafana.server-admins" = { };
|
||||
"nextcloud.access" = { };
|
||||
"nextcloud.admins" = { };
|
||||
"navidrome.access" = { };
|
||||
"freshrss.access" = { };
|
||||
"firefly.access" = { };
|
||||
"radicale.access" = { };
|
||||
"slink.access" = { };
|
||||
};
|
||||
|
||||
inherit (config.repo.secrets.local) persons;
|
||||
|
||||
systems = {
|
||||
oauth2 = {
|
||||
immich = {
|
||||
displayName = "Immich";
|
||||
originUrl = [
|
||||
"https://${immichDomain}/auth/login"
|
||||
"https://${immichDomain}/user-settings"
|
||||
"app.immich:///oauth-callback"
|
||||
"https://${immichDomain}/api/oauth/mobile-redirect"
|
||||
];
|
||||
originLanding = "https://${immichDomain}/";
|
||||
basicSecretFile = config.sops.secrets.kanidm-immich.path;
|
||||
preferShortUsername = true;
|
||||
enableLegacyCrypto = true; # can use RS256 / HS256, not ES256
|
||||
scopeMaps."immich.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
};
|
||||
paperless = {
|
||||
displayName = "Paperless";
|
||||
originUrl = "https://${paperlessDomain}/accounts/oidc/kanidm/login/callback/";
|
||||
originLanding = "https://${paperlessDomain}/";
|
||||
basicSecretFile = config.sops.secrets.kanidm-paperless.path;
|
||||
preferShortUsername = true;
|
||||
scopeMaps."paperless.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
};
|
||||
forgejo = {
|
||||
displayName = "Forgejo";
|
||||
originUrl = "https://${forgejoDomain}/user/oauth2/kanidm/callback";
|
||||
originLanding = "https://${forgejoDomain}/";
|
||||
basicSecretFile = config.sops.secrets.kanidm-forgejo.path;
|
||||
scopeMaps."forgejo.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
# XXX: PKCE is currently not supported by gitea/forgejo,
|
||||
# see https://github.com/go-gitea/gitea/issues/21376.
|
||||
allowInsecureClientDisablePkce = true;
|
||||
preferShortUsername = true;
|
||||
claimMaps.groups = {
|
||||
joinType = "array";
|
||||
valuesByGroup."forgejo.admins" = [ "admin" ];
|
||||
};
|
||||
};
|
||||
grafana = {
|
||||
displayName = "Grafana";
|
||||
originUrl = "https://${grafanaDomain}/login/generic_oauth";
|
||||
originLanding = "https://${grafanaDomain}/";
|
||||
basicSecretFile = config.sops.secrets.kanidm-grafana.path;
|
||||
preferShortUsername = true;
|
||||
scopeMaps."grafana.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
claimMaps.groups = {
|
||||
joinType = "array";
|
||||
valuesByGroup = {
|
||||
"grafana.editors" = [ "editor" ];
|
||||
"grafana.admins" = [ "admin" ];
|
||||
"grafana.server-admins" = [ "server_admin" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
nextcloud = {
|
||||
displayName = "Nextcloud";
|
||||
originUrl = " https://${nextcloudDomain}/apps/sociallogin/custom_oidc/kanidm";
|
||||
originLanding = "https://${nextcloudDomain}/";
|
||||
basicSecretFile = config.sops.secrets.kanidm-nextcloud.path;
|
||||
allowInsecureClientDisablePkce = true;
|
||||
scopeMaps."nextcloud.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
preferShortUsername = true;
|
||||
claimMaps.groups = {
|
||||
joinType = "array";
|
||||
valuesByGroup = {
|
||||
"nextcloud.admins" = [ "admin" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
oauth2-proxy = {
|
||||
displayName = "Oauth2-Proxy";
|
||||
originUrl = "https://${oauth2ProxyDomain}/oauth2/callback";
|
||||
originLanding = "https://${oauth2ProxyDomain}/";
|
||||
basicSecretFile = config.sops.secrets.kanidm-oauth2-proxy.path;
|
||||
scopeMaps = {
|
||||
"freshrss.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
"navidrome.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
"firefly.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
"radicale.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
"slink.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
};
|
||||
preferShortUsername = true;
|
||||
claimMaps.groups = {
|
||||
joinType = "array";
|
||||
valuesByGroup = {
|
||||
"freshrss.access" = [ "ttrss_access" ];
|
||||
"navidrome.access" = [ "navidrome_access" ];
|
||||
"firefly.access" = [ "firefly_access" ];
|
||||
"radicale.access" = [ "radicale_access" ];
|
||||
"slink.access" = [ "slink_access" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services = {
|
||||
${serviceName}.serviceConfig.RestartSec = "30";
|
||||
};
|
||||
|
||||
nodes.moonside.services.nginx = {
|
||||
upstreams = {
|
||||
${serviceName} = {
|
||||
servers = {
|
||||
"${serviceAddress}:${builtins.toString servicePort}" = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
virtualHosts = {
|
||||
"${serviceDomain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "https://${serviceName}";
|
||||
};
|
||||
};
|
||||
extraConfig = ''
|
||||
proxy_ssl_verify off;
|
||||
chmod 0644 "${certPath}"
|
||||
chmod 0600 "${keyPath}"
|
||||
chown ${serviceUser}:${serviceGroup} "${certPath}" "${keyPath}"
|
||||
fi
|
||||
'';
|
||||
deps = [ "etc" ];
|
||||
};
|
||||
|
||||
services = {
|
||||
${serviceName} = {
|
||||
package = pkgs.kanidmWithSecretProvisioning_1_7;
|
||||
enableServer = true;
|
||||
serverSettings = {
|
||||
domain = serviceDomain;
|
||||
origin = "https://${serviceDomain}";
|
||||
# tls_chain = config.sops.secrets.kanidm-self-signed-crt.path;
|
||||
tls_chain = certPath;
|
||||
# tls_key = config.sops.secrets.kanidm-self-signed-key.path;
|
||||
tls_key = keyPath;
|
||||
bindaddress = "0.0.0.0:${toString servicePort}";
|
||||
trust_x_forward_for = true;
|
||||
};
|
||||
enableClient = true;
|
||||
clientSettings = {
|
||||
uri = config.services.kanidm.serverSettings.origin;
|
||||
verify_ca = true;
|
||||
verify_hostnames = true;
|
||||
};
|
||||
provision = {
|
||||
enable = true;
|
||||
adminPasswordFile = config.sops.secrets.kanidm-admin-pw.path;
|
||||
idmAdminPasswordFile = config.sops.secrets.kanidm-idm-admin-pw.path;
|
||||
groups = {
|
||||
"immich.access" = { };
|
||||
"paperless.access" = { };
|
||||
"forgejo.access" = { };
|
||||
"forgejo.admins" = { };
|
||||
"grafana.access" = { };
|
||||
"grafana.editors" = { };
|
||||
"grafana.admins" = { };
|
||||
"grafana.server-admins" = { };
|
||||
"nextcloud.access" = { };
|
||||
"nextcloud.admins" = { };
|
||||
"navidrome.access" = { };
|
||||
"freshrss.access" = { };
|
||||
"firefly.access" = { };
|
||||
"radicale.access" = { };
|
||||
"slink.access" = { };
|
||||
"opkssh.access" = { };
|
||||
};
|
||||
|
||||
inherit (config.repo.secrets.local) persons;
|
||||
|
||||
systems = {
|
||||
oauth2 = {
|
||||
immich = {
|
||||
displayName = "Immich";
|
||||
originUrl = [
|
||||
"https://${immichDomain}/auth/login"
|
||||
"https://${immichDomain}/user-settings"
|
||||
"app.immich:///oauth-callback"
|
||||
"https://${immichDomain}/api/oauth/mobile-redirect"
|
||||
];
|
||||
originLanding = "https://${immichDomain}/";
|
||||
basicSecretFile = config.sops.secrets.kanidm-immich.path;
|
||||
preferShortUsername = true;
|
||||
enableLegacyCrypto = true; # can use RS256 / HS256, not ES256
|
||||
scopeMaps."immich.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
};
|
||||
paperless = {
|
||||
displayName = "Paperless";
|
||||
originUrl = "https://${paperlessDomain}/accounts/oidc/kanidm/login/callback/";
|
||||
originLanding = "https://${paperlessDomain}/";
|
||||
basicSecretFile = config.sops.secrets.kanidm-paperless.path;
|
||||
preferShortUsername = true;
|
||||
scopeMaps."paperless.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
};
|
||||
forgejo = {
|
||||
displayName = "Forgejo";
|
||||
originUrl = "https://${forgejoDomain}/user/oauth2/kanidm/callback";
|
||||
originLanding = "https://${forgejoDomain}/";
|
||||
basicSecretFile = config.sops.secrets.kanidm-forgejo.path;
|
||||
scopeMaps."forgejo.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
# XXX: PKCE is currently not supported by gitea/forgejo,
|
||||
# see https://github.com/go-gitea/gitea/issues/21376.
|
||||
allowInsecureClientDisablePkce = true;
|
||||
preferShortUsername = true;
|
||||
claimMaps.groups = {
|
||||
joinType = "array";
|
||||
valuesByGroup."forgejo.admins" = [ "admin" ];
|
||||
};
|
||||
};
|
||||
grafana = {
|
||||
displayName = "Grafana";
|
||||
originUrl = "https://${grafanaDomain}/login/generic_oauth";
|
||||
originLanding = "https://${grafanaDomain}/";
|
||||
basicSecretFile = config.sops.secrets.kanidm-grafana.path;
|
||||
preferShortUsername = true;
|
||||
scopeMaps."grafana.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
claimMaps.groups = {
|
||||
joinType = "array";
|
||||
valuesByGroup = {
|
||||
"grafana.editors" = [ "editor" ];
|
||||
"grafana.admins" = [ "admin" ];
|
||||
"grafana.server-admins" = [ "server_admin" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
nextcloud = {
|
||||
displayName = "Nextcloud";
|
||||
originUrl = " https://${nextcloudDomain}/apps/sociallogin/custom_oidc/kanidm";
|
||||
originLanding = "https://${nextcloudDomain}/";
|
||||
basicSecretFile = config.sops.secrets.kanidm-nextcloud.path;
|
||||
allowInsecureClientDisablePkce = true;
|
||||
scopeMaps."nextcloud.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
preferShortUsername = true;
|
||||
claimMaps.groups = {
|
||||
joinType = "array";
|
||||
valuesByGroup = {
|
||||
"nextcloud.admins" = [ "admin" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
opkssh = {
|
||||
displayName = "OPKSSH";
|
||||
originUrl = [
|
||||
"http://localhost:3000"
|
||||
"http://localhost:3000/login-callback"
|
||||
"http://localhost:10001/login-callback"
|
||||
"http://localhost:11110/login-callback"
|
||||
];
|
||||
originLanding = "http://localhost:3000";
|
||||
public = true;
|
||||
enableLocalhostRedirects = true;
|
||||
scopeMaps."opkssh.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
};
|
||||
oauth2-proxy = {
|
||||
displayName = "Oauth2-Proxy";
|
||||
originUrl = "https://${oauth2ProxyDomain}/oauth2/callback";
|
||||
originLanding = "https://${oauth2ProxyDomain}/";
|
||||
basicSecretFile = config.sops.secrets.kanidm-oauth2-proxy.path;
|
||||
scopeMaps = {
|
||||
"freshrss.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
"navidrome.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
"firefly.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
"radicale.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
"slink.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
};
|
||||
preferShortUsername = true;
|
||||
claimMaps.groups = {
|
||||
joinType = "array";
|
||||
valuesByGroup = {
|
||||
"freshrss.access" = [ "ttrss_access" ];
|
||||
"navidrome.access" = [ "navidrome_access" ];
|
||||
"firefly.access" = [ "firefly_access" ];
|
||||
"radicale.access" = [ "radicale_access" ];
|
||||
"slink.access" = [ "slink_access" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services = {
|
||||
${serviceName}.serviceConfig.RestartSec = "30";
|
||||
};
|
||||
|
||||
nodes.moonside.services.nginx = {
|
||||
upstreams = {
|
||||
${serviceName} = {
|
||||
servers = {
|
||||
"${serviceAddress}:${builtins.toString servicePort}" = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
virtualHosts = {
|
||||
"${serviceDomain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "https://${serviceName}";
|
||||
};
|
||||
};
|
||||
extraConfig = ''
|
||||
proxy_ssl_verify off;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
#+end_src
|
||||
|
||||
**** oauth2-proxy
|
||||
|
|
@ -9738,9 +9757,15 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d ${cfg.settings.storage.filesystem_folder} 0750 ${serviceUser} ${serviceGroup} - -"
|
||||
];
|
||||
systemd.tmpfiles.settings."10-radicale" = {
|
||||
"${cfg.settings.storage.filesystem_folder}" = {
|
||||
d = {
|
||||
group = serviceGroup;
|
||||
user = serviceUser;
|
||||
mode = "0750";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ servicePort ];
|
||||
|
||||
|
|
@ -10048,13 +10073,25 @@ in
|
|||
];
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d ${serviceDir}/data 0750 1001 root - -"
|
||||
"d ${serviceDir}/data/cache 0750 1001 root - -"
|
||||
"d ${serviceDir}/data/locks 0750 1001 root - -"
|
||||
"d ${serviceDir}/data/log 0750 1001 root - -"
|
||||
"d ${serviceDir}/data/proxies 0750 1001 root - -"
|
||||
];
|
||||
systemd.tmpfiles.settings."11-shlink" = builtins.listToAttrs (
|
||||
map
|
||||
(path: {
|
||||
name = "${serviceDir}/${path}";
|
||||
value = {
|
||||
d = {
|
||||
group = "root";
|
||||
user = "1001";
|
||||
mode = "0750";
|
||||
};
|
||||
};
|
||||
}) [
|
||||
"${serviceDir}/data"
|
||||
"${serviceDir}/data/cache"
|
||||
"${serviceDir}/data/locks"
|
||||
"${serviceDir}/data/log"
|
||||
"${serviceDir}/data/proxies"
|
||||
]
|
||||
);
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ servicePort ];
|
||||
|
||||
|
|
@ -10137,10 +10174,22 @@ Deployment notes:
|
|||
];
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d ${serviceDir}/var/data 0750 root root - -"
|
||||
"d ${serviceDir}/images 0750 root root - -"
|
||||
];
|
||||
systemd.tmpfiles.settings."12-slink" = builtins.listToAttrs (
|
||||
map
|
||||
(path: {
|
||||
name = "${serviceDir}/${path}";
|
||||
value = {
|
||||
d = {
|
||||
group = "root";
|
||||
user = "root";
|
||||
mode = "0750";
|
||||
};
|
||||
};
|
||||
}) [
|
||||
"${serviceDir}/var/data"
|
||||
"${serviceDir}/images"
|
||||
]
|
||||
);
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ servicePort ];
|
||||
|
||||
|
|
@ -10326,6 +10375,48 @@ Deployment notes:
|
|||
|
||||
}
|
||||
#+end_src
|
||||
**** OPKSSH
|
||||
|
||||
#+begin_src nix-ts :tangle modules/nixos/server/opkssh.nix
|
||||
{ lib, config, globals, ... }:
|
||||
let
|
||||
serviceName = "opkssh";
|
||||
serviceUser = "opksshuser";
|
||||
serviceGroup = serviceUser;
|
||||
|
||||
kanidmDomain = globals.services.kanidm.domain;
|
||||
|
||||
inherit (config.swarselsystems) mainUser;
|
||||
inherit (config.repo.secrets.local) persons;
|
||||
in
|
||||
{
|
||||
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
|
||||
config = lib.mkIf config.swarselmodules.server.${serviceName} {
|
||||
|
||||
services.${serviceName} = {
|
||||
enable = true;
|
||||
user = serviceUser;
|
||||
group = serviceGroup;
|
||||
providers = {
|
||||
kanidm = {
|
||||
lifetime = "oidc";
|
||||
issuer = "https://${kanidmDomain}/oauth2/openid/${serviceName}";
|
||||
clientId = serviceName;
|
||||
};
|
||||
};
|
||||
authorizations = [
|
||||
{
|
||||
user = mainUser;
|
||||
principal = builtins.head persons.${mainUser}.mailAddresses;
|
||||
inherit (config.services.opkssh.providers.kanidm) issuer;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#+end_src
|
||||
*** Darwin
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: h:ac0cd8b3-06cf-4dca-ba73-6100c8fedb47
|
||||
|
|
@ -11286,6 +11377,9 @@ This holds packages that I can use as provided, or with small modifications (as
|
|||
simple-scan
|
||||
cura-appimage
|
||||
|
||||
# ssh login using idm
|
||||
opkssh
|
||||
|
||||
# dict
|
||||
(aspellWithDicts (dicts: with dicts; [ de en en-computers en-science ]))
|
||||
|
||||
|
|
@ -14651,9 +14745,15 @@ When setting up a new machine:
|
|||
};
|
||||
|
||||
# assure correct permissions
|
||||
systemd.user.tmpfiles.rules = [
|
||||
"d ${homeDir}/.gnupg 700 ${mainUser} users"
|
||||
];
|
||||
systemd.user.tmpfiles.settings."30-gpgagent".rules = {
|
||||
"${homeDir}/.gnupg" = {
|
||||
d = {
|
||||
group = "users";
|
||||
user = mainUser;
|
||||
mode = "0700";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -15239,6 +15339,41 @@ This service changes the screen hue at night. I am not sure if that really does
|
|||
}
|
||||
#+end_src
|
||||
|
||||
**** opkssh
|
||||
|
||||
#+begin_src nix-ts :tangle modules/home/common/opkssh.nix
|
||||
{ lib, config, ... }:
|
||||
let
|
||||
moduleName = "opkssh";
|
||||
in
|
||||
{
|
||||
options.swarselmodules.${moduleName} = lib.mkEnableOption "enable ${moduleName} and settings";
|
||||
config = lib.mkIf config.swarselmodules.${moduleName} {
|
||||
programs.${moduleName} = {
|
||||
enable = true;
|
||||
settings = {
|
||||
default_provider = "kanidm";
|
||||
|
||||
providers = [
|
||||
{
|
||||
alias = "kanidm";
|
||||
issuer = "https://sso.swarsel.win/oauth2/openid/opkssh";
|
||||
client_id = "opkssh";
|
||||
scopes = "openid email profile";
|
||||
redirect_uris = [
|
||||
"http://localhost:3000/login-callback"
|
||||
"http://localhost:10001/login-callback"
|
||||
"http://localhost:11110/login-callback"
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
#+end_src
|
||||
|
||||
*** Server
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: h:b1a00339-6e9b-4ae4-b5dc-6fd5669a2ddb
|
||||
|
|
@ -18826,6 +18961,7 @@ This holds modules that are to be used on most hosts. These are also the most im
|
|||
obs-studio = lib.mkDefault true;
|
||||
obsidian = lib.mkDefault true;
|
||||
obsidian-tray = lib.mkDefault true;
|
||||
opkssh = lib.mkDefault true;
|
||||
ownpackages = lib.mkDefault true;
|
||||
packages = lib.mkDefault true;
|
||||
passwordstore = lib.mkDefault true;
|
||||
|
|
|
|||
11
flake.lock
generated
11
flake.lock
generated
|
|
@ -4666,15 +4666,16 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1762025346,
|
||||
"narHash": "sha256-6KR4dsNfA3Pqm6uT8j7aKjWydP/KXFqZUhOfMlfP+1E=",
|
||||
"owner": "nix-community",
|
||||
"lastModified": 1762257324,
|
||||
"narHash": "sha256-05SxDx82j23zd1/EMDFZTPYFgvzxviBiByUBVs+860w=",
|
||||
"owner": "Swarsel",
|
||||
"repo": "home-manager",
|
||||
"rev": "87044c57222fb485974062e2dd557e7b8abd8fff",
|
||||
"rev": "d27fabec395885790e7ab666c72522e18e534117",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"owner": "Swarsel",
|
||||
"ref": "main",
|
||||
"repo": "home-manager",
|
||||
"type": "github"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@
|
|||
swarsel-modules.url = "github:Swarsel/swarsel-modules/main";
|
||||
swarsel-nix.url = "github:Swarsel/swarsel-nix/main";
|
||||
home-manager = {
|
||||
url = "github:nix-community/home-manager";
|
||||
# url = "github:Swarsel/home-manager/main";
|
||||
# url = "github:nix-community/home-manager";
|
||||
url = "github:Swarsel/home-manager/main";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
swarsel.url = "github:Swarsel/.dotfiles";
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@
|
|||
ankisync = lib.mkDefault true;
|
||||
# snipeit = lib.mkDefault false;
|
||||
homebox = lib.mkDefault true;
|
||||
opkssh = lib.mkDefault true;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"data": "ENC[AES256_GCM,data:lDbxvTQBbWAyHGx1a0TPXA6nIJ4crJICZaG/VYdeRl09NbJeF1dO2/UEquQxulE0IR+VkzIbfRiLPJ74kRcEsuFEBQ9LrF+gMEgwocQGCPGRTaWTfl84HfcX4qo+elOB5/W5lx1moOdYKFNFkxKbAj6wN0A8n0YBFqPDW/zeMO0DU6+MLW1XEb8zjG0hERocHb8svHVv2Xhu6sP2AX844vtN9u2xKil/kAR8XLPyuVCutsO+8GNfGkZh4hYdn5H+TYmWcWzzLujBt2H8+7UfdYsU4Q2PYcJ/Uokol8PAqMmPQDt9fF2S/IBbWZBmJY+ZmcxGHgYGY1+FeXZviIR37i8t9DS6isasDmGexDn4WyBq45XI/xo96qy0+GNHbeUoirAWWa+2YhLeqekG8q1luTbMh1uLw1n+ZmT3SexA20ens2sYmwjWdhyCR0cY3lcLhP/NVXgnbmOP61RUl7/RCPq0F3PCZ29LJG7oeDjD3JbJypRhTKnRMF+heEPrvmacWrkCMpEAkR8eB2WQmDxUTFyFTk/tv55GtHDuw5uA77pSmPIqVPppH2CupzDf+nBKyVIqON1jbpyxjlE8bBHtrEWEd0SioiTuC/CcoytzB8IiiEDgNjgoqNHfHYRyxGq0EKFtVcdqvkm3mbD0XyGG0UR3Arl8QSdHhIBSqedN7Y6rZJxef6VfLuxE13FWrZnSVGopAjMb/RTZbXLxjDNeHg6HwdBlrXMT7rps7jxbg39v5sOhGYhphF/L7KdCKVfmi8ubAfDVFZ3XRSuBzcHCW8FkxBWG+7Gnl3mMoNVw8loQwUjT+PbL1VHNQCr2fqS4wrv6ehQZIqOsqqlUF9JH9A3TgmHb4ioQ+jAEyOymTmrMzeaUBzcB9w54epkU+okDTO1LOvwC6gvEOQMoHv6fI2YCsQRCH3Mk3rhNBaotD3lQfuz1Pc3XL8t/9KGrCVwHLAoA+lt9g6o1KZoiBfcp3pFCWsPX3lrmUsJnKZHIVO+S9jOz+aJdOgaX/h5+cHp607bL8Zb296N4yK9yt5U+3mYONKn/hzGAmSghjfb/GTlMRJa5f6J9SerUvKqrjUVXJ2CmMAYojBt30Z1QRXIADRLLeyJglMZy9TwtoNsVr7iD2+rylU5TLJmPpxDbnQFriN0X4yhp1wYYBgjVkXV4SNGElDxjm0HFsBJkBaOpXeijCrcOJ5vmnuGLIhBTw+3qG4dEx/foUYRV1oJFrwH1U/f4oL9cOfdC0B9fv9yXJ/GORywOIlVb4FNLewSbu+PIAiZJLVQcBeBWNKQfoIb892ao2RXXJN6XZxp7IfEIBRBM/sfcfgtDk5ud+nuYPWYf09533t/ZjgbZ1en24MAwsit060IPROVwW3pIh2TSx/j1iMWbJ9ljaabBhivmGVo8CLVErGeSLwLL8eXLQ02D9i+LgY1oQavx3675Z7RDwQbdQxjLCKB5Fq77nPGuf2mzTLE/6NL7l6INCcuyg+Vp2zaxX87NMgh+0q9ZFW/ECL/+QzNeBaUmFJ2tXwMiVJAcm2vGiUvI,iv:emlV4hFKBALvzUiaDtu3CDX0Y8fd8TTQmPaR9WyqN4I=,tag:aFPEYachc1H0F+/q3FbuGA==,type:str]",
|
||||
"data": "ENC[AES256_GCM,data:i8kqmycc80NLcOirK7D20hxsWWFGNMx5d1SDueaSTmymvTb0rNMFiRoLf44c9Bc5yBySg9zRNCJ8lyc1SZH5YAqIYGN8y4nzOTxyPxT1R+Igtzm49sBdp1dK6MVCW1/xIsjDE/niV19l9LTptN7neCIEuDjB22bSMRhfVOxOiSwd2FKBeH61XACFLAz3AuVC4a+FhqsBkmLOAg7SIG0xdsyi2tjuTOCiMci9eQk8q9XkmLQC3z6vBaIBxPErkIG/fyhNBYt0Hv+37b/TFVbBL9qnGK369Ln9EUm0IarInaq9haxE18DkI5bzlJH5hw4JNjMGFz8av6rOJT5oW52yPor1RBodwUtP6YDQCQsdINIbjmAM9C0HGBY31nyy07fVT+QDcNydjT1fEXLSJTseO5E/MrRCVBioorBpG+5kBBQhRMihGeT8htVGVQpiJC7peARRfSQTUqjNH/esWTPCk0xPOXgApgPIbXBIJFj4RiH2erzN1PKPpuGZfuqbEr63VXCp6t0jttZKDEEjob1ZJMKfiqRubaz+ycg/sxFb1p+l9O21ihW8jM9huiBpVTc+mHU0ENTSstC4uB5LG6HMqV9vmqrKP4OM13vifggpQ6K9VRXebpI/t4tdRETcwWIMo/LRCmhGO4o0+1tNG+ayVDVmY/ORJu/Nrl61TtmUXxGc74Vd1sea+60LuqDHdIEs06thxFLSCVXaxa70gTlQIlVSEJBz9yaAMm7Iw4CSvLbYTXrRg6P/jIZx7rGSyC7I/kFMAPsa2KYxUUkBNd8zSoHyf8paxbgocb3yNcMtHIyNYiOXaLgr56DasJKsXTdjnuic6PLBCd9+U9o9R4wdBw4CGHZ3+3P+LexImkK9InVTm3QD9gyWtgDe66jrQMJxicixtx6hKvP0P0nmjhE6UjhfMMYV2Qu7vx1APhE62KF9y+axIlKju4kYkRhC9BHi2FuZUCFkPiPd/RRWzBTuChnKud9TWTixBtzpBI39/5e3i8f55hcG0XkUT+rMolq/hCObIczq7M2TVrZK4vUGByHXi1Vljk+K2tUZLVGq+Vpa7JUfmyp/qdUBG5FFXBBLUmAA0yjR+XxTtuZ4+M7JdgoYlzXEN8AbyBTEfVps4HJVPfwWMZaXEWqc7fwSVNlkRpIGSkbF8+tzBd0M66FtjbC9hs1P/SwwUr/ZTwJW0D8EXDUOJo2VCGpGtzHZpg5wd7qPTKL20fLVrpdfKIMeBrPtpCkv2YAzSXClAMQqMJ1DtrFr9WNeTAv0ROwkfnGIYwFpDnK3Xy3Z9V1HlZY3K/UYybzb43Dvtl0qWcSmXxKWLK0rqe3r4sWKA/gpOi8UIyCssAv5At0JO2e0yBJv7tXi+WGNZIBEy559EYdnfHty2KZTR5M/PiP5t1PMbuzUkee3voybnAioCZfGsh5Ln04ZihUHbtbxocM4yieaqBd7nryO81b1ZARoZKbASaGMc7y65pgsA1MiNnbtGIZUwlNyg1q3iZxdtkG6qgG2vCY9Z6JNXXl6RoBmbDbCaIzvid8OXvK8z0z4t0BpYQCFVb3/sEAqweUnQffstEFB,iv:+cS1MmSlZWLdRt5Ey31y6WrDAudgjHxsUbfCBUK0/Sg=,tag:byOqNWWPQmlrDWQO1tRRJQ==,type:str]",
|
||||
"sops": {
|
||||
"age": [
|
||||
{
|
||||
|
|
@ -11,8 +11,8 @@
|
|||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNeGtTZ0ZSV0trWlQrS2dV\nSFo0dytGYXhRTjl6cDZrUU0wZ1IybDVRaFZrCmZmRmxJNmdwS0xodHdEOGU4bldU\nR1JScHAvZHhlVTBJbWExb0VpR0h2MXMKLS0tIDYwQmZpMjdYRmpBeXFNOXArN0h5\nVGN1THljeCtVV0hXenMyRVJkMjlHNEEKm+yZTT48nYr3H0Bd1OKw/CYk1kwnrBzk\nTgSQHsGXhmOyDag9cSZ4wAOmqtqSjA9bouFBuhl2lSbgpjnarvFaXQ==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||
}
|
||||
],
|
||||
"lastmodified": "2025-09-16T11:26:37Z",
|
||||
"mac": "ENC[AES256_GCM,data:T87Y33N0Tu8IySeUgrV7lgMzG+8Cl0ezJkjZFHzmeXy7+TJ2JKrnTfy0nY2oXjVCRLC2CBRh6e9n6ITnAnQJxyS3ZDF/FaY1h5LSm4e6bklFxBZRTQhssVJHbRE4dm8VZL+NLli32VM5YG+E8Kn640YE0oUgBlxqS4qmH4/fLl4=,iv:37xHtgBX6nmgGUGhwSpLIItN8OMto5yLL+Xr+KA4h9E=,tag:Y4FU6/HYmu1IgLG4ChutZw==,type:str]",
|
||||
"lastmodified": "2025-11-04T09:26:35Z",
|
||||
"mac": "ENC[AES256_GCM,data:T8GqsMxfFB9s1EOeLHNzxoz23FCOnlNsBsbvMxiLq7a78xt5Xw3dVN/IWfkyiCDwfSjo+fVx2yEd5tP/B3fSN7S8WJNSe5ZywLpal/RlsCzv7ARvbVCaBx22S4az97JsR1qQUcGSvoiTH5e/0t2tBtimGJ1witbvbiGkTBp8taw=,iv:Qs26cjeMLtRhTDO91yfBo93wUKJ9zVfUbJ8o6myHGUo=,tag:FbT8emz6q1QnXdxoX6hsYQ==,type:str]",
|
||||
"pgp": [
|
||||
{
|
||||
"created_at": "2025-08-24T23:36:17Z",
|
||||
|
|
@ -21,6 +21,6 @@
|
|||
}
|
||||
],
|
||||
"unencrypted_suffix": "_unencrypted",
|
||||
"version": "3.10.2"
|
||||
"version": "3.11.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,9 +37,15 @@ in
|
|||
};
|
||||
|
||||
# assure correct permissions
|
||||
systemd.user.tmpfiles.rules = [
|
||||
"d ${homeDir}/.gnupg 700 ${mainUser} users"
|
||||
];
|
||||
systemd.user.tmpfiles.settings."30-gpgagent".rules = {
|
||||
"${homeDir}/.gnupg" = {
|
||||
d = {
|
||||
group = "users";
|
||||
user = mainUser;
|
||||
mode = "0700";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
30
modules/home/common/opkssh.nix
Normal file
30
modules/home/common/opkssh.nix
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
{ lib, config, ... }:
|
||||
let
|
||||
moduleName = "opkssh";
|
||||
in
|
||||
{
|
||||
options.swarselmodules.${moduleName} = lib.mkEnableOption "enable ${moduleName} and settings";
|
||||
config = lib.mkIf config.swarselmodules.${moduleName} {
|
||||
programs.${moduleName} = {
|
||||
enable = true;
|
||||
settings = {
|
||||
default_provider = "kanidm";
|
||||
|
||||
providers = [
|
||||
{
|
||||
alias = "kanidm";
|
||||
issuer = "https://sso.swarsel.win/oauth2/openid/opkssh";
|
||||
client_id = "opkssh";
|
||||
scopes = "openid email profile";
|
||||
redirect_uris = [
|
||||
"http://localhost:3000/login-callback"
|
||||
"http://localhost:10001/login-callback"
|
||||
"http://localhost:11110/login-callback"
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -22,6 +22,9 @@
|
|||
simple-scan
|
||||
cura-appimage
|
||||
|
||||
# ssh login using idm
|
||||
opkssh
|
||||
|
||||
# dict
|
||||
(aspellWithDicts (dicts: with dicts; [ de en en-computers en-science ]))
|
||||
|
||||
|
|
|
|||
|
|
@ -135,6 +135,7 @@ in
|
|||
"firefly.access" = { };
|
||||
"radicale.access" = { };
|
||||
"slink.access" = { };
|
||||
"opkssh.access" = { };
|
||||
};
|
||||
|
||||
inherit (config.repo.secrets.local) persons;
|
||||
|
|
@ -229,6 +230,23 @@ in
|
|||
};
|
||||
};
|
||||
};
|
||||
opkssh = {
|
||||
displayName = "OPKSSH";
|
||||
originUrl = [
|
||||
"http://localhost:3000"
|
||||
"http://localhost:3000/login-callback"
|
||||
"http://localhost:10001/login-callback"
|
||||
"http://localhost:11110/login-callback"
|
||||
];
|
||||
originLanding = "http://localhost:3000";
|
||||
public = true;
|
||||
enableLocalhostRedirects = true;
|
||||
scopeMaps."opkssh.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
};
|
||||
oauth2-proxy = {
|
||||
displayName = "Oauth2-Proxy";
|
||||
originUrl = "https://${oauth2ProxyDomain}/oauth2/callback";
|
||||
|
|
|
|||
38
modules/nixos/server/opkssh.nix
Normal file
38
modules/nixos/server/opkssh.nix
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
{ lib, config, globals, ... }:
|
||||
let
|
||||
serviceName = "opkssh";
|
||||
serviceUser = "opksshuser";
|
||||
serviceGroup = serviceUser;
|
||||
|
||||
kanidmDomain = globals.services.kanidm.domain;
|
||||
|
||||
inherit (config.swarselsystems) mainUser;
|
||||
inherit (config.repo.secrets.local) persons;
|
||||
in
|
||||
{
|
||||
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
|
||||
config = lib.mkIf config.swarselmodules.server.${serviceName} {
|
||||
|
||||
services.${serviceName} = {
|
||||
enable = true;
|
||||
user = serviceUser;
|
||||
group = serviceGroup;
|
||||
providers = {
|
||||
kanidm = {
|
||||
lifetime = "oidc";
|
||||
issuer = "https://${kanidmDomain}/oauth2/openid/${serviceName}";
|
||||
clientId = serviceName;
|
||||
};
|
||||
};
|
||||
authorizations = [
|
||||
{
|
||||
user = mainUser;
|
||||
principal = builtins.head persons.${mainUser}.mailAddresses;
|
||||
inherit (config.services.opkssh.providers.kanidm) issuer;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -76,9 +76,15 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d ${cfg.settings.storage.filesystem_folder} 0750 ${serviceUser} ${serviceGroup} - -"
|
||||
];
|
||||
systemd.tmpfiles.settings."10-radicale" = {
|
||||
"${cfg.settings.storage.filesystem_folder}" = {
|
||||
d = {
|
||||
group = serviceGroup;
|
||||
user = serviceUser;
|
||||
mode = "0750";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ servicePort ];
|
||||
|
||||
|
|
|
|||
|
|
@ -48,13 +48,25 @@ in
|
|||
];
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d ${serviceDir}/data 0750 1001 root - -"
|
||||
"d ${serviceDir}/data/cache 0750 1001 root - -"
|
||||
"d ${serviceDir}/data/locks 0750 1001 root - -"
|
||||
"d ${serviceDir}/data/log 0750 1001 root - -"
|
||||
"d ${serviceDir}/data/proxies 0750 1001 root - -"
|
||||
];
|
||||
systemd.tmpfiles.settings."11-shlink" = builtins.listToAttrs (
|
||||
map
|
||||
(path: {
|
||||
name = "${serviceDir}/${path}";
|
||||
value = {
|
||||
d = {
|
||||
group = "root";
|
||||
user = "1001";
|
||||
mode = "0750";
|
||||
};
|
||||
};
|
||||
}) [
|
||||
"${serviceDir}/data"
|
||||
"${serviceDir}/data/cache"
|
||||
"${serviceDir}/data/locks"
|
||||
"${serviceDir}/data/log"
|
||||
"${serviceDir}/data/proxies"
|
||||
]
|
||||
);
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ servicePort ];
|
||||
|
||||
|
|
|
|||
|
|
@ -29,10 +29,22 @@ in
|
|||
];
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d ${serviceDir}/var/data 0750 root root - -"
|
||||
"d ${serviceDir}/images 0750 root root - -"
|
||||
];
|
||||
systemd.tmpfiles.settings."12-slink" = builtins.listToAttrs (
|
||||
map
|
||||
(path: {
|
||||
name = "${serviceDir}/${path}";
|
||||
value = {
|
||||
d = {
|
||||
group = "root";
|
||||
user = "root";
|
||||
mode = "0750";
|
||||
};
|
||||
};
|
||||
}) [
|
||||
"${serviceDir}/var/data"
|
||||
"${serviceDir}/images"
|
||||
]
|
||||
);
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ servicePort ];
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
obs-studio = lib.mkDefault true;
|
||||
obsidian = lib.mkDefault true;
|
||||
obsidian-tray = lib.mkDefault true;
|
||||
opkssh = lib.mkDefault true;
|
||||
ownpackages = lib.mkDefault true;
|
||||
packages = lib.mkDefault true;
|
||||
passwordstore = lib.mkDefault true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue