diff --git a/sys/machines/hopper/lab/default.nix b/sys/machines/hopper/lab/default.nix index 5f8a9e1..0b60454 100644 --- a/sys/machines/hopper/lab/default.nix +++ b/sys/machines/hopper/lab/default.nix @@ -15,6 +15,7 @@ ncPort = 46523; adguardWebPort = 23489; kanidmPort = 8300; + oauth2ProxyPort = 23490; in { imports = [ ./samba.nix @@ -149,6 +150,31 @@ in { hostName = "dash.hopper.xun.host:80"; extraConfig = "reverse_proxy localhost:${toString config.services.homepage-dashboard.listenPort}"; }; + oauth2-proxy = { + hostName = "oauth2.${domain}:${toString caddyPort}"; + extraConfig = "reverse_proxy unix//run/oauth2-proxy/oauth2-proxy.sock"; + }; + # slskd-pub = { + # hostName = "slskd.${domain}:${toString caddyPort}"; + # extraConfig = '' + # handle /oauth2/* { + # reverse_proxy unix//run/oauth2-proxy/oauth2-proxy.sock + # } + # handle { + # forward_auth unix//run/oauth2-proxy/oauth2-proxy.sock { + # uri /oauth2/auth + # + # header_up X-Real-IP {remote_host} + # + # @bad status 4xx + # handle_response @bad { + # redir * /oauth2/start + # } + # } + # reverse_proxy localhost:${toString config.services.slskd.settings.web.port} + # } + # ''; + # }; # prometheus = { # useACMEHost = null; # hostName = "prometheus.hopper.xun.host:80"; @@ -347,6 +373,57 @@ in { # group = config.services.caddy.group; # }; + # systemd.services.oauth2-proxy.vpnConfinement = { + # enable = true; + # vpnNamespace = "wg"; + # }; + + systemd.services.oauth2-proxy = { + after = ["kanidm.service"]; + serviceConfig = { + RuntimeDirectory = "oauth2-proxy"; + UMask = "007"; + }; + }; + users.groups.oauth2-proxy.members = ["caddy"]; + + services.oauth2-proxy = let + clientID = "oauth2-proxy"; + in { + enable = true; + inherit clientID; + cookie.expire = "24h"; + email.domains = ["*"]; + httpAddress = "unix:///run/oauth2-proxy/oauth2-proxy.sock"; + + keyFile = config.sops.secrets.oauth2-proxy.path; + + reverseProxy = true; + approvalPrompt = "auto"; + setXauthrequest = true; + + provider = "oidc"; + + loginURL = "https://${config.services.kanidm.serverSettings.domain}/ui/oauth2"; + redeemURL = "https://${config.services.kanidm.serverSettings.domain}/oauth2/token"; + validateURL = "https://${config.services.kanidm.serverSettings.domain}/oauth2/openid/${clientID}/userinfo"; + oidcIssuerUrl = "https://${config.services.kanidm.serverSettings.domain}/oauth2/openid/${clientID}"; + + # redeemURL = "https://${config.services.kanidm.serverSettings.domain}/oauth2/token"; + # loginURL = "https://${config.services.kanidm.serverSettings.domain}/ui/oauth2"; + # validateURL = "https://${config.services.kanidm.serverSettings.domain}/oauth2/openid/oauth2-proxy"; + # oidcIssuerUrl = "https://kanidm.${domain}/oauth2/openid/oauth2-proxy"; + # profileURL = "https://kanidm.${domain}/oauth2/openid/oauth2-proxy/userinfo"; + + extraConfig = { + code-challenge-method = "S256"; # PKCE + # oidc-issuer-url = "https://${config.services.kanidm.serverSettings.domain}"; + # insecure-oidc-skip-issuer-verification = "true"; + # insecure-oidc-allow-unverified-email = "true"; + # scope = "openid profile email groups"; + }; + }; + systemd.services.kanidm = { vpnConfinement = { enable = true; @@ -378,7 +455,33 @@ in { displayName = "xun"; legalName = "xun"; mailAddresses = ["xunuwu@gmail.com"]; - groups = []; + groups = [ + "oauth2-proxy.access" + "oauth2-proxy.adguardhome" + "oauth2-proxy.analytics" + ]; + }; + }; + + groups."oauth2-proxy.access" = {}; + groups."oauth2-proxy.adguardhome" = {}; + # groups."oauth2-proxy.openwebui" = {}; + groups."oauth2-proxy.analytics" = {}; + systems.oauth2.oauth2-proxy = { + displayName = "Oauth2 Proxy"; + originUrl = "https://oauth2.${domain}/oauth2/callback"; + originLanding = "https://oauth2.${domain}/"; + # basicSecretFile = config.age.secrets..path; + preferShortUsername = true; + scopeMaps."oauth2-proxy.access" = [ + "openid" + "email" + ]; + claimMaps.groups = { + joinType = "array"; + valuesByGroup."oauth2-proxy.adguardhome" = ["access_adguardhome"]; + # valuesByGroup."oauth2-proxy.openwebui" = ["access_openwebui"]; + valuesByGroup."oauth2-proxy.analytics" = ["access_analytics"]; }; }; }; diff --git a/sys/profiles/secrets/hopper/default.nix b/sys/profiles/secrets/hopper/default.nix index 6a26f1f..6c51dfb 100644 --- a/sys/profiles/secrets/hopper/default.nix +++ b/sys/profiles/secrets/hopper/default.nix @@ -7,6 +7,10 @@ in { format = "binary"; sopsFile = ./wireguard; }; + oauth2-proxy = { + format = "binary"; + sopsFile = ./oauth2-proxy; + }; # grafana-pass = { # format = "binary"; # sopsFile = ./grafana-pass; diff --git a/sys/profiles/secrets/hopper/oauth2-proxy b/sys/profiles/secrets/hopper/oauth2-proxy new file mode 100644 index 0000000..534deb2 --- /dev/null +++ b/sys/profiles/secrets/hopper/oauth2-proxy @@ -0,0 +1,24 @@ +{ + "data": "ENC[AES256_GCM,data:jvzEDBxCG38o0tvGPHvMDvY9cnTkLdZlnhUWeEHDIPGKztfQ/HRPQoj9yBLGMEnuIYhWUCYJklyEDc3BcULRLskf/jEWs+6UoP/V+DnNNyMXf8NF00xrOA+QfGxDfK3k2Wdv9MV0ZAHuldzc6/DiWnmqPOtKXHIrcZUVlcmqw2LcN/mOFvop74y8j6yJ07UA,iv:toRLJ+bZPtL3gtTpSsHbk9hKbW9PKIb9H/lAMSaPF68=,tag:u+6PwiTkjFF/TKJIewdQ+A==,type:str]", + "sops": { + "kms": null, + "gcp_kms": null, + "azure_kv": null, + "hc_vault": null, + "age": [ + { + "recipient": "age17pdqkpfh6kc6wm7gxzdnwf6vphlwddv9yfpdu3j76e24y3amd9tq3avfc8", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGaEpxdTRMY3F2M2d2SjNB\nKzhyZjBFMTVZeHJiUi9JNTBBVDYwaHo2UUFjCjVqbTVQTG11b0RUUU8vWU96SXMw\nVmRBMGlBcHVzRGpZYWZLK1NHZXlvL1UKLS0tIHV4RU5BY0t4WXU1bE1JcThGWGpQ\nYWxkS3h4OTkxNFE2RERObi9XQ1d5SkUKZ7w17h14jYOIj0YaIo5aknhLIkhaMEEy\nLD7ND/Hi5+jJo0FtYYpZLIVJvAcOjQq/OTeaE6hrHelnsUKLJhk5PA==\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age15mgf89h220puhz48rjpwxwu4n2h4edur60w6cd8gku2hh4e5kqpsghvnyw", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwSEpIOWVjb0xDM003QkRB\nSGVyWlpyOFNjUmVhYkNQMHFzVmRQSzRpQjFvCjNZaUFxeGNDbWNMVytOaUJFYVZS\nRWE5OGIxNllUY0toajBaVjJmcFdpcmsKLS0tIE9wdjVOd1ZDaDIwNnZOK2gxZGxS\nckdNREtKNnNGV3p3aWJueENMYi9EWjQKwrZI1MOWWrGzmxkm31tQzD5apsih0Rdj\nvJAp4PXLVFHusaByR+fr/lErQ8Km22R5jLZvrtcTXBkDtKrBG5AQEw==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-01-20T10:11:17Z", + "mac": "ENC[AES256_GCM,data:QDXvlOqSBoP2XPyY1eUG51ygnc3aNf+M3BwXCekHLXE7uUSJETYb94gXETkh3ygPHfOGKv4d9mGpmreejkuJV8DaYjmE8/L200HLJBRskN8MUkfnYKHyNwh2kCHGux3Z/1moeXofU9pu2PyYnajESW8v5TNCIFBUSs/Ide5v2KQ=,iv:AumUp97UDADaAmLTfAId3jLtZi08ZQxnal77o/7pYME=,tag:I8YZOzrK4yTe4i6zNnrrYw==,type:str]", + "pgp": null, + "unencrypted_suffix": "_unencrypted", + "version": "3.9.2" + } +} \ No newline at end of file