at 25.11-pre 5.8 kB view raw
1{ config, lib, ... }: 2let 3 cfg = config.services.oauth2-proxy.nginx; 4in 5{ 6 options.services.oauth2-proxy.nginx = { 7 proxy = lib.mkOption { 8 type = lib.types.str; 9 default = config.services.oauth2-proxy.httpAddress; 10 defaultText = lib.literalExpression "config.services.oauth2-proxy.httpAddress"; 11 description = '' 12 The address of the reverse proxy endpoint for oauth2-proxy 13 ''; 14 }; 15 16 domain = lib.mkOption { 17 type = lib.types.str; 18 description = '' 19 The domain under which the oauth2-proxy will be accesible and the path of cookies are set to. 20 This setting must be set to ensure back-redirects are working properly 21 if oauth2-proxy is configured with {option}`services.oauth2-proxy.cookie.domain` 22 or multiple {option}`services.oauth2-proxy.nginx.virtualHosts` that are not on the same domain. 23 ''; 24 }; 25 26 virtualHosts = lib.mkOption { 27 type = 28 let 29 vhostSubmodule = lib.types.submodule { 30 options = { 31 allowed_groups = lib.mkOption { 32 type = lib.types.nullOr (lib.types.listOf lib.types.str); 33 description = "List of groups to allow access to this vhost, or null to allow all."; 34 default = null; 35 }; 36 allowed_emails = lib.mkOption { 37 type = lib.types.nullOr (lib.types.listOf lib.types.str); 38 description = "List of emails to allow access to this vhost, or null to allow all."; 39 default = null; 40 }; 41 allowed_email_domains = lib.mkOption { 42 type = lib.types.nullOr (lib.types.listOf lib.types.str); 43 description = "List of email domains to allow access to this vhost, or null to allow all."; 44 default = null; 45 }; 46 }; 47 }; 48 oldType = lib.types.listOf lib.types.str; 49 convertFunc = 50 x: 51 lib.warn 52 "services.oauth2-proxy.nginx.virtualHosts should be an attrset, found ${lib.generators.toPretty { } x}" 53 lib.genAttrs 54 x 55 (_: { }); 56 newType = lib.types.attrsOf vhostSubmodule; 57 in 58 lib.types.coercedTo oldType convertFunc newType; 59 default = { }; 60 example = { 61 "protected.foo.com" = { 62 allowed_groups = [ "admins" ]; 63 allowed_emails = [ "boss@foo.com" ]; 64 }; 65 }; 66 description = '' 67 Nginx virtual hosts to put behind the oauth2 proxy. 68 You can exclude specific locations by setting `auth_request off;` in the locations extraConfig setting. 69 ''; 70 }; 71 }; 72 73 config.services.oauth2-proxy = 74 lib.mkIf (cfg.virtualHosts != { } && (lib.hasPrefix "127.0.0.1:" cfg.proxy)) 75 { 76 enable = true; 77 }; 78 79 config.services.nginx = lib.mkIf (cfg.virtualHosts != { } && config.services.oauth2-proxy.enable) ( 80 lib.mkMerge ( 81 [ 82 { 83 virtualHosts.${cfg.domain}.locations."/oauth2/" = { 84 proxyPass = cfg.proxy; 85 extraConfig = '' 86 auth_request off; 87 proxy_set_header X-Scheme $scheme; 88 proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri; 89 ''; 90 }; 91 } 92 ] 93 ++ lib.optional (cfg.virtualHosts != { }) { 94 recommendedProxySettings = true; # needed because duplicate headers 95 } 96 ++ (lib.mapAttrsToList (vhost: conf: { 97 virtualHosts.${vhost} = { 98 locations = { 99 "/".extraConfig = '' 100 # pass information via X-User and X-Email headers to backend, requires running with --set-xauthrequest flag 101 proxy_set_header X-User $user; 102 proxy_set_header X-Email $email; 103 104 # if you enabled --cookie-refresh, this is needed for it to work with auth_request 105 add_header Set-Cookie $auth_cookie; 106 ''; 107 108 "= /oauth2/auth" = 109 let 110 maybeQueryArg = 111 name: value: 112 if value == null then 113 null 114 else 115 "${name}=${lib.concatStringsSep "," (builtins.map lib.escapeURL value)}"; 116 allArgs = lib.mapAttrsToList maybeQueryArg conf; 117 cleanArgs = builtins.filter (x: x != null) allArgs; 118 cleanArgsStr = lib.concatStringsSep "&" cleanArgs; 119 in 120 { 121 # nginx doesn't support passing query string arguments to auth_request, 122 # so pass them here instead 123 proxyPass = "${cfg.proxy}/oauth2/auth?${cleanArgsStr}"; 124 extraConfig = '' 125 auth_request off; 126 proxy_set_header X-Scheme $scheme; 127 # nginx auth_request includes headers but not body 128 proxy_set_header Content-Length ""; 129 proxy_pass_request_body off; 130 ''; 131 }; 132 133 "@redirectToAuth2ProxyLogin" = { 134 return = "307 https://${cfg.domain}/oauth2/start?rd=$scheme://$host$request_uri"; 135 extraConfig = '' 136 auth_request off; 137 ''; 138 }; 139 }; 140 141 extraConfig = '' 142 auth_request /oauth2/auth; 143 error_page 401 = @redirectToAuth2ProxyLogin; 144 145 # set variables being used in locations."/".extraConfig 146 auth_request_set $user $upstream_http_x_auth_request_user; 147 auth_request_set $email $upstream_http_x_auth_request_email; 148 auth_request_set $auth_cookie $upstream_http_set_cookie; 149 ''; 150 }; 151 }) cfg.virtualHosts) 152 ) 153 ); 154}