nixos-config/modules/nixos/services/vouch-proxy.nix

178 lines
5.5 KiB
Nix
Raw Normal View History

2023-10-06 05:29:22 +00:00
{ config, lib, pkgs, utils, ... }:
let
cfg = config.services.vouch-proxy;
settingsFormat = pkgs.formats.yaml { };
instanceType = { name, config, options, ... }: {
options = {
package = lib.mkPackageOption pkgs "vouch-proxy" { };
2023-10-06 05:29:22 +00:00
settings = lib.mkOption {
description = ''
Configuration to be passed to Vouch Proxy.
2023-10-06 05:29:22 +00:00
::: {.note}
For settings with sensitive values like JWT token secret, you can
specify a `_secret` attribute with a path value. In the final version
of the generated settings, the key will have the value with the
content of the specified path.
:::
'';
type = settingsFormat.type;
default = { };
example = lib.literalExpression ''
{
vouch = {
listen = "127.0.0.1";
port = 30746;
domains = [ "gitea.example.com" ];
allowAllUsers = true;
jwt.secret._secret = "/path/to/jwt-secret";
session.key._secret = "/path/to/session-key-secret";
};
2023-10-06 05:29:22 +00:00
oauth = {
provider = "github";
client_id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
client_secret._secret = "/path/to/secret";
auth_url = "https://gitea.example.com/login/oauth/authorize";
token_url = "https://gitea.example.com/login/oauth/access_token";
user_info_url = "https://gitea.example.com/api/v1/user?token=";
callback_url = "https://example.com/auth";
};
}
'';
};
2023-10-06 05:29:22 +00:00
settingsFile = lib.mkOption {
type = with lib.types; nullOr path;
default = null;
defaultText = lib.literalExpression "settingsFile";
description = ''
The path of the configuration file. If `null`, it uses the
filepath from NixOS-generated settings.
'';
example = lib.literalExpression "/etc/vouch-proxy/config.yml";
};
2023-10-06 05:29:22 +00:00
};
};
mkVouchInstance = name: instance:
let
inherit (instance) settings settingsFile;
settingsFile' = "/var/lib/vouch-proxy/${name}-config.yml";
2023-10-06 05:29:22 +00:00
in
lib.nameValuePair "vouch-proxy-${name}" {
2023-10-09 12:48:01 +00:00
preStart =
if (settings != { } && settingsFile == null)
2023-10-06 05:29:22 +00:00
then ''
${pkgs.writeScript
"vouch-proxy-replace-secrets"
(utils.genJqSecretsReplacementSnippet settings settingsFile')}
2023-10-06 05:29:22 +00:00
''
else ''
install -Dm0600 "${settingsFile}" "${settingsFile'}"
2023-10-06 05:29:22 +00:00
'';
script = "${lib.getExe' instance.package "vouch-proxy"} -config ${settingsFile'}";
2023-10-06 05:29:22 +00:00
serviceConfig = {
User = config.users.users.vouch-proxy.name;
Group = config.users.groups.vouch-proxy.name;
2023-10-06 05:29:22 +00:00
Restart = "on-failure";
RestartSec = 5;
PrivateTmp = true;
PrivateDevices = true;
2023-10-06 05:29:22 +00:00
LockPersonality = true;
MemoryDenyWriteExecute = true;
2023-10-06 05:29:22 +00:00
NoNewPrivileges = true;
RestrictSUIDSGID = true;
RestrictRealtime = true;
ProtectClock = true;
ProtectKernelLogs = true;
ProtectKernelTunables = true;
ProtectKernelModules = true;
ProtectHostname = true;
ProtectControlGroups = true;
ProtectProc = "invisible";
ProcSubset = "pid";
SystemCallFilter = [
"@system-service"
"~@cpu-emulation"
"~@keyring"
"~@module"
"~@privileged"
"~@reboot"
];
2023-10-06 05:29:22 +00:00
SystemCallErrorNumber = "EPERM";
SystemCallArchitectures = "native";
RuntimeDirectory = "vouch-proxy";
StateDirectory = "vouch-proxy";
# Restricting what capabilities this service has.
CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ];
AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
# Limit this service to Unix sockets and IPs.
RestrictAddressFamilies = [
"AF_LOCAL"
"AF_INET"
"AF_INET6"
];
RestrictNamespaces = true;
};
};
in
{
options.services.vouch-proxy = {
enable = lib.mkEnableOption "Vouch Proxy, a proxy for SSO and OAuth/OIDC logins";
instances = lib.mkOption {
type = with lib.types; attrsOf (submodule instanceType);
description = lib.mdDoc "Instances of Vouch proxy to be run.";
default = { };
example = lib.literalExpression ''
{
"vouch.example.com".settings = {
vouch = {
listen = "127.0.0.1";
port = 19900;
domains = [ "example.com" ];
jwt.secret._secret = "/var/lib/secrets/vouch-proxy-jwt-secret";
};
oauth = rec {
provider = "oidc";
client_id = "vouch";
client_secret._secret = "/var/lib/secrets/vouch-proxy-client-secret";
code_challenge_method = "S256";
auth_url = "https://auth.example.com/ui/oauth2";
token_url = "https://auth.example.com/oauth2/token";
user_info_url = "https://auth.example.com/oauth2/openid/$${client_id}/userinfo";
scopes = [ "login" "email" ];
callback_url = "https://auth.example.com/auth";
};
};
}
'';
};
};
config = lib.mkIf cfg.enable {
systemd.services = lib.mapAttrs' mkVouchInstance cfg.instances;
users.users.vouch-proxy = {
description = "Vouch Proxy user";
group = config.users.groups.vouch-proxy.name;
isSystemUser = true;
};
users.groups.vouch-proxy = { };
2023-10-06 05:29:22 +00:00
};
}