diff --git a/README.md b/README.md index 202b5b7..8c4c119 100644 --- a/README.md +++ b/README.md @@ -136,32 +136,39 @@ openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \ ```bash # Recover admin account (server must not be running) -> systemctl stop kanidm -> kanidmd recover-account -c server.toml admin -AhNeQgKkwwEHZ85dxj1GPjx58vWsBU8QsvKSyYwUL7bz57bp -> systemctl start kanidm +systemctl stop kanidm +kanidmd recover-account -c server.toml admin +> AhNeQgKkwwEHZ85dxj1GPjx58vWsBU8QsvKSyYwUL7bz57bp +systemctl start kanidm # Login with recovered root account -> kanidm login --name admin +kanidm login --name admin # Generate new credentials for idm_admin account -> kanidm service-account credential generate -D admin idm_admin -Yk0W24SQGzkLp97DNxxExCcryDLvA7Q2dR0A7ZuaVQevLR6B +kanidm service-account credential generate -D admin idm_admin +> Yk0W24SQGzkLp97DNxxExCcryDLvA7Q2dR0A7ZuaVQevLR6B # Generate new oauth2 app for grafana -> kanidm group create grafana-access -> kanidm group create grafana-server-admins -> kanidm group create grafana-admins -> kanidm group create grafana-editors -> kanidm system oauth2 create grafana "Grafana" https://grafana.${personalDomain} -> kanidm system oauth2 update-scope-map grafana grafana-access openid profile email -> kanidm system oauth2 update-sup-scope-map grafana grafana-server-admins server_admin -> kanidm system oauth2 update-sup-scope-map grafana grafana-admins admin -> kanidm system oauth2 update-sup-scope-map grafana grafana-editors editor -> kanidm system oauth2 show-basic-secret grafana +kanidm group create grafana-access +kanidm group create grafana-server-admins +kanidm group create grafana-admins +kanidm group create grafana-editors +kanidm system oauth2 create grafana "Grafana" https://grafana.${personalDomain} +kanidm system oauth2 update-scope-map grafana grafana-access openid profile email +kanidm system oauth2 update-sup-scope-map grafana grafana-server-admins server_admin +kanidm system oauth2 update-sup-scope-map grafana grafana-admins admin +kanidm system oauth2 update-sup-scope-map grafana grafana-editors editor +kanidm system oauth2 show-basic-secret grafana +# Generate new oauth2 app for proxied webapps +kanidm group create web-sentinel-access +kanidm group create web-sentinel-adguardhome-access +kanidm system oauth2 create web-sentinel "Web services" https://sentinel.${personalDomain} +kanidm system oauth2 update-scope-map web-sentinel web-sentinel-access openid profile email +kanidm system oauth2 update-sup-scope-map web-sentinel web-sentinel-adguardhome-access access_adguardhome +kanidm system oauth2 show-basic-secret web-sentinel # Add new user -> kanidm login --name idm_admin -> kanidm person create myuser "My User" -> kanidm person update myuser --legalname "Full Name" --mail "myuser@example.com" -> kanidm group add_members grafana-access myuser -> kanidm group add_members grafana-server-admins myuser +kanidm login --name idm_admin +kanidm person create myuser "My User" +kanidm person update myuser --legalname "Full Name" --mail "myuser@example.com" +kanidm group add-members grafana-access myuser +kanidm group add-members grafana-server-admins myuser ``` diff --git a/flake.lock b/flake.lock index 449ba50..5fc6d92 100644 --- a/flake.lock +++ b/flake.lock @@ -31,11 +31,11 @@ ] }, "locked": { - "lastModified": 1687090623, - "narHash": "sha256-LdlH20WGKY1ebO3YJ85gPgmMPlGJUP4JUdqM+k5MsZw=", + "lastModified": 1687304097, + "narHash": "sha256-VId0oZxpYm4HSHwbsuGKI84zFkL6Gp4wuoJbbl52oZg=", "owner": "oddlama", "repo": "agenix-rekey", - "rev": "317558abbec903324e6d38393e2e84b42c25f479", + "rev": "b1811920562ba287b680f35644ce3ed78d029cdf", "type": "github" }, "original": { @@ -119,11 +119,11 @@ ] }, "locked": { - "lastModified": 1687028856, - "narHash": "sha256-vKV3I31tmXwaWHiUOgfDVd27cEHqaPBr1lt9+NKdIp8=", + "lastModified": 1687134796, + "narHash": "sha256-gjBAkEtNPMQzqK4IHjTQBUv3VhggszOHLJbhXZy0OVQ=", "owner": "nix-community", "repo": "disko", - "rev": "64c9c78c15fd4c899d857bf09dba88bda771b43a", + "rev": "4823509bb3b014dc85abefc13efcfa076d36338a", "type": "github" }, "original": { @@ -169,11 +169,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1685518550, - "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", + "lastModified": 1687171271, + "narHash": "sha256-BJlq+ozK2B1sJDQXS3tzJM5a+oVZmi1q0FlBK/Xqv7M=", "owner": "numtide", "repo": "flake-utils", - "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", + "rev": "abfb11bd1aec8ced1c9bb9adfe68018230f4fb3c", "type": "github" }, "original": { @@ -210,11 +210,11 @@ ] }, "locked": { - "lastModified": 1687081547, - "narHash": "sha256-/JV70TxhvP2r4xYtTlbQ2rrRDcj7MqHnF13r5ZE0oFc=", + "lastModified": 1687301540, + "narHash": "sha256-vFbCrE9WlOSVpyAT5VNR3bqMB7W7sDzMNDcO6JqtmBw=", "owner": "nix-community", "repo": "home-manager", - "rev": "28c823032cabfaa340a09e1d84cf45d11375c644", + "rev": "9a76fb9a852fdf9edd3b0aabc119efa1d618f969", "type": "github" }, "original": { @@ -275,11 +275,11 @@ }, "nixlib": { "locked": { - "lastModified": 1685840432, - "narHash": "sha256-VJIbiKsY7Xy4E4WcgwUt/UiwYDmN5BAk8tngAjcWsqY=", + "lastModified": 1687049841, + "narHash": "sha256-FBNZQfWtA7bb/rwk92mfiWc85x4hXta2OAouDqO5W8w=", "owner": "nix-community", "repo": "nixpkgs.lib", - "rev": "961e99baaaa57f5f7042fe7ce089a88786c839f4", + "rev": "908af6d1fa3643c5818ea45aa92b21d6385fbbe5", "type": "github" }, "original": { @@ -296,11 +296,11 @@ ] }, "locked": { - "lastModified": 1686924781, - "narHash": "sha256-6r3Hm2Fxf4F7LIWRYKU9bsS/xJwlG6L2+/I/pdffvOs=", + "lastModified": 1687183443, + "narHash": "sha256-foX4pkph2AwUdJL3JURa7IHog+YRIheZ54vwHwxqwhU=", "owner": "nix-community", "repo": "nixos-generators", - "rev": "a54683aa7eff00ee5b33dec225525d0eb6ab02de", + "rev": "09140f23f5ffce828db4ef040070bdd9595b1f3a", "type": "github" }, "original": { @@ -388,11 +388,11 @@ "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1686668298, - "narHash": "sha256-AADh9NqHh6X2LOem4BvI7oCkMm+JPCSCE7iIw5nn0VA=", + "lastModified": 1687251716, + "narHash": "sha256-+sFS41thsB5U+lY/dBYPSmU4AJ7nz/VdM1WD35fXVeM=", "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "5b6b54d3f722aa95cbf4ddbe35390a0af8c0015a", + "rev": "7807e1851d95828ed98491930d2d9e7ddbe65da4", "type": "github" }, "original": { diff --git a/hosts/common/core/system.nix b/hosts/common/core/system.nix index 5fcd5a2..dfc4d8e 100644 --- a/hosts/common/core/system.nix +++ b/hosts/common/core/system.nix @@ -362,6 +362,25 @@ lib.mkIf (pubkeyPath != null && lib.pathExists pubkeyPath) pubkeyPath; }; + age.generators.basic-auth.script = { + pkgs, + lib, + decrypt, + deps, + ... + }: + lib.flip lib.concatMapStrings deps ({ + name, + host, + file, + }: '' + echo " -> Aggregating "${lib.escapeShellArg host}":"${lib.escapeShellArg name}"" >&2 + echo -n ${lib.escapeShellArg host}"+"${lib.escapeShellArg name}" " + ${decrypt} ${lib.escapeShellArg file} \ + | ${pkgs.caddy}/bin/caddy hash-password --algorithm bcrypt \ + || die "Failure while aggregating caddy basic auth hashes" + ''); + boot = { initrd.systemd = { enable = true; diff --git a/hosts/sentinel/caddy.nix b/hosts/sentinel/caddy.nix index 6988959..b6fba7e 100644 --- a/hosts/sentinel/caddy.nix +++ b/hosts/sentinel/caddy.nix @@ -1,14 +1,19 @@ { config, - lib, - nodes, - nodeName, pkgs, ... }: { users.groups.acme.members = ["caddy"]; - services.caddy = { + age.secrets.caddy-env = { + rekeyFile = ./secrets/caddy-env.age; + mode = "440"; + group = "caddy"; + }; + + services.caddy = let + proxyAuthDomain = "sentinel.${config.repo.secrets.local.personalDomain}"; + in { enable = true; package = pkgs.caddy.withPackages { plugins = [ @@ -19,5 +24,52 @@ ]; vendorHash = "sha256-RqSXQihtY5+ACaMo7bLdhu1A+qcraexb1W/Ia+aUF1k"; }; + + virtualHosts.${proxyAuthDomain} = { + useACMEHost = config.lib.extra.matchingWildcardCert proxyAuthDomain; + extraConfig = '' + import common + authenticate with myportal + ''; + }; + + globalConfig = '' + order authenticate before respond + order authorize before basicauth + + security { + oauth identity provider kanidm { + realm kanidm + driver generic + client_id web-sentinel + client_secret {env.KANIDM_CLIENT_SECRET} + scopes openid email profile + base_auth_url https://${config.proxiedDomains.kanidm}/ui/oauth2 + metadata_url https://${config.proxiedDomains.kanidm}/oauth2/openid/sentinel/.well-known/openid-configuration + } + + authentication portal myportal { + enable identity provider kanidm + cookie domain ${config.repo.secrets.local.personalDomain} + ui { + links { + "My Identity" "/whoami" icon "las la-user" + } + } + + transform user { + match realm kanidm + action add role authp/user + } + + #transform user { + # match realm kanidm + # match scope read:access_aguardhome + # action add role authp/admin + #} + } + ''; }; + + systemd.services.caddy.serviceConfig.environmentFile = config.age.secrets.caddy-env.path; } diff --git a/hosts/sentinel/default.nix b/hosts/sentinel/default.nix index ca21c68..776caba 100644 --- a/hosts/sentinel/default.nix +++ b/hosts/sentinel/default.nix @@ -16,4 +16,9 @@ ./acme.nix ./caddy.nix ]; + + extra.promtail = { + enable = true; + proxy = "sentinel"; + }; } diff --git a/hosts/sentinel/secrets/caddy-env.age b/hosts/sentinel/secrets/caddy-env.age new file mode 100644 index 0000000..e778980 Binary files /dev/null and b/hosts/sentinel/secrets/caddy-env.age differ diff --git a/hosts/sentinel/secrets/promtail-loki-basic-auth-password.age b/hosts/sentinel/secrets/promtail-loki-basic-auth-password.age new file mode 100644 index 0000000..0699c11 --- /dev/null +++ b/hosts/sentinel/secrets/promtail-loki-basic-auth-password.age @@ -0,0 +1,11 @@ +age-encryption.org/v1 +-> X25519 5yDq2pctzyK8uUxKxekOz9tHbmUq4JKCzEbBCYQ79w0 +lFsTmuUufwYoZ1fAbs7BCmaU3h6Mck8w98TmUdahWP8 +-> piv-p256 xqSe8Q Aul+3eIiUD0DWAiRPR7Ms4l9ohF+62P98EYqngOFOwU9 +TdW4WUaIeT7rC9eeGjEM1jPEp/LE1q2V3/fQFLyjbtk +-> yYnni-grease 2a +SV/4RAhtPi8LsDwcXpwT8AZQCwwJ1tu0R3aN8r7J5cs2RCNGKvNYhU3WRZ6XUi84 +S1SGmd886W3twPhMYSjm9j8IqqJ5iaWq0IXPpxLZIpv1viS4jDoLgMcKxFbKI97z +5OCc +--- 30SxKU9DX+vU3e/fd4upxOLcv4DSujy06P+Ja2yHPjM +?Gu>ir7yۦm`"AM7^ M*O%BRQ“^Hx_;edW3q0\4: \ No newline at end of file diff --git a/hosts/ward/microvms/loki/default.nix b/hosts/ward/microvms/loki/default.nix index 21931dd..38ddbb6 100644 --- a/hosts/ward/microvms/loki/default.nix +++ b/hosts/ward/microvms/loki/default.nix @@ -26,27 +26,9 @@ in { age.secrets.loki-basic-auth-hashes = { rekeyFile = ./secrets/loki-basic-auth-hashes.age; - generator = { - # Dependencies are added by the nodes that define passwords (using distributed-config). - script = { - pkgs, - lib, - decrypt, - deps, - ... - }: - lib.flip lib.concatMapStrings deps ({ - name, - host, - file, - }: '' - echo " -> Aggregating "${lib.escapeShellArg host}":"${lib.escapeShellArg name}"" >&2 - echo -n ${lib.escapeShellArg host}"+"${lib.escapeShellArg name}" " - ${decrypt} ${lib.escapeShellArg file} \ - | ${pkgs.caddy}/bin/caddy hash-password --algorithm bcrypt \ - || die "Failure while aggregating caddy basic auth hashes" - ''); - }; + # Copy only the script so the dependencies can be added by the nodes + # that define passwords (using distributed-config). + generator.script = config.age.generators.basic-auth.script; mode = "440"; group = "caddy"; }; @@ -55,6 +37,7 @@ in { useACMEHost = sentinelCfg.lib.extra.matchingWildcardCert lokiDomain; extraConfig = '' import common + skip_log basicauth { import ${sentinelCfg.age.secrets.loki-basic-auth-hashes.path} } diff --git a/hosts/ward/microvms/loki/secrets/loki-basic-auth-hashes.age b/hosts/ward/microvms/loki/secrets/loki-basic-auth-hashes.age index 122be11..738a26e 100644 Binary files a/hosts/ward/microvms/loki/secrets/loki-basic-auth-hashes.age and b/hosts/ward/microvms/loki/secrets/loki-basic-auth-hashes.age differ