diff --git a/hosts/architect/bazarr.nix b/hosts/architect/bazarr.nix index 2e68e67..706ef3b 100644 --- a/hosts/architect/bazarr.nix +++ b/hosts/architect/bazarr.nix @@ -3,6 +3,7 @@ let domain = "htbaz.giugl.io"; network = import ./network.nix; + auth_block = (import ./openid.nix).openresty_oidc_block; in { services = { bazarr = { @@ -15,11 +16,12 @@ in { enableACME = true; locations."/" = { proxyPass = "http://localhost:6767"; - extraConfig = '' - allow 10.0.0.0/24; - ${lib.concatMapStrings (x: "allow ${x};") network.gdevices-wg} - deny all; - ''; + extraConfig = auth_block { + realm = "master"; + client_id = "bazarr"; + client_secret = "OPn4Mmto2m3dDPji1cjPfHy9W55M9JFq"; + redirect_uri = "https://${domain}"; + }; }; }; }; diff --git a/hosts/architect/deluge.nix b/hosts/architect/deluge.nix index 0ccbbf3..a3ef01d 100644 --- a/hosts/architect/deluge.nix +++ b/hosts/architect/deluge.nix @@ -3,6 +3,7 @@ let domain = "htdel.giugl.io"; network = import ./network.nix; + auth_block = (import ./openid.nix).openresty_oidc_block; in { services = { deluge = { @@ -32,13 +33,17 @@ in { }; nginx.virtualHosts.${domain} = { + forceSSL = true; + enableACME = true; + locations."/" = { proxyPass = "http://localhost:8112"; - extraConfig = '' - allow 10.0.0.0/24; - ${lib.concatMapStrings (x: "allow ${x};") network.gdevices-wg} - deny all; - ''; + extraConfig = auth_block { + realm = "master"; + client_id = "deluge"; + client_secret = "AGa1U9S1zkaM3TJVxtyx4Er76DBk1APR"; + redirect_uri = "https://${domain}"; + }; }; }; }; diff --git a/hosts/architect/keycloak.nix b/hosts/architect/keycloak.nix new file mode 100644 index 0000000..4607e18 --- /dev/null +++ b/hosts/architect/keycloak.nix @@ -0,0 +1,78 @@ +{ pkgs, config, ... }: + +let + network = import ./network.nix; + domain = "auth.giugl.io"; +in { + services = { + keycloak = { + enable = true; + initialAdminPassword = "giulio"; + database.passwordFile = "/secrets/keycloak/database.key"; + settings = { + hostname = domain; + proxy = "edge"; + http-port = 6654; + https-port = 6655; + hostname-strict-backchannel = true; + }; + }; + + postgresql = { + ensureDatabases = + [ "${toString config.services.keycloak.database.name}" ]; + ensureUsers = [{ + name = "${toString config.services.keycloak.database.username}"; + ensurePermissions = { + "DATABASE ${toString config.services.keycloak.database.name}" = + "ALL PRIVILEGES"; + }; + }]; + }; + + nginx.virtualHosts.${domain} = { + forceSSL = true; + enableACME = true; + + locations = { + "/" = { return = "301 https://${domain}/realms/master/account"; }; + + "/admin" = { + proxyPass = "http://127.0.0.1:${ + toString config.services.keycloak.settings.http-port + }"; + }; + + "/js" = { + proxyPass = "http://127.0.0.1:${ + toString config.services.keycloak.settings.http-port + }"; + }; + + "/realms" = { + proxyPass = "http://127.0.0.1:${ + toString config.services.keycloak.settings.http-port + }"; + }; + + "/resources" = { + proxyPass = "http://127.0.0.1:${ + toString config.services.keycloak.settings.http-port + }"; + }; + + "/robots.txt" = { + proxyPass = "http://127.0.0.1:${ + toString config.services.keycloak.settings.http-port + }"; + }; + + }; + }; + }; + + networking.extraHosts = '' + ${network.architect-lan} ${domain} + ${network.architect-wg} ${domain} + ''; +} diff --git a/hosts/architect/lidarr.nix b/hosts/architect/lidarr.nix index 9f9183d..c07fed5 100644 --- a/hosts/architect/lidarr.nix +++ b/hosts/architect/lidarr.nix @@ -3,6 +3,7 @@ let domain = "htlid.giugl.io"; network = import ./network.nix; + auth_block = (import ./openid.nix).openresty_oidc_block; in { services = { lidarr = { @@ -15,12 +16,12 @@ in { enableACME = true; locations."/" = { proxyPass = "http://localhost:8686"; - extraConfig = '' - allow 10.0.0.0/24; - ${lib.concatMapStrings (x: "allow ${x};") network.gdevices-wg} - deny all; - deny 10.0.0.1; - ''; + extraConfig = auth_block { + realm = "master"; + client_id = "lidarr"; + client_secret = "7s4dd1SEi84F4fUFsqRaQmSSucZhyTco"; + redirect_uri = "https://${domain}"; + }; }; }; }; diff --git a/hosts/architect/nextcloud.nix b/hosts/architect/nextcloud.nix index ee7bdcf..e6bb13b 100644 --- a/hosts/architect/nextcloud.nix +++ b/hosts/architect/nextcloud.nix @@ -3,24 +3,34 @@ let domain = "cloud.giugl.io"; network = import ./network.nix; + redis_port = 6379; in { services = { - mysql.enable = true; - mysql.package = pkgs.unstable.mysql80; + mysql = { + enable = true; + package = pkgs.unstable.mysql80; + }; - redis.servers."default".enable = true; + redis = { + vmOverCommit = true; + servers."nextcloud" = { + enable = true; + port = redis_port; + }; + }; nextcloud = { enable = true; - hostName = "${domain}"; + hostName = domain; https = true; package = pkgs.unstable.nextcloud24; - caching.redis = true; + caching = { + redis = true; + }; autoUpdateApps.enable = true; autoUpdateApps.startAt = "05:00:00"; - logLevel = 1; config = { overwriteProtocol = "https"; diff --git a/hosts/architect/nginx.nix b/hosts/architect/nginx.nix index 0777276..16a3542 100644 --- a/hosts/architect/nginx.nix +++ b/hosts/architect/nginx.nix @@ -1,8 +1,9 @@ -{ services, ... }: +{ services, pkgs, lib, ... }: { services.nginx = { enable = true; + package = pkgs.openresty; recommendedGzipSettings = true; recommendedOptimisation = true; recommendedProxySettings = true; @@ -25,6 +26,45 @@ "/wat.jpg" = { }; }; }; + appendHttpConfig = let + extraPureLuaPackages = with pkgs.luajitPackages; [ + lua-resty-openidc + lua-resty-http + lua-resty-session + lua-resty-jwt + lua-resty-openssl + ]; + luaPath = pkg: "${pkg}/share/lua/5.1/?.lua"; + makeLuaPath = lib.concatMapStringsSep ";" luaPath; + in '' + lua_package_path '${makeLuaPath extraPureLuaPackages};;'; + lua_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt; + lua_ssl_verify_depth 5; + + # cache for OIDC discovery metadata + lua_shared_dict discovery 1m; + lua_shared_dict jwks 1m; + + # https://github.com/openresty/lua-resty-redis/issues/159 + resolver local=on ipv6=off; + + init_worker_by_lua_block { + function check_role (res, role) + if res.user.roles == nil then + return false + end + + for _,v in pairs(res.user.roles) do + if string.lower(v) == role then + return true + end + end + + return false + end + } + ''; + appendConfig = '' worker_processes 24; ''; diff --git a/hosts/architect/nzbget.nix b/hosts/architect/nzbget.nix index 8875098..27fcb67 100644 --- a/hosts/architect/nzbget.nix +++ b/hosts/architect/nzbget.nix @@ -3,6 +3,7 @@ let domain = "htnzb.giugl.io"; network = import ./network.nix; + auth_block = (import ./openid.nix).openresty_oidc_block; in { services = { nzbget = { @@ -15,11 +16,12 @@ in { enableACME = true; locations."/" = { proxyPass = "http://localhost:6789"; - extraConfig = '' - allow 10.0.0.0/24; - ${lib.concatMapStrings (x: "allow ${x};") network.gdevices-wg} - deny all; - ''; + extraConfig = auth_block { + realm = "master"; + client_id = "nzbget"; + client_secret = "tkjzdqnUoWTlGUYah5tgMqVPFMlOUvk9"; + redirect_uri = "https://${domain}"; + }; }; }; }; diff --git a/hosts/architect/openid.nix b/hosts/architect/openid.nix new file mode 100644 index 0000000..caf865b --- /dev/null +++ b/hosts/architect/openid.nix @@ -0,0 +1,37 @@ +{ lib }: + +{ + openresty_oidc_block = + { realm, client_id, client_secret, redirect_uri, access_role ? "" }: '' + access_by_lua_block { + local opts = { + discovery = "https://auth.giugl.io/realms/${realm}/.well-known/openid-configuration", + client_id = "${client_id}", + client_secret = "${client_secret}", + logout_path = "/logout", + redirect_after_logout_uri = "/", + redirect_uri = "/redirect_uri", + keepalive = "yes", + accept_none_alg = true + } + + -- call introspect for OAuth 2.0 Bearer Access Token validation + local res, err = require("resty.openidc").authenticate(opts) + + if err then + ngx.status = 403 + ngx.say(err) + ngx.exit(ngx.HTTP_FORBIDDEN) + end + + ${lib.optionalString (access_role != "") '' + if not check_role(res, "${access_role}") then + ngx.status = 401 + ngx.header.content_type = 'text/html'; + ngx.say("You are not authorized to access this page. Please contact Er Pepotto.") + ngx.exit(ngx.HTTP_UNAUTHORIZED) + end + ''} + } + ''; +} diff --git a/hosts/architect/radarr.nix b/hosts/architect/radarr.nix index 2f6e8ca..f0dda97 100644 --- a/hosts/architect/radarr.nix +++ b/hosts/architect/radarr.nix @@ -3,6 +3,7 @@ let domain = "htrad.giugl.io"; network = import ./network.nix; + auth_block = (import ./openid.nix).openresty_oidc_block; in { services = { radarr = { @@ -15,11 +16,12 @@ in { enableACME = true; locations."/" = { proxyPass = "http://localhost:7878"; - extraConfig = '' - allow 10.0.0.0/24; - ${lib.concatMapStrings (x: "allow ${x};") network.gdevices-wg} - deny all; - ''; + extraConfig = auth_block { + realm = "master"; + client_id = "radarr"; + client_secret = "DCoeN4PwqGrAoG6Mqw73orrUjojJ1fmn"; + redirect_uri = "https://${domain}"; + }; }; }; }; diff --git a/hosts/architect/sonarr.nix b/hosts/architect/sonarr.nix index 2776fbe..5bccd50 100644 --- a/hosts/architect/sonarr.nix +++ b/hosts/architect/sonarr.nix @@ -3,6 +3,7 @@ let domain = "htson.giugl.io"; network = import ./network.nix; + auth_block = (import ./openid.nix).openresty_oidc_block; in { services = { sonarr = { @@ -15,11 +16,12 @@ in { enableACME = true; locations."/" = { proxyPass = "http://localhost:8989"; - extraConfig = '' - allow 10.0.0.0/24; - ${lib.concatMapStrings (x: "allow ${x};") network.gdevices-wg} - deny all; - ''; + extraConfig = auth_block { + realm = "master"; + client_id = "sonarr"; + client_secret = "d36ehMSPCI3xLfOGNcnSUKZWQblyGumi"; + redirect_uri = "https://${domain}"; + }; }; }; }; diff --git a/roles/home/common.nix b/roles/home/common.nix index c8a4462..6b91360 100644 --- a/roles/home/common.nix +++ b/roles/home/common.nix @@ -1,7 +1,7 @@ { config, pkgs, ... }: { - imports = [ ./zsh.nix ./git.nix ./neovim.nix ]; + imports = [ ./zsh.nix ./git.nix ./helix.nix ]; home = { packages = with pkgs; [ rizin sshfs victor-mono home-manager ]; }; } diff --git a/roles/home/helix.nix b/roles/home/helix.nix new file mode 100644 index 0000000..764a7e8 --- /dev/null +++ b/roles/home/helix.nix @@ -0,0 +1,22 @@ +{ config, pkgs, ... }: + +{ + home = { + sessionVariables = { + EDITOR = "hx"; + VISUAL = "hx"; + }; + + file.".config/helix/config.toml".text = '' + theme = "monokai" + ''; + + packages = with pkgs.unstable; [ + helix + clang-tools + rust-analyzer + rnix-lsp + python310Packages.python-lsp-server + ]; + }; +} diff --git a/roles/home/neovim.nix b/roles/home/neovim.nix index cf1730b..3132572 100644 --- a/roles/home/neovim.nix +++ b/roles/home/neovim.nix @@ -20,6 +20,8 @@ cmake-format clang-tools rustfmt + nixfmt + shfmt ]; plugins = with pkgs.vimPlugins; [ vim-nix @@ -38,9 +40,11 @@ cmp-nvim-lsp (nvim-treesitter.withPlugins (_: pkgs.tree-sitter.allGrammars)) nvim-treesitter-textobjects + minimap-vim + pkgs.vimExtraPlugins.leap-nvim ]; - + extraConfig = '' " syntax syntax enable @@ -53,7 +57,7 @@ set wildmode=longest:full,full " remapping popup menu (command autocompletion) - cnoremap pumvisible() ? "" : " + cnoremap pumvisible() ? "" : "" cnoremap pumvisible() ? "" : "" cnoremap pumvisible() ? "":"" @@ -80,6 +84,11 @@ " Enable trimmming of trailing whitespace let g:neoformat_basic_format_trim = 1 + " Config minimap + let g:minimap_width = 10 + let g:minimap_auto_start = 1 + let g:minimap_auto_start_win_enter = 1 + lua << EOF -- Setup leap-nvim keymappings