build-bazel-package: added rm of extra local folders for toolchain configuration...
[NixPkgs.git] / nixos / modules / services / web-servers / nginx / tailscale-auth.nix
blob7529e6258fd25d90a4a3802006e0efe1ec09b71c
1 { config, lib, ... }:
3 let
4   inherit (lib)
5     genAttrs
6     maintainers
7     mkAliasOptionModule
8     mkEnableOption
9     mkIf
10     mkOption
11     types
12     ;
13   cfg = config.services.nginx.tailscaleAuth;
14   cfgAuth = config.services.tailscaleAuth;
17   imports = [
18     (mkAliasOptionModule
19       [ "services" "nginx" "tailscaleAuth" "package" ]
20       [ "services" "tailscaleAuth" "package" ]
21     )
22     (mkAliasOptionModule
23       [ "services" "nginx" "tailscaleAuth" "user" ]
24       [ "services" "tailscaleAuth" "user" ]
25     )
26     (mkAliasOptionModule
27       [ "services" "nginx" "tailscaleAuth" "group" ]
28       [ "services" "tailscaleAuth" "group" ]
29     )
30     (mkAliasOptionModule
31       [ "services" "nginx" "tailscaleAuth" "socketPath" ]
32       [ "services" "tailscaleAuth" "socketPath" ]
33     )
34   ];
36   options.services.nginx.tailscaleAuth = {
37     enable = mkEnableOption "tailscale.nginx-auth, to authenticate nginx users via tailscale";
39     expectedTailnet = mkOption {
40       default = "";
41       type = types.nullOr types.str;
42       example = "tailnet012345.ts.net";
43       description = ''
44         If you want to prevent node sharing from allowing users to access services
45         across tailnets, declare your expected tailnets domain here.
46       '';
47     };
49     virtualHosts = mkOption {
50       type = types.listOf types.str;
51       default = [ ];
52       description = ''
53         A list of nginx virtual hosts to put behind tailscale.nginx-auth
54       '';
55     };
56   };
58   config = mkIf cfg.enable {
59     services.tailscaleAuth.enable = true;
60     services.nginx.enable = true;
62     users.users.${config.services.nginx.user}.extraGroups = [ cfgAuth.group ];
64     systemd.services.tailscale-nginx-auth = {
65       after = [ "nginx.service" ];
66       wants = [ "nginx.service" ];
67     };
69     services.nginx.virtualHosts = genAttrs cfg.virtualHosts (vhost: {
70       locations."/auth" = {
71         extraConfig = ''
72           internal;
74           proxy_pass http://unix:${cfgAuth.socketPath};
75           proxy_pass_request_body off;
77           # Upstream uses $http_host here, but we are using gixy to check nginx configurations
78           # gixy wants us to use $host: https://github.com/yandex/gixy/blob/master/docs/en/plugins/hostspoofing.md
79           proxy_set_header Host $host;
80           proxy_set_header Remote-Addr $remote_addr;
81           proxy_set_header Remote-Port $remote_port;
82           proxy_set_header Original-URI $request_uri;
83           proxy_set_header X-Scheme                $scheme;
84           proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri;
85         '';
86       };
87       locations."/".extraConfig = ''
88         auth_request /auth;
89         auth_request_set $auth_user $upstream_http_tailscale_user;
90         auth_request_set $auth_name $upstream_http_tailscale_name;
91         auth_request_set $auth_login $upstream_http_tailscale_login;
92         auth_request_set $auth_tailnet $upstream_http_tailscale_tailnet;
93         auth_request_set $auth_profile_picture $upstream_http_tailscale_profile_picture;
95         proxy_set_header X-Webauth-User "$auth_user";
96         proxy_set_header X-Webauth-Name "$auth_name";
97         proxy_set_header X-Webauth-Login "$auth_login";
98         proxy_set_header X-Webauth-Tailnet "$auth_tailnet";
99         proxy_set_header X-Webauth-Profile-Picture "$auth_profile_picture";
101         ${lib.optionalString (
102           cfg.expectedTailnet != ""
103         ) ''proxy_set_header Expected-Tailnet "${cfg.expectedTailnet}";''}
104       '';
105     });
106   };
108   meta.maintainers = with maintainers; [ phaer ];