Files
sso-bsn/flake.nix
bluepython508 cf60f1140c Nixos module
2023-11-10 00:26:07 +00:00

113 lines
3.9 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" ''
mkdir -p $1
(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"} ${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.sso.enable = lib.mkEnableOption "SSO BSN";
config.extraConfig = lib.mkIf config.sso.enable ''
auth_request /__auth_sso_validate;
proxy_set_header X-Auth-Username $auth_resp_username;
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 url=https://${cfg.host}/user/log_in?next=$http_host$request_uri;
}
'';
}));
};
config.environment.systemPackages = lib.mkIf cfg.enable [ script ];
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 = {
DynamicUser = true;
ProtectHome = true;
PrivateUsers = true;
StateDirectory = "sso-bsn";
};
};
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;
};
};
};
};
};
};
}