summaryrefslogtreecommitdiff
path: root/hostnix/weebnix/home-assistant.nix
blob: 500ff1017f9dde89fbea05a6534ddbe6c7ce4ad2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
{ pkgs, ... }:

let
  # Being cleaned up; see https://github.com/NixOS/nixpkgs/pull/160346
  customComponentFromGitHub = { name, ... }@attrs:
    { stdenv, fetchFromGitHub }:
    stdenv.mkDerivation {
      inherit name;
      src = fetchFromGitHub (removeAttrs attrs [ "name" ]);
      dontUnpack = true;
      installPhase = "cp -r $src/custom_components/${name} $out";
    };
  mapComponentTmpfile = map (package:
    let drv = pkgs.callPackage package { };
    in "L+ /var/lib/hass/custom_components/${drv.name} - - - - ${drv}/");
in {
  systemd.tmpfiles.rules =
    [ "d /var/lib/hass/custom_components 0700 hass hass" ]
    ++ mapComponentTmpfile [
      (customComponentFromGitHub {
        name = "auth_header";
        owner = "BeryJu";
        repo = "hass-auth-header";
        rev = "v1.10";
        hash = "sha256-dSmY3d8Kx0pXl+20dTGAYgjSH6OhNh53jPX7VLCZs7Y=";
      })
      (customComponentFromGitHub {
        name = "tuya_local";
        owner = "make-all";
        repo = "tuya-local";
        rev = "2023.9.1";
        hash = "sha256-uHImitvHFU7JoBx+aKzZuvpKl2tJCXwsxxk+sJ1+igk=";
      })
    ];

  services.postgresql = {
    enable = true;
    ensureDatabases = [ "hass" ];
    ensureUsers = [{
      name = "hass";
      ensurePermissions = { "DATABASE hass" = "ALL PRIVILEGES"; };
    }];
  };

  services.home-assistant = {
    enable = true;
    extraPackages = ps: with ps; [ psycopg2 ];
    extraComponents = [
      "androidtv_remote"
      "apple_tv"
      "cast"
      "homekit_controller"
      "hue"
      "spotify"
      "esphome"
      "met"
      "radio_browser"
    ];
    config = {
      default_config = { };
      http = {
        server_host = "::1";
        trusted_proxies = [ "::1" ];
        use_x_forwarded_for = true;
      };
      recorder.db_url = "postgresql://@/hass";
      auth_header = { };
    };
  };

  services.nginx.virtualHosts."ha.weebnix.mou.fo" = {
    enableACME = true;
    forceSSL = true;
    locations."/" = {
      proxyPass = "http://[::1]:8123";
      proxyWebsockets = true;
      extraConfig = ''
        # This is frequently used in examples but without clear explanation. It
        # might help with WebSockets.
        proxy_buffering off;
        # oauth2_proxy NixOS module sets some non-standard headers, but we need
        # the preferred_username claim.
        auth_request_set $preferred_username $upstream_http_x_auth_request_preferred_username;
        proxy_set_header X-Forwarded-Preferred-Username $preferred_username;
      '';
    };
  };

  # TODO how to configure for multiple domains?
  services.oauth2_proxy = {
    enable = true;
    nginx.virtualHosts = [ "ha.weebnix.mou.fo" ];
    setXauthrequest = true;
    # https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/oauth_provider/#keycloak-oidc-auth-provider
    provider = "keycloak-oidc";
    clientID = "ha.weebnix.mou.fo";
    # Sets OAUTH2_PROXY_COOKIE_SECRET and OAUTH2_PROXY_CLIENT_SECRET.
    keyFile = "/var/lib/secrets/oauth2-proxy.env";
    redirectURL = "https://ha.weebnix.mou.fo/oauth2/callback";
    email.domains = [ "*" ];
    extraConfig = {
      "oidc-issuer-url" = "https://kc.weebnix.mou.fo/realms/staging";
      "code-challenge-method" = "S256";
      # TODO this is specific to HA. move to nginx config?
      "skip-auth-route" = "^/api/";
    };
  };
}