Further nixos module fixes Add tailwind and esbuild to assets build Handle domain on session cookies correctly
134 lines
4.6 KiB
Nix
134 lines
4.6 KiB
Nix
{
|
|
description = "A simple OIDC SSO service";
|
|
|
|
outputs = {
|
|
self,
|
|
nixpkgs,
|
|
systems,
|
|
}: let
|
|
inherit (nixpkgs) lib;
|
|
eachSystem = f:
|
|
lib.genAttrs (import systems) (system:
|
|
f {
|
|
inherit system;
|
|
pkgs = nixpkgs.legacyPackages.${system};
|
|
ownPkgs = self.packages.${system};
|
|
});
|
|
in {
|
|
devShells = eachSystem ({pkgs, ...}: {
|
|
default = pkgs.beam.packages.erlang_26.callPackage ./shell.nix {};
|
|
});
|
|
packages = eachSystem ({pkgs, ...}: {
|
|
default = pkgs.beam.packages.erlang_26.callPackage ./default.nix {
|
|
inherit self;
|
|
};
|
|
});
|
|
|
|
nixosModules = {
|
|
default = { lib, pkgs, config, ... }: let
|
|
sso-bsn = self.packages.${pkgs.system}.default;
|
|
gen-secret = pkgs.writeShellScript "gen-secret" ''
|
|
(umask 077; [ -f $1/$2 ] || ${pkgs.coreutils}/bin/head -c 128 /dev/urandom | ${pkgs.coreutils}/bin/base64 -w0 > $1/$2)
|
|
'';
|
|
secret = var: dir: file: ''
|
|
${gen-secret} "${dir}" "${file}"
|
|
${var}=$(${pkgs.coreutils}/bin/cat "${dir}/${file}")
|
|
'';
|
|
script = pkgs.writeShellScriptBin "sso-bsn" ''
|
|
${secret "RELEASE_COOKIE" "/run/sso-bsn" "cookie"}
|
|
RELEASE_COOKIE="$RELEASE_COOKIE" ${lib.getExe sso-bsn} "$@"
|
|
'';
|
|
cfg = config.services.bluepython508.sso-bsn;
|
|
in {
|
|
options.services.bluepython508.sso-bsn = {
|
|
enable = lib.mkEnableOption "sso-bsn";
|
|
host = lib.mkOption { type = lib.types.str; };
|
|
session-domain = lib.mkOption { type = with lib.types; nullOr str; };
|
|
};
|
|
options.services.nginx.virtualHosts = lib.mkOption {
|
|
type = lib.types.attrsOf (lib.types.submodule ({ config, ...}: {
|
|
options.locations = lib.mkOption {
|
|
type = lib.types.attrsOf (lib.types.submodule {
|
|
extraConfig = lib.mkIf config.sso.enable ''
|
|
proxy_set_header X-Auth-Username $auth_resp_username
|
|
'';
|
|
});
|
|
};
|
|
options.sso.enable = lib.mkEnableOption "SSO BSN";
|
|
config.extraConfig = lib.mkIf config.sso.enable ''
|
|
auth_request /__auth_sso_validate;
|
|
|
|
location = /__auth_sso_validate {
|
|
internal;
|
|
proxy_pass https://${cfg.host}/whoami;
|
|
proxy_pass_request_body off; # no need to send the POST body
|
|
|
|
proxy_set_header Content-Length "";
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
|
|
auth_request_set $auth_resp_username $upstream_http_x_auth_username;
|
|
}
|
|
|
|
error_page 401 = @error401;
|
|
|
|
location @error401 {
|
|
return 302 https://${cfg.host}/users/log_in?next=$scheme://$http_host$request_uri;
|
|
}
|
|
'';
|
|
}));
|
|
};
|
|
config.environment.systemPackages = lib.mkIf cfg.enable [ script ];
|
|
config.users = lib.mkIf cfg.enable {
|
|
groups.sso-bsn = {};
|
|
users.nginx.extraGroups = ["sso-bsn"];
|
|
users.sso-bsn = {
|
|
group = "sso-bsn";
|
|
isSystemUser = true;
|
|
};
|
|
};
|
|
config.systemd.services.sso-bsn = lib.mkIf cfg.enable {
|
|
description = "sso-bsn";
|
|
environment = {
|
|
SERVER = "true";
|
|
DATABASE_PATH = "/var/lib/sso-bsn/db.sqlite";
|
|
BIND_UNIX = "/run/sso-bsn/sock";
|
|
SSO_BSN_HOST = cfg.host;
|
|
SESSION_DOMAIN = cfg.session-domain;
|
|
};
|
|
script = ''
|
|
${secret "SECRET_KEY_BASE" "/var/lib/sso-bsn" "secret-key-base"}
|
|
SECRET_KEY_BASE="$SECRET_KEY_BASE" ${lib.getExe script} start
|
|
'';
|
|
wantedBy = [ "multi-user.target" ];
|
|
serviceConfig = {
|
|
ProtectHome = true;
|
|
PrivateUsers = true;
|
|
StateDirectory = "sso-bsn";
|
|
RuntimeDirectory = "sso-bsn";
|
|
UMask = "007";
|
|
User = "sso-bsn";
|
|
Group = "sso-bsn";
|
|
PrivateTmp = true;
|
|
RemoveIPC = true;
|
|
NoNewPrivileges = true;
|
|
RestrictSUIDSGID = true;
|
|
};
|
|
};
|
|
config.services.nginx.virtualHosts = lib.mkIf cfg.enable {
|
|
${cfg.host} = {
|
|
forceSSL = true;
|
|
enableACME = true;
|
|
locations."/" = {
|
|
proxyPass = "http://unix:/run/sso-bsn/sock:/";
|
|
recommendedProxySettings = true;
|
|
proxyWebsockets = true;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
}
|