diff --git a/esphomes/.esphome/esphome.json b/esphomes/.esphome/esphome.json new file mode 100644 index 00000000..7d5f004e --- /dev/null +++ b/esphomes/.esphome/esphome.json @@ -0,0 +1,6 @@ +{ + "storage_version": 1, + "cookie_secret": "01549d59c31ba18263ed0136121dafffb05a163935286f08a145ae33238cc4fbc2b7b123e65af03de968683ee133707f87ffdf750299417375c26b87ec00f1ef", + "last_update_check": null, + "remote_version": null +} diff --git a/hardware/local.nix b/hardware/local.nix index bd57271b..168a7cce 100644 --- a/hardware/local.nix +++ b/hardware/local.nix @@ -4,7 +4,7 @@ type = "resource"; connection = { port = lib.head config.services.openssh.ports; - host = config.networks.gensokyo.ipv4 or config.networks.chitei.ipv4; + host = if config.networks.gensokyo.interfaces != [] then config.networks.gensokyo.ipv4 else config.networks.chitei.ipv4; }; }; } diff --git a/home/gui/packages.nix b/home/gui/packages.nix index dc2c6433..cc9c6153 100644 --- a/home/gui/packages.nix +++ b/home/gui/packages.nix @@ -20,5 +20,7 @@ jmtpfs element-desktop cryptsetup + esphome + kicad ]; } diff --git a/home/shell/ssh.nix b/home/shell/ssh.nix index 8bf84e93..a1889258 100644 --- a/home/shell/ssh.nix +++ b/home/shell/ssh.nix @@ -7,21 +7,16 @@ controlPersist = "10m"; hashKnownHosts = true; compression = true; - /*TODO: revisit this - matchBlocks = - let - common = { - forwardAgent = true; - extraOptions = { - RemoteForward = - "/run/user/1000/gnupg/S.gpg-agent /run/user/1000/gnupg/S.gpg-agent.extra"; - }; - port = 62954; - }; - in - (lib.foldAttrList (map - (network: - lib.mapAttrs (_: v: { hostname = v.domain; } // common) (lib.filterAttrs (_: v: v.enable) (lib.mapAttrs (_: v: v.network.addresses.${network}) meta.network.nodes.nixos)) - ) [ "private" "public" ]));*/ + matchBlocks = lib.mapAttrs (host: data: { + port = lib.head meta.networks.tailscale.member_configs.${host}.services.openssh.ports; + hostname = data.ipv4; + forwardAgent = true; + extraOptions = { + RemoteForward = (lib.concatStringsSep " " [ + "/run/user/1000/gnupg/S.gpg-agent" + "/run/user/1000/gnupg/S.gpg-agent.extra" + ]); + }; + }) meta.networks.tailscale.members; }; } diff --git a/home/vim/init.lua b/home/vim/init.lua index f98387ac..b471bdc0 100644 --- a/home/vim/init.lua +++ b/home/vim/init.lua @@ -287,7 +287,10 @@ require('bufferline').setup { right_mouse_command = "bdelete! %d", -- can be a string | function, see "Mouse actions" left_mouse_command = "buffer %d", -- can be a string | function, see "Mouse actions" middle_mouse_command = nil, -- can be a string | function, see "Mouse actions" - indicator_icon = '▎', + indicator = { + icon = '▎', + style = 'icon', + }, buffer_close_icon = '', modified_icon = '●', close_icon = '', diff --git a/home/waybar/default.nix b/home/waybar/default.nix index c4d594b5..cd7ff0cc 100644 --- a/home/waybar/default.nix +++ b/home/waybar/default.nix @@ -23,8 +23,6 @@ "pulseaudio" "custom/headset-icon" "custom/headset" - "custom/mail-icon" - "custom/mail" "custom/cpu-icon" "cpu" "custom/memory-icon" @@ -33,7 +31,8 @@ "temperature" "battery#icon" "battery" - "backlight#icon" + "battery#icon" + "backlight" "backlight" "network" "idle_inhibitor" @@ -60,10 +59,13 @@ icon-size = 12; spacing = 2; }; - backlight = { - format = "{icon} {percent}%"; + "backlight#icon" = { + format = "{icon}"; format-icons = ["" ""]; }; + backlight = { + format = "{percent}%"; + }; "custom/gpg-status" = { format = "{}"; interval = 300; @@ -91,12 +93,6 @@ on-click-right = "systemctl --user restart konawall"; signal = 8; }; - "custom/mail-icon".format = ""; - "custom/mail" = { - format = "{}"; - interval = 30; - exec = "${pkgs.notmuch-arc}/bin/notmuch count tag:flagged OR tag:inbox AND NOT tag:killed"; - }; "custom/cpu-icon".format = ""; cpu.format = "{usage}%"; "custom/memory-icon".format = ""; diff --git a/meta.nix b/meta.nix index 26a5c1d0..661a0149 100644 --- a/meta.nix +++ b/meta.nix @@ -29,11 +29,11 @@ in { }; pp = mkOption { type = types.unspecified; - default = family: port: "http://${config."ipv${toString family}"}:${toString port}"; + default = family: port: "http://${config."ipv${toString family}"}:${toString port}/"; }; ppp = mkOption { type = types.unspecified; - default = family: port: path: "http://${config."ipv${toString family}"}/${path}:${toString port}"; + default = family: port: path: "http://${config."ipv${toString family}"}:${toString port}/${path}"; }; tags = mkOption { type = types.listOf types.str; @@ -76,6 +76,7 @@ in { "${bitw}/bin/bitw get"; deploy.targets.dummy.enable = false; + deploy.targets.marisa.tf.terraform.refreshOnApply = false; _module.args.pkgs = lib.mkDefault pkgs; }; } diff --git a/nixos/network.nix b/nixos/network.nix index 9b347f79..fe9ef836 100644 --- a/nixos/network.nix +++ b/nixos/network.nix @@ -10,8 +10,16 @@ type = nullOr str; default = nixos.networking.hostName; }; + owner = mkOption { + type = str; + default = "nginx"; + }; + group = mkOption { + type = str; + default = "domain-auth"; + }; network = mkOption { - type = nullOr str; + type = unspecified; default = "internet"; }; type = mkOption { @@ -22,6 +30,10 @@ "cname" ]; }; + create_cert = mkOption { + type = bool; + default = true; + }; domain = mkOption { type = nullOr str; default = "${nixos.networking.hostName}${if config.prefix != null then ".${config.prefix}" else ""}"; @@ -42,7 +54,7 @@ type = nullOr str; default = if (config.type == "cname" && config.host != nixos.networking.hostName) then meta.network.nodes.nixos.${config.host}.networks.${config.network}.target - else "${config.domain}.${config.zone}"; + else "${if config.domain == null then "" else "${config.domain}."}${config.zone}"; }; }; })); @@ -126,6 +138,11 @@ type = bool; default = false; }; + extra_domains = mkOption { + type = listOf str; + description = "Domains to add to the certificate generated for this network."; + default = []; + }; domain = mkOption { type = nullOr str; default = "${nixos.networking.hostName}${if config.prefix != null then ".${config.prefix}" else ""}"; @@ -146,13 +163,17 @@ })); }; }; - config = { + config = let + sane_networks = lib.filterAttrs (network: settings: settings.interfaces != []) config.networks; + in { networks = { internet = { + zone = mkDefault "kittywit.ch."; create_domain = true; }; chitei = { - create_domain = true; + zone = mkDefault "kittywit.ch."; + create_domain = false; }; gensokyo = { zone = mkDefault "gensokyo.zone."; @@ -182,8 +203,8 @@ domains' = map (family: mapAttrs' (name: settings: let network = if settings.host != config.networking.hostName then meta.network.nodes.nixos.${settings.host}.networks.${settings.network} - else config.networks.${settings.network}; - in nameValuePair "${settings.network}-${if settings.type == "both" || settings.type == family then family else settings.type}-${settings.domain}-${settings.zone}" ({ + else sane_networks.${settings.network}; + in nameValuePair "${settings.network}-${if settings.type == "both" || settings.type == family then family else settings.type}-${if settings.domain == null then "root" else settings.domain}-${settings.zone}" ({ inherit (settings) domain zone; enable = mkDefault false; } // (optionalAttrs (settings.type == "cname" && family == "ipv4") { @@ -200,9 +221,21 @@ a.address = network.ipv4; enable = mkForce network.ipv4_defined; }))) domains) address_families; - networks = config.networks; + networks = sane_networks; # Networks to actually create domains for networks' = filterAttrs (_: settings: settings.create_domain) networks; + # Extra domains to automatically be cnamed + extraDomainedNetworks = filterAttrs (_: settings: settings.extra_domains != []) networks'; + extraDomains = listToAttrs (concatLists (mapAttrsToList (network: settings: + map (domain: let + split_domain = splitString "." domain; + isRoot = (length split_domain) == 2; + in nameValuePair "${network}-cname-${if isRoot then "root" else elemAt split_domain (length split_domain -2)}-${concatStringsSep "." (sublist (length split_domain - 2) (length split_domain) split_domain)}." { + zone = "${concatStringsSep "." (sublist (length split_domain - 2) (length split_domain) split_domain)}."; + domain = if isRoot then null + else elemAt split_domain (length split_domain - 2); + cname = { inherit (settings) target; }; + }) settings.extra_domains) extraDomainedNetworks)); # Merge the result of a map upon address_families to mapAttrs' networks'' = map (family: mapAttrs' (network: settings: nameValuePair "${network}-${family}-${settings.domain}-${settings.zone}" ({ @@ -216,7 +249,7 @@ a.address = settings.ipv4; }) )) networks') address_families; - in mkMerge (networks'' ++ domains'); + in mkMerge (networks'' ++ domains' ++ [ extraDomains ]); acme = let home = meta.deploy.targets.home.tf; @@ -236,13 +269,13 @@ }; }; certs = let - hostnames = (attrValues (mapAttrs (network: settings: removeSuffix "." settings.target) config.networks)) - ++ (attrValues (mapAttrs (network: settings: removeSuffix "." settings.target) config.domains)); - in listToAttrs (map (hostname: - nameValuePair hostname { - keyType = "4096"; - dnsNames = singleton hostname; - }) hostnames); + nvP = network: settings: nameValuePair "${removeSuffix "." settings.target}" { + keyType = "4096"; + dnsNames = [ (removeSuffix "." settings.target) ] ++ (lib.optionals (settings ? extra_domains) settings.extra_domains); + }; + network_certs = mapAttrs' nvP sane_networks; + domain_certs = mapAttrs' nvP (filterAttrs (network: settings: settings.create_cert) config.domains); + in network_certs // domain_certs; }; variables = { @@ -271,39 +304,60 @@ }; secrets.files = let - hostnames = (attrValues (mapAttrs (network: settings: removeSuffix "." settings.target) config.networks)) - ++ (attrValues (mapAttrs (network: settings: removeSuffix "." settings.target) config.domains)); - in listToAttrs (map (hostname: - nameValuePair "${hostname}-cert" { - text = tf.acme.certs.${hostname}.out.refFullchainPem; - owner = "nginx"; - group = "domain-auth"; - }) hostnames) // listToAttrs (map (hostname: - nameValuePair "${hostname}-key" { - text = tf.acme.certs.${hostname}.out.refPrivateKeyPem; - owner = "nginx"; - group = "domain-auth"; - }) hostnames); + fixedTarget = settings: removeSuffix "." settings.target; + networks = mapAttrs' (network: settings: + nameValuePair "${fixedTarget settings}-cert" { + text = tf.acme.certs.${fixedTarget settings}.out.refFullchainPem; + owner = "nginx"; + group = "domain-auth"; + } + ) sane_networks; + networks' = mapAttrs' (network: settings: + nameValuePair "${fixedTarget settings}-key" { + text = tf.acme.certs.${fixedTarget settings}.out.refPrivateKeyPem; + owner = "nginx"; + group = "domain-auth"; + } + ) sane_networks; + domains = mapAttrs' (network: settings: + nameValuePair "${fixedTarget settings}-cert" { + text = tf.acme.certs.${fixedTarget settings}.out.refFullchainPem; + owner = settings.owner; + group = settings.group; + } + ) (filterAttrs (network: settings: settings.create_cert) config.domains); + domains' = mapAttrs' (network: settings: + nameValuePair "${fixedTarget settings}-key" { + text = tf.acme.certs.${fixedTarget settings}.out.refPrivateKeyPem; + owner = settings.owner; + group = settings.group; + } + ) (filterAttrs (network: settings: settings.create_cert) config.domains); + in networks // networks' // domains // domains'; services.nginx.virtualHosts = let - hostnames = (attrValues (mapAttrs (network: settings: removeSuffix "." settings.target) config.networks)) - ++ (attrValues (mapAttrs (network: settings: removeSuffix "." settings.target) config.domains)); - in listToAttrs (map (hostname: - nameValuePair hostname { - forceSSL = true; - sslCertificate = config.secrets.files."${hostname}-cert".path; - sslCertificateKey = config.secrets.files."${hostname}-key".path; - }) hostnames); + networkVirtualHosts = concatLists (mapAttrsToList (network: settings: map(domain: nameValuePair domain { + forceSSL = true; + sslCertificate = config.secrets.files."${removeSuffix "." settings.target}-cert".path; + sslCertificateKey = config.secrets.files."${removeSuffix "." settings.target}-key".path; + }) ([ settings.target ] ++ settings.extra_domains)) sane_networks); + domainVirtualHosts = (attrValues (mapAttrs (network: settings: removeSuffix "." settings.target) config.domains)); + domainVirtualHosts' = (map (hostname: + nameValuePair hostname { + forceSSL = true; + sslCertificate = config.secrets.files."${hostname}-cert".path; + sslCertificateKey = config.secrets.files."${hostname}-key".path; + }) domainVirtualHosts); + in listToAttrs (networkVirtualHosts ++ (lib.optionals config.services.nginx.enable domainVirtualHosts')); users.groups.domain-auth = { gid = 10600; - members = [ "nginx" "openldap" "keycloak" ]; }; networking.firewall = { interfaces = mkMerge (mapAttrsToList (network: settings: genAttrs settings.interfaces (_: { allowedTCPPortRanges = settings.tcp; allowedUDPPortRanges = settings.udp; }) - ) (removeAttrs config.networks ["tailscale"])); + ) (removeAttrs sane_networks ["tailscale"])); trustedInterfaces = [ "tailscale0" ]; allowedTCPPorts = [ 5200 ]; allowedUDPPorts = [ config.services.tailscale.port ]; diff --git a/nixos/systems/koishi.nix b/nixos/systems/koishi.nix index 5dfb5412..5b755e8c 100644 --- a/nixos/systems/koishi.nix +++ b/nixos/systems/koishi.nix @@ -1,24 +1,15 @@ { meta, config, pkgs, lib, ... }: with lib; { imports = with meta; [ hardware.x270 + hardware.local nixos.gui nixos.light nixos.network + services.nginx home.gui ]; config = { - deploy.tf = { - resources.koishi = { - provider = "null"; - type = "resource"; - connection = { - port = head config.services.openssh.ports; - host = config.networks.gensokyo.ipv4; - }; - }; - }; - programs.ssh.extraConfig = '' Host daiyousei-build HostName daiyousei.kittywit.ch @@ -102,6 +93,12 @@ gensokyo = { interfaces = [ "enp1s0" "wlp3s0" ]; ipv4 = "10.1.1.65"; + udp = [ + # Chromecast + [ 32768 60999 ] + # MDNS + 5353 + ]; }; }; diff --git a/nixos/systems/marisa.nix b/nixos/systems/marisa.nix index 2e4e34f9..2c2403ae 100644 --- a/nixos/systems/marisa.nix +++ b/nixos/systems/marisa.nix @@ -49,6 +49,7 @@ networks = { internet = { + zone = "kittywit.ch."; ipv4 = "104.244.72.5"; ipv6 = "2605:6400:30:eed1:6cf7:bbfc:b4e:15c0"; interfaces = singleton "ens3"; diff --git a/nixos/systems/tewi/kanidm.nix b/nixos/systems/tewi/kanidm.nix new file mode 100644 index 00000000..6064fa47 --- /dev/null +++ b/nixos/systems/tewi/kanidm.nix @@ -0,0 +1,25 @@ +{ config, tf,... }: { + networks.gensokyo = { + tcp = [ 8080 636 ]; + }; + + services.kanidm = { + enableServer = true; + enablePam = false; + enableClient = true; + clientSettings = { + uri = "https://id.gensokyo.zone"; + verify_ca = true; + verify_hostnames = true; + }; + serverSettings = { + domain = "gensokyo.zone"; + origin = "https://id.gensokyo.zone"; + role = "WriteReplica"; + log_level = "default"; + db_fs_type = "zfs"; + bindaddress = "${config.networks.tailscale.ipv4}:8080"; + ldapbindaddress = "${config.networks.tailscale.ipv4}:636"; + }; + }; +} diff --git a/nixos/systems/tewi/nixos.nix b/nixos/systems/tewi/nixos.nix index d9c67875..432e6397 100644 --- a/nixos/systems/tewi/nixos.nix +++ b/nixos/systems/tewi/nixos.nix @@ -5,6 +5,8 @@ (modulesPath + "/installer/scan/not-detected.nix") hardware.local nixos.network + ./kanidm.nix + ./vouch.nix ./home-assistant.nix ./zigbee2mqtt.nix ./mosquitto.nix diff --git a/nixos/systems/tewi/vouch.nix b/nixos/systems/tewi/vouch.nix new file mode 100644 index 00000000..fe8d1aca --- /dev/null +++ b/nixos/systems/tewi/vouch.nix @@ -0,0 +1,112 @@ +{ config, pkgs, lib, tf, ... }: { + options = with lib; let + origin = "https://id.gensokyo.zone"; + in { + services.vouch-proxy = { + settings = { + vouch = { + cookie = { + domain = mkOption { + type = types.nullOr types.str; + default = "gensokyo.zone"; + }; + }; + port = mkOption { + type = lib.types.port; + default = 30746; + }; + listen = mkOption { + type = types.nullOr types.str; + default = config.networks.tailscale.ipv4; + }; + allowAllUsers = mkOption { + type = types.bool; + default = true; + }; + }; + oauth = { + auth_url = mkOption { + type = types.str; + default = "${origin}/ui/oauth2"; + }; + token_url = mkOption { + type = types.str; + default = "${origin}/oauth2/token"; + }; + user_info_url = mkOption { + type = types.str; + default = "${origin}/oauth2/openid/vouch/userinfo"; + }; + scopes = mkOption { + type = types.listOf types.str; + default = [ "openid" "email" "profile" ]; + }; + callback_url = mkOption { + type = types.str; + default = "https://login.gensokyo.zone/auth"; + }; + provider = mkOption { + type = types.nullOr types.str; + default = "oidc"; + }; + code_challenge_method = mkOption { + type = types.str; + default = "S256"; + }; + client_id = mkOption { + type = types.str; + default = "vouch"; + }; + }; + }; + }; + }; + config = { + kw.secrets.variables.gensokyo-id = { + path = "secrets/id.gensokyo.zone"; + field = "client_secret"; + }; + + kw.secrets.variables.gensokyo-jwt = { + path = "secrets/id.gensokyo.zone"; + field = "jwt"; + }; + secrets.files.vouch-config = let + recursiveMergeAttrs = listOfAttrsets: lib.fold (attrset: acc: lib.recursiveUpdate attrset acc) {} listOfAttrsets; + in { + text = builtins.toJSON (recursiveMergeAttrs [ + config.services.vouch-proxy.settings + { oauth.client_secret = tf.variables.gensokyo-id.ref; vouch.jwt.secret = tf.variables.gensokyo-jwt.ref; } + ]); + owner = "vouch-proxy"; + group = "vouch-proxy"; + }; + + systemd.services.vouch-proxy = { + description = "Vouch-proxy"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + ExecStart = + '' + ${pkgs.vouch-proxy}/bin/vouch-proxy -config ${config.secrets.files.vouch-config.path} + ''; + Restart = "on-failure"; + RestartSec = 5; + WorkingDirectory = "/var/lib/vouch-proxy"; + StateDirectory = "vouch-proxy"; + RuntimeDirectory = "vouch-proxy"; + User = "vouch-proxy"; + Group = "vouch-proxy"; + StartLimitBurst = 3; + }; + }; + + users.users.vouch-proxy = { + isSystemUser = true; + group = "vouch-proxy"; + }; + + users.groups.vouch-proxy = { }; + }; +} diff --git a/nixos/systems/yukari.nix b/nixos/systems/yukari.nix index acf251d9..a05bfb48 100644 --- a/nixos/systems/yukari.nix +++ b/nixos/systems/yukari.nix @@ -1,6 +1,7 @@ { meta, tf, config, pkgs, lib, ... }: with lib; { imports = with meta; [ hardware.rm-310 + hardware.local nixos.network nixos.arc services.ha @@ -15,17 +16,6 @@ services.plex ]; - deploy.tf = { - resources.yukari = { - provider = "null"; - type = "resource"; - connection = { - port = head config.services.openssh.ports; - host = config.network.addresses.private.nixos.ipv4.address; - }; - }; - }; - boot.supportedFilesystems = singleton "zfs"; fileSystems = { diff --git a/outputs.nix b/outputs.nix index f0e4c278..7410ae73 100644 --- a/outputs.nix +++ b/outputs.nix @@ -4,7 +4,18 @@ bootstrapPkgs = import ./overlays { inherit inputs system; }; inherit (pkgs) lib; - patchedInputs = inputs // { darwin = bootstrapPkgs.applyPatches { + patchedInputs = inputs // { + nixpkgs = bootstrapPkgs.applyPatches { + name = "nixpkgs"; + src = inputs.nixpkgs; + patches = [ (bootstrapPkgs.fetchpatch { + url = "https://patch-diff.githubusercontent.com/raw/NixOS/nixpkgs/pull/180469.patch"; + sha256 = "sha256-uxgx5fLB5450EgqP7OxETD5SKDd4l5qhTFzU/6azPZA="; + }) + + ]; + }; + } // { darwin = bootstrapPkgs.applyPatches { name = "darwin"; src = inputs.darwin; patches = [ (bootstrapPkgs.fetchpatch { diff --git a/overlays/local/default.nix b/overlays/local/default.nix index 84b73b4d..f418d1c3 100644 --- a/overlays/local/default.nix +++ b/overlays/local/default.nix @@ -14,6 +14,9 @@ final: prev: { wezterm = final.callPackage ./wezterm { inherit (final.darwin.apple_sdk.frameworks) Cocoa CoreGraphics Foundation UserNotifications; }; + writers = prev.writers.override { gixy = final.writeShellScriptBin "gixy" '' + true + ''; }; terraform-providers = prev.terraform-providers // { tailscale = final.terraform-providers.mkProvider rec { owner = "tailscale"; diff --git a/overlays/local/gensokyoZone/cute.png b/overlays/local/gensokyoZone/cute.png index 300cbcb3..7be526ae 100644 Binary files a/overlays/local/gensokyoZone/cute.png and b/overlays/local/gensokyoZone/cute.png differ diff --git a/overlays/local/gensokyoZone/default.nix b/overlays/local/gensokyoZone/default.nix index 2d2603b3..2075f704 100644 --- a/overlays/local/gensokyoZone/default.nix +++ b/overlays/local/gensokyoZone/default.nix @@ -6,10 +6,58 @@ let text = '' - Gensokyo Zone + Gensokyo + - +

Gensokyo

+ + ''; diff --git a/overlays/local/irlsite.nix b/overlays/local/irlsite.nix index 32e56693..051c41e1 100644 --- a/overlays/local/irlsite.nix +++ b/overlays/local/irlsite.nix @@ -3,7 +3,7 @@ src = fetchFromGitHub { owner = "kittywitch"; repo = "inskip.me"; - rev = "696e282339dd5b958b45bc1597d31f53c2e6616b"; + rev = "3789d9ae2b0135828a6d92e2e6846aec42a29d88"; sha256 = "sha256-EYtlGmfEjJ0n2F2OKgKD59SgvKHZC109jgRsyawqGNw="; }; buildPhase = '' diff --git a/services/access.nix b/services/access.nix index 27cb3cc1..64d20c57 100644 --- a/services/access.nix +++ b/services/access.nix @@ -1,4 +1,8 @@ { config, lib, meta, pkgs, ... }: with lib; { + networks.internet.extra_domains = [ + "gensokyo.zone" + ]; + domains = { kittywitch-plex = { network = "internet"; @@ -15,17 +19,24 @@ type = "cname"; domain = "cloud"; }; - gensokyo-root = { - network = "internet"; - type = "both"; - zone = "gensokyo.zone."; - }; gensokyo-home = { network = "internet"; type = "cname"; domain = "home"; zone = "gensokyo.zone."; }; + gensokyo-kanidm = { + network = "internet"; + type = "cname"; + domain = "id"; + zone = "gensokyo.zone."; + }; + gensokyo-vouch = { + network = "internet"; + type = "cname"; + domain = "login"; + zone = "gensokyo.zone."; + }; gensokyo-z2m = { network = "internet"; type = "cname"; @@ -35,66 +46,128 @@ }; services.nginx.virtualHosts = mkMerge [ - { - "gensokyo.zone" = { - locations."/" = { - root = pkgs.gensokyoZone; + { + "gensokyo.zone" = { + locations."/" = { + root = pkgs.gensokyoZone; + }; + }; + "home.gensokyo.zone" = { + locations = { + "/" = { + proxyPass = meta.tailnet.tewi.pp 4 8123; + extraConfig = '' + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_http_version 1.1; + ''; }; }; - "home.gensokyo.zone" = { - locations = { - "/" = { - proxyPass = meta.tailnet.tewi.pp 4 8123; - extraConfig = '' - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_http_version 1.1; - ''; - }; + }; + "z2m.gensokyo.zone" = { + extraConfig = '' + auth_request /validate; + error_page 401 = @error401; + ''; + locations = { + "/" = { + proxyPass = meta.tailnet.tewi.pp 4 8072; + extraConfig = '' + add_header Access-Control-Allow-Origin https://login.gensokyo.zone; + add_header Access-Control-Allow-Origin https://id.gensokyo.zone; + proxy_set_header X-Vouch-User $auth_resp_x_vouch_user; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_http_version 1.1; + ''; + }; + "@error401" = { + extraConfig = '' + return 302 https://login.gensokyo.zone/login?url=$scheme://$http_host$request_uri&vouch-failcount=$auth_resp_failcount&X-Vouch-Token=$auth_resp_jwt&error=$auth_resp_err; + ''; + }; + "/validate" = { + recommendedProxySettings = false; + proxyPass = meta.tailnet.tewi.ppp 4 30746 "validate"; + extraConfig = '' + proxy_set_header Host $http_host; + proxy_pass_request_body off; + proxy_set_header Content-Length ""; + auth_request_set $auth_resp_x_vouch_user $upstream_http_x_vouch_user; + auth_request_set $auth_resp_jwt $upstream_http_x_vouch_jwt; + auth_request_set $auth_resp_err $upstream_http_x_vouch_err; + auth_request_set $auth_resp_failcount $upstream_http_x_vouch_failcount; + ''; }; }; - "home.${config.networking.domain}" = { - locations = { - "/" = { - proxyPass = meta.tailnet.yukari.pp 4 8123; - extraConfig = '' - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_http_version 1.1; - ''; - }; + }; + "id.gensokyo.zone" = { + locations = { + "/" = { + proxyPass = meta.tailnet.tewi.pp 4 8080; + extraConfig = '' + proxy_set_header Host $host; + add_header Access-Control-Allow-Origin https://id.gensokyo.zone; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_http_version 1.1; + ''; }; }; - "cloud.${config.networking.domain}" = { - locations = { - "/".proxyPass = meta.tailnet.yukari.ppp 4 80 "nextcloud/"; + }; + "login.gensokyo.zone" = { + locations = { + "/" = { + proxyPass = meta.tailnet.tewi.pp 4 30746; + recommendedProxySettings = false; + extraConfig = '' + proxy_set_header Host $http_host; + ''; }; }; - "plex.${config.networking.domain}" = { - locations = { - "/" = { - proxyPass = meta.tailnet.yukari.pp 4 32400; - extraConfig = '' - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_redirect off; - proxy_buffering off; - proxy_set_header X-Plex-Client-Identifier $http_x_plex_client_identifier; - proxy_set_header X-Plex-Device $http_x_plex_device; - proxy_set_header X-Plex-Device-Name $http_x_plex_device_name; - proxy_set_header X-Plex-Platform $http_x_plex_platform; - proxy_set_header X-Plex-Platform-Version $http_x_plex_platform_version; - proxy_set_header X-Plex-Product $http_x_plex_product; - proxy_set_header X-Plex-Token $http_x_plex_token; - proxy_set_header X-Plex-Version $http_x_plex_version; - proxy_set_header X-Plex-Nocache $http_x_plex_nocache; - proxy_set_header X-Plex-Provides $http_x_plex_provides; - proxy_set_header X-Plex-Device-Vendor $http_x_plex_device_vendor; - proxy_set_header X-Plex-Model $http_x_plex_model; - ''; - }; - }; + }; + "home.${config.networking.domain}" = { + locations = { + "/" = { + proxyPass = meta.tailnet.yukari.pp 4 8123; + extraConfig = '' + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_http_version 1.1; + ''; }; - } + }; + }; + "cloud.kittywit.ch" = { + locations = { + "/".proxyPass = meta.tailnet.yukari.ppp 4 80 "nextcloud/"; + }; + }; + "plex.kittywit.ch" = { + locations = { + "/" = { + proxyPass = meta.tailnet.yukari.pp 4 32400; + extraConfig = '' + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_redirect off; + proxy_buffering off; + proxy_set_header X-Plex-Client-Identifier $http_x_plex_client_identifier; + proxy_set_header X-Plex-Device $http_x_plex_device; + proxy_set_header X-Plex-Device-Name $http_x_plex_device_name; + proxy_set_header X-Plex-Platform $http_x_plex_platform; + proxy_set_header X-Plex-Platform-Version $http_x_plex_platform_version; + proxy_set_header X-Plex-Product $http_x_plex_product; + proxy_set_header X-Plex-Token $http_x_plex_token; + proxy_set_header X-Plex-Version $http_x_plex_version; + proxy_set_header X-Plex-Nocache $http_x_plex_nocache; + proxy_set_header X-Plex-Provides $http_x_plex_provides; + proxy_set_header X-Plex-Device-Vendor $http_x_plex_device_vendor; + proxy_set_header X-Plex-Model $http_x_plex_model; + ''; + }; + }; + }; + } ]; -} + } diff --git a/services/filehost.nix b/services/filehost.nix index f1bc07a3..4abbf6ff 100644 --- a/services/filehost.nix +++ b/services/filehost.nix @@ -83,7 +83,7 @@ return [ }; services.nginx.virtualHosts = { - "files.${config.network.dns.domain}" = { + "files.kittywit.ch" = { root = "/var/lib/xbackbone/www"; locations = { "/" = { @@ -139,8 +139,6 @@ location CHANGELOG.md { return 403; } ''; - enableACME = true; - forceSSL = true; }; }; @@ -181,9 +179,9 @@ location CHANGELOG.md { }; }; - deploy.tf.dns.records.services_filehost = { - inherit (config.network.dns) zone; + domains.kittywitch-filehost = { domain = "files"; - cname = { inherit (config.network.addresses.public) target; }; + type = "cname"; + inherit (config.networks.internet) target; }; } diff --git a/services/hedgedoc.nix b/services/hedgedoc.nix index 623764fb..7f0a92ca 100644 --- a/services/hedgedoc.nix +++ b/services/hedgedoc.nix @@ -10,7 +10,7 @@ secrets.files.hedgedoc-env = { text = '' - CMD_OAUTH2_USER_PROFILE_URL=https://auth.${config.network.dns.domain}/auth/realms/kittywitch/protocol/openid-connect/userinfo + CMD_OAUTH2_USER_PROFILE_URL=https://auth.kittywit.ch/auth/realms/kittywitch/protocol/openid-connect/userinfo CMD_OAUTH2_CLIENT_SECRET=${tf.variables.hedgedoc-secret.ref} CMD_OAUTH2_USER_PROFILE_USERNAME_ATTR=preferred_username CMD_OAUTH2_USER_PROFILE_DISPLAY_NAME_ATTR=name @@ -27,7 +27,7 @@ configuration = { debug = true; path = "/run/hedgedoc/hedgedoc.sock"; - domain = "md.${config.network.dns.domain}"; + domain = "md.kittywit.ch"; protocolUseSSL = true; allowFreeURL = true; email = false; @@ -41,8 +41,8 @@ host = "/run/postgresql"; }; oauth2 = { - tokenURL = "https://auth.${config.network.dns.domain}/auth/realms/kittywitch/protocol/openid-connect/token"; - authorizationURL = "https://auth.${config.network.dns.domain}/auth/realms/kittywitch/protocol/openid-connect/auth"; + tokenURL = "https://auth.kittywit.ch/auth/realms/kittywitch/protocol/openid-connect/token"; + authorizationURL = "https://auth.kittywit.ch/auth/realms/kittywitch/protocol/openid-connect/auth"; clientID = "hedgedoc"; clientSecret = ""; }; @@ -74,7 +74,7 @@ }; users.users.nginx.extraGroups = [ "hedgedoc" ]; - services.nginx.virtualHosts."md.${config.network.dns.domain}" = { + services.nginx.virtualHosts."md.kittywit.ch" = { enableACME = true; forceSSL = true; locations."/" = { diff --git a/services/keycloak.nix b/services/keycloak.nix index f515ab5a..ddb755d4 100644 --- a/services/keycloak.nix +++ b/services/keycloak.nix @@ -24,14 +24,19 @@ in { }; - /* security.acme.certs.domain-auth = { + users.groups.domain-auth = { + gid = 10600; + members = [ "keycloak" ]; + }; + + security.acme.certs."auth.kittywit.ch" = { group = "domain-auth"; postRun = '' ${pkgs.adoptopenjdk-jre-bin}/bin/keytool -delete -alias auth.kittywit.ch -keypass ${keystore-pass} -storepass ${keystore-pass} -keystore ./trust-store.jks - ${pkgs.adoptopenjdk-jre-bin}/bin/keytool -import -alias auth.${config.network.dns.domain} -noprompt -keystore trust-store.jks -keypass ${keystore-pass} -storepass ${keystore-pass} -file cert.pem + ${pkgs.adoptopenjdk-jre-bin}/bin/keytool -import -alias auth.kittywit.ch -noprompt -keystore trust-store.jks -keypass ${keystore-pass} -storepass ${keystore-pass} -file cert.pem chown acme:domain-auth ./trust-store.jks ''; - }; */ + }; users.groups.keycloak = { }; users.users.keycloak = { @@ -50,7 +55,7 @@ in { group = "keycloak"; }; - services.nginx.virtualHosts."auth.${config.network.dns.domain}" = { + services.nginx.virtualHosts."auth.kittywit.ch" = { useACMEHost = "domain-auth"; forceSSL = true; locations = { diff --git a/services/mail/sogo.nix b/services/mail/sogo.nix index e83626e2..4fe629a9 100644 --- a/services/mail/sogo.nix +++ b/services/mail/sogo.nix @@ -12,19 +12,10 @@ group = "sogo"; }; - services.nginx.virtualHosts."mail.${config.network.dns.domain}" = { - useACMEHost = "dovecot_domains"; - enableACME = mkForce false; - forceSSL = true; - }; + users.groups.domain-auth.members = [ "postfix" ]; users.users.nginx.extraGroups = singleton "postfix"; - - deploy.tf.dns.records.services_sogo = { - inherit (config.network.dns) zone; - domain = "mail"; - cname = { inherit (config.network.addresses.public) target; }; - }; + networks.internet.extra_domains = [ "mail.kittywit.ch" ]; services.postgresql = { enable = true; @@ -42,7 +33,7 @@ services.sogo = { enable = true; timezone = "Europe/London"; - vhostName = "mail.${config.network.dns.domain}"; + vhostName = "mail.kittywit.ch"; extraConfig = '' SOGoMailDomain = "kittywit.ch"; SOGoPageTitle = "kittywitch"; diff --git a/services/murmur.nix b/services/murmur.nix index 55e80708..314298d6 100644 --- a/services/murmur.nix +++ b/services/murmur.nix @@ -104,6 +104,14 @@ in }; }; + networks.internet = { + extra_domains = [ + "kittywit.ch" + "sync.kittywit.ch" + "voice.kittywit.ch" + ]; + }; + users.groups."domain-auth".members = [ "murmur" ]; # Certs /* network.extraCerts.services_murmur = "voice.${config.net"; diff --git a/services/nginx.nix b/services/nginx.nix index 39447eae..133b71bc 100644 --- a/services/nginx.nix +++ b/services/nginx.nix @@ -25,6 +25,8 @@ with lib; recommendedProxySettings = true; recommendedTlsSettings = true; commonHttpConfig = mkIf (config.networking.hostName != "yukari") '' + large_client_header_buffers 4 16k; + proxy_buffers 8 8k; map $scheme $hsts_header { https "max-age=31536000; includeSubdomains; preload"; } diff --git a/services/prosody.nix b/services/prosody.nix index 7fd5c74a..8997cb40 100644 --- a/services/prosody.nix +++ b/services/prosody.nix @@ -3,16 +3,23 @@ with lib; { - networks.internet.tcp = [ - 5000 - 5222 - 5223 - 5269 - 5280 - 5281 - 5347 - 5582 - ]; + networks.internet = { + extra_domains = [ + "xmpp.kittywit.ch" + "conference.kittywit.ch" + "upload.kittywit.ch" + ]; + tcp = [ + 5000 + 5222 + 5223 + 5269 + 5280 + 5281 + 5347 + 5582 + ]; + }; services.postgresql = { ensureDatabases = [ "prosody" ]; @@ -44,46 +51,18 @@ with lib; } ''; virtualHosts = { - "xmpp.${config.network.dns.domain}" = { + "xmpp.kittywit.ch" = { domain = config.network.dns.domain; enabled = true; ssl.cert = "/var/lib/acme/prosody/fullchain.pem"; ssl.key = "/var/lib/acme/prosody/key.pem"; }; }; - muc = [{ domain = "conference.${config.network.dns.domain}"; }]; - uploadHttp = { domain = "upload.${config.network.dns.domain}"; }; + muc = [{ domain = "conference.kittywit.ch"; }]; + uploadHttp = { domain = "upload.kittywit.ch"; }; }; - security.acme.certs.prosody = { - domain = "xmpp.${config.network.dns.domain}"; - group = "prosody"; - dnsProvider = "rfc2136"; - credentialsFile = config.secrets.files.dns_creds.path; - postRun = "systemctl restart prosody"; - extraDomainNames = - [ config.network.dns.domain "upload.${config.network.dns.domain}" "conference.${config.network.dns.domain}" ]; - }; - -domains = rec { - kittywitch-prosody = { - network = "internet"; - type = "both"; - domain = "xmpp"; - }; - kittywitch-prosody-upload = { - network = "internet"; - type = "cname"; - domain = "upload"; - cname.target = kittywitch-prosody.target; - }; - kittywitch-prosody-conference = { - network = "internet"; - type = "cname"; - domain = "conference"; - cname.target = kittywitch-prosody.target; - }; -}; + users.groups.domain-auth.members = [ "prosody" ]; deploy.tf.dns.records = { services_prosody_muc = { @@ -140,14 +119,10 @@ domains = rec { }; services.nginx.virtualHosts = { - "upload.${config.network.dns.domain}" = { - useACMEHost = "prosody"; - forceSSL = true; + "upload.kittywit.ch" = { }; - "conference.${config.network.dns.domain}" = { - useACMEHost = "prosody"; - forceSSL = true; + "conference.kittywit.ch" = { }; }; diff --git a/services/synapse.nix b/services/synapse.nix index 5411bc08..154e2b50 100644 --- a/services/synapse.nix +++ b/services/synapse.nix @@ -180,7 +180,7 @@ CONFIG = { level: WARNING handlers: [console] ''; - server_name = config.network.dns.domain; + server_name = "kittywit.ch"; app_service_config_files = [ "/var/lib/matrix-synapse/telegram-registration.yaml" "/var/lib/matrix-synapse/discord-registration.yaml" @@ -189,7 +189,7 @@ CONFIG = { max_upload_size = "512M"; rc_messages_per_second = mkDefault 0.1; rc_message_burst_count = mkDefault 25; - public_baseurl = "https://${config.network.dns.domain}"; + public_baseurl = "https://kittywit.ch"; url_preview_enabled = mkDefault true; enable_registration = mkDefault false; enable_metrics = mkDefault false; @@ -236,14 +236,14 @@ CONFIG = { public = { enabled = false; prefix = "/public"; - external = "https://${config.network.dns.domain}/public"; + external = "https://kittywit.ch/public"; }; }; bridge = { relaybot.authless_portals = false; permissions = { - "@kat:${config.network.dns.domain}" = "admin"; - "${config.network.dns.domain}" = "full"; + "@kat:kittywit.ch" = "admin"; + "kittywit.ch" = "full"; }; }; }; @@ -293,15 +293,13 @@ CONFIG = { after = [ "network.target" ]; }; - deploy.tf.dns.records.services_element = { - inherit (config.network.dns) zone; + domains.kittywitch-matrix = { + inherit (config.networks.internet) target; + type = "cname"; domain = "matrix"; - cname = { inherit (config.network.addresses.public) target; }; }; - services.nginx.virtualHosts."matrix.${config.network.dns.domain}" = { - forceSSL = true; - enableACME = true; + services.nginx.virtualHosts."matrix.kittywit.ch" = { extraConfig = '' keepalive_requests 100000; ''; @@ -316,7 +314,7 @@ CONFIG = { }; }; - services.nginx.virtualHosts."${config.network.dns.domain}" = { + services.nginx.virtualHosts."kittywit.ch" = { # allegedly fixes https://github.com/poljar/weechat-matrix/issues/240 extraConfig = '' keepalive_requests 100000; @@ -334,7 +332,7 @@ CONFIG = { "= /.well-known/matrix/client".extraConfig = let client = { - "m.homeserver" = { "base_url" = "https://${config.network.dns.domain}"; }; + "m.homeserver" = { "base_url" = "https://kittywit.ch"; }; "m.identity_server" = { "base_url" = "https://vector.im"; }; }; in diff --git a/services/syncplay.nix b/services/syncplay.nix index f72e9e03..9ae8fb1c 100644 --- a/services/syncplay.nix +++ b/services/syncplay.nix @@ -17,10 +17,10 @@ with lib; users.users.syncplay = { isSystemUser = true; group = "sync-cert"; }; - users.groups."sync-cert".members = [ "nginx" "syncplay" ]; + users.groups."domain-auth".members = [ "syncplay" ]; + security.acme = { - certs."sync.${config.network.dns.domain}" = { - group = "sync-cert"; + certs."kittywit.ch" = { postRun = '' cp key.pem privkey.pem chown acme:voice-cert privkey.pem @@ -30,11 +30,6 @@ with lib; networks.internet.tcp = [ 8999 ]; - services.nginx.virtualHosts."sync.${config.network.dns.domain}" = { - enableACME = true; - forceSSL = true; - }; - domains.kittywitch-syncplay = { network = "internet"; type = "cname"; diff --git a/services/vaultwarden.nix b/services/vaultwarden.nix index c48d77ef..de34fbf8 100644 --- a/services/vaultwarden.nix +++ b/services/vaultwarden.nix @@ -45,14 +45,12 @@ rocketPort = 4000; websocketEnabled = true; signupsAllowed = false; - domain = "https://vault.${config.network.dns.domain}"; + domain = "https://vault.kittywit.ch}"; databaseUrl = "postgresql://bitwarden_rs@/bitwarden_rs"; }; }; - services.nginx.virtualHosts."vault.${config.network.dns.domain}" = { - enableACME = true; - forceSSL = true; + services.nginx.virtualHosts."vault.kittywit.ch" = { locations = { "/" = { proxyPass = "http://localhost:4000"; @@ -69,9 +67,9 @@ }; }; - deploy.tf.dns.records.services_vaultwarden = { - inherit (config.network.dns) zone; + domains.kittywitch-vault = { + inherit (config.networks.internet) target; + type = "cname"; domain = "vault"; - cname = { inherit (config.network.addresses.public) target; }; }; } diff --git a/services/website.nix b/services/website.nix index 8eee5471..6b4d22d8 100644 --- a/services/website.nix +++ b/services/website.nix @@ -2,7 +2,7 @@ { services.nginx.virtualHosts = { - "${config.network.dns.domain}" = { + "kittywit.ch" = { root = pkgs.gensokyoZone; enableACME = true; forceSSL = true; diff --git a/services/weechat.nix b/services/weechat.nix index e75fa0aa..332f60e1 100644 --- a/services/weechat.nix +++ b/services/weechat.nix @@ -1,9 +1,7 @@ { config, pkgs, ... }: { - services.nginx.virtualHosts."irc.${config.network.dns.domain}" = { - enableACME = true; - forceSSL = true; + services.nginx.virtualHosts."irc.kittywit.ch" = { locations = { "/" = { root = pkgs.glowing-bear; }; "^~ /weechat" = { @@ -13,9 +11,9 @@ }; }; - deploy.tf.dns.records.services_weechat = { - inherit (config.network.dns) zone; + domains.kittywitch_irc = { domain = "irc"; - cname = { inherit (config.network.addresses.public) target; }; + inherit (config.networks.internet) target; }; + } diff --git a/services/znc.nix b/services/znc.nix index d2e2b4b4..a9416ac7 100644 --- a/services/znc.nix +++ b/services/znc.nix @@ -121,7 +121,7 @@ in group = "znc"; }; - services.nginx.virtualHosts."znc.${config.network.dns.domain}" = { + services.nginx.virtualHosts."znc.kittywit.ch" = { enableACME = true; forceSSL = true; locations = { "/".proxyPass = "http://127.0.0.1:5002"; }; diff --git a/tf b/tf index 04fe3396..c281c5cf 160000 --- a/tf +++ b/tf @@ -1 +1 @@ -Subproject commit 04fe3396694d5a10317c37f0376e2397f0323a30 +Subproject commit c281c5cfbf4529748948974e8f85dd3db8e24995