2024-01-02 11:29:13 +00:00
|
|
|
{ config, lib, pkgs, ... }:
|
|
|
|
|
|
|
|
let
|
2024-04-21 15:54:59 +00:00
|
|
|
inherit (lib)
|
|
|
|
genAttrs
|
|
|
|
maintainers
|
|
|
|
mkAliasOptionModule
|
|
|
|
mkEnableOption
|
|
|
|
mkIf
|
|
|
|
mkOption
|
|
|
|
types
|
|
|
|
;
|
2024-01-02 11:29:13 +00:00
|
|
|
cfg = config.services.nginx.tailscaleAuth;
|
2024-04-21 15:54:59 +00:00
|
|
|
cfgAuth = config.services.tailscaleAuth;
|
2024-01-02 11:29:13 +00:00
|
|
|
in
|
|
|
|
{
|
2024-04-21 15:54:59 +00:00
|
|
|
imports = [
|
|
|
|
(mkAliasOptionModule [ "services" "nginx" "tailscaleAuth" "package" ] [ "services" "tailscaleAuth" "package" ])
|
|
|
|
(mkAliasOptionModule [ "services" "nginx" "tailscaleAuth" "user" ] [ "services" "tailscaleAuth" "user" ])
|
|
|
|
(mkAliasOptionModule [ "services" "nginx" "tailscaleAuth" "group" ] [ "services" "tailscaleAuth" "group" ])
|
|
|
|
(mkAliasOptionModule [ "services" "nginx" "tailscaleAuth" "socketPath" ] [ "services" "tailscaleAuth" "socketPath" ])
|
|
|
|
];
|
2024-01-02 11:29:13 +00:00
|
|
|
|
2024-04-21 15:54:59 +00:00
|
|
|
options.services.nginx.tailscaleAuth = {
|
|
|
|
enable = mkEnableOption "Enable tailscale.nginx-auth, to authenticate nginx users via tailscale.";
|
2024-01-02 11:29:13 +00:00
|
|
|
|
|
|
|
expectedTailnet = mkOption {
|
|
|
|
default = "";
|
|
|
|
type = types.nullOr types.str;
|
|
|
|
example = "tailnet012345.ts.net";
|
2024-04-21 15:54:59 +00:00
|
|
|
description = ''
|
2024-01-02 11:29:13 +00:00
|
|
|
If you want to prevent node sharing from allowing users to access services
|
|
|
|
across tailnets, declare your expected tailnets domain here.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
virtualHosts = mkOption {
|
|
|
|
type = types.listOf types.str;
|
|
|
|
default = [];
|
2024-04-21 15:54:59 +00:00
|
|
|
description = ''
|
2024-01-02 11:29:13 +00:00
|
|
|
A list of nginx virtual hosts to put behind tailscale.nginx-auth
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
config = mkIf cfg.enable {
|
2024-04-21 15:54:59 +00:00
|
|
|
services.tailscaleAuth.enable = true;
|
2024-01-02 11:29:13 +00:00
|
|
|
services.nginx.enable = true;
|
|
|
|
|
2024-04-21 15:54:59 +00:00
|
|
|
users.users.${config.services.nginx.user}.extraGroups = [ cfgAuth.group ];
|
2024-01-02 11:29:13 +00:00
|
|
|
|
|
|
|
systemd.services.tailscale-nginx-auth = {
|
|
|
|
after = [ "nginx.service" ];
|
|
|
|
wants = [ "nginx.service" ];
|
|
|
|
};
|
|
|
|
|
|
|
|
services.nginx.virtualHosts = genAttrs
|
|
|
|
cfg.virtualHosts
|
|
|
|
(vhost: {
|
|
|
|
locations."/auth" = {
|
|
|
|
extraConfig = ''
|
|
|
|
internal;
|
|
|
|
|
2024-04-21 15:54:59 +00:00
|
|
|
proxy_pass http://unix:${cfgAuth.socketPath};
|
2024-01-02 11:29:13 +00:00
|
|
|
proxy_pass_request_body off;
|
|
|
|
|
|
|
|
# Upstream uses $http_host here, but we are using gixy to check nginx configurations
|
|
|
|
# gixy wants us to use $host: https://github.com/yandex/gixy/blob/master/docs/en/plugins/hostspoofing.md
|
|
|
|
proxy_set_header Host $host;
|
|
|
|
proxy_set_header Remote-Addr $remote_addr;
|
|
|
|
proxy_set_header Remote-Port $remote_port;
|
|
|
|
proxy_set_header Original-URI $request_uri;
|
|
|
|
proxy_set_header X-Scheme $scheme;
|
|
|
|
proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri;
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
locations."/".extraConfig = ''
|
|
|
|
auth_request /auth;
|
|
|
|
auth_request_set $auth_user $upstream_http_tailscale_user;
|
|
|
|
auth_request_set $auth_name $upstream_http_tailscale_name;
|
|
|
|
auth_request_set $auth_login $upstream_http_tailscale_login;
|
|
|
|
auth_request_set $auth_tailnet $upstream_http_tailscale_tailnet;
|
|
|
|
auth_request_set $auth_profile_picture $upstream_http_tailscale_profile_picture;
|
|
|
|
|
|
|
|
proxy_set_header X-Webauth-User "$auth_user";
|
|
|
|
proxy_set_header X-Webauth-Name "$auth_name";
|
|
|
|
proxy_set_header X-Webauth-Login "$auth_login";
|
|
|
|
proxy_set_header X-Webauth-Tailnet "$auth_tailnet";
|
|
|
|
proxy_set_header X-Webauth-Profile-Picture "$auth_profile_picture";
|
|
|
|
|
|
|
|
${lib.optionalString (cfg.expectedTailnet != "") ''proxy_set_header Expected-Tailnet "${cfg.expectedTailnet}";''}
|
|
|
|
'';
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
meta.maintainers = with maintainers; [ phaer ];
|
|
|
|
|
|
|
|
}
|