diff --git a/tewi/cloudflared.nix b/tewi/cloudflared.nix index 2fa7fc2c..06b7f848 100644 --- a/tewi/cloudflared.nix +++ b/tewi/cloudflared.nix @@ -1,20 +1,30 @@ -{ config, lib, ... }: let - inherit (lib) mapAttrs' nameValuePair splitString last; +{ pkgs, config, utils, lib, ... }: let + inherit (lib) mapAttrsToList mapAttrs' nameValuePair splitString last singleton + mkIf mkMerge mkForce; inherit (config) services; inherit (services.kanidm.serverSettings) domain; + cfg = services.cloudflared; + apartment = "131222b0-9db0-4168-96f5-7d45ec51c3be"; + shadowTunnel = { + ${apartment}.ingress.deluge = { + hostname._secret = config.sops.secrets.cloudflared-tunnel-apartment-deluge.path; + service = "http://localhost:${toString services.deluge.web.port}"; + }; + }; in { sops.secrets.cloudflared-tunnel-apartment.owner = services.cloudflared.user; + sops.secrets.cloudflared-tunnel-apartment-deluge.owner = services.cloudflared.user; services.cloudflared = { enable = true; tunnels = { - "131222b0-9db0-4168-96f5-7d45ec51c3be" = { + ${apartment} = { credentialsFile = config.sops.secrets.cloudflared-tunnel-apartment.path; default = "http_status:404"; ingress = mapAttrs' (prefix: nameValuePair "${prefix}${domain}") { - "" = "http://localhost:80"; - "home." = "http://localhost:${toString services.home-assistant.config.http.server_port}"; - "z2m." = "http://localhost:80"; - "login." = "http://localhost:${toString services.vouch-proxy.settings.vouch.port}"; + "".service = "http://localhost:80"; + "home.".service = "http://localhost:${toString services.home-assistant.config.http.server_port}"; + "z2m.".service = "http://localhost:80"; + "login.".service = "http://localhost:${toString services.vouch-proxy.settings.vouch.port}"; "id." = let inherit (services.kanidm.serverSettings) bindaddress; port = last (splitString ":" bindaddress); @@ -26,4 +36,40 @@ in { }; }; }; + systemd.services = let + filterConfig = lib.filterAttrsRecursive (_: v: ! builtins.elem v [ null [ ] { } ]); + mapIngress = hostname: ingress: { + inherit hostname; + } // filterConfig (filterConfig ingress); + in mkIf cfg.enable (mapAttrs' (uuid: tunnel: let + RuntimeDirectory = "cloudflared-tunnel-${uuid}"; + configPath = "/run/${RuntimeDirectory}/config.yml"; + settings = { + tunnel = uuid; + credentials-file = tunnel.credentialsFile; + ingress = mapAttrsToList mapIngress tunnel.ingress + ++ mapAttrsToList mapIngress shadowTunnel.${uuid}.ingress or { } + ++ singleton { service = tunnel.default; }; + }; + in nameValuePair "cloudflared-tunnel-${uuid}" (mkMerge [ + { + after = [ "tailscale-autoconnect.service" ]; + serviceConfig = { + RestartSec = 10; + }; + } + (mkIf (shadowTunnel.${uuid} or { } != { }) { + serviceConfig = { + inherit RuntimeDirectory; + ExecStart = mkForce [ + "${cfg.package}/bin/cloudflared tunnel --config=${configPath} --no-autoupdate run" + ]; + ExecStartPre = [ + (pkgs.writeShellScript "cloudflared-tunnel-${uuid}-prepare" '' + ${utils.genJqSecretsReplacementSnippet settings configPath} + '') + ]; + }; + }) + ])) cfg.tunnels); } diff --git a/tewi/secrets.yaml b/tewi/secrets.yaml index d85fc5cb..be8ff030 100644 --- a/tewi/secrets.yaml +++ b/tewi/secrets.yaml @@ -13,6 +13,7 @@ deluge-auth: ENC[AES256_GCM,data:qJP/CztnN7RV4Z3pP+jbH1B0zzBm8oa3n3X0pecEVe7UI3+ syncplay-env: ENC[AES256_GCM,data:MzL/Q4ihwVX+QgdWl20PfpCP8hiPd3uc00FuTJ+gsVN7EJOoDlTyA2pgfw75eklQgWa0r9T+3u3gigo7jxrBqmgD2oYDFrZNKrHyrXlxALQ=,iv:AO7hcXucPqJkCa3u3Y7nrgfIsw9f8fbWBc5g7Kb77cM=,tag:G+URgzoVrwiS6TjEgRy9rg==,type:str] ha-secrets: ENC[AES256_GCM,data:sw+sxrDyNIOAkHSA2fPLqtHR32iKIaZDdgJ1ZcQTeOqlgdZDhK5XzXiBkpZBTwKswUc2UPDOANsn+YRusX2tUvLYjdxZz4jIBKJuaW3aEtOcxjmG55KYxHmTzSbR4IhpuZ+1wDhvp4UiUqyD273Lt6LTFDmohZAVqwxJc2k4YTZJXiofVf8ywcXPMcS+zIMxb5nBX9EJqgJ80pnBI8vZeCg4pFv/Ux2OoS+PTnkYHnsywf57NA23YcKqnsbJoZwi3e4ooM2erygv0DuoP7QBnBdEf5RKSziECDTDPUFQVNYIOEAgJIYOD/GtZmWMx4SadsmrgTB1RqtAdPnvuuD3jLYW20zci8CxmI4F/h/+8lxUH/TGiG2bUmPYvwTE1eW1cLK91XhxXp6ORyWMGYcR98ryGL00ctD/BaZLdk7FYbQMTF2y2vx5vWAABTnYLsv6H9csmD4O7OeNkd9k+YQB/atENAXRgIiGDvkkbNoRkRU5SzIIHGcjjU7GC6hT+LDportPuhUW+g6KJj0ENOCI0yXNkIfa6LXAJcCmdovJCIbdw1HCGHuu+dc5rSWueiOWo+2rr8loytZTTMwevTaldfrNyu42K+bZI2BkPdXzkPQDeV8y5PmfnXfdXthmmnZbYRyVYUd1OH9L,iv:zxpazCPJTWmuw7/BNj90G89aGyk3fCqBB+RCyKW6QwY=,tag:5zSnrZOxo8G2Wg4LNtEsaQ==,type:str] cloudflared-tunnel-apartment: ENC[AES256_GCM,data:ccqV0jqrnbSz/r+C8v5FTWCtWVDHNdMwhiYHmjyrSLRt0xlcfSzqLhlTPMOfcEcded/NgiM9x3KrLm3hjW8GJpnaPGmQhP4GwBFEJ81R7dzXwpzbj0jbkj/sxxE7MEyofxfF+H2g5Kk55Yu148thxOB5Q4w2c6ZT16bHEXD20Cr88+T8chKQycfCWec0tE1WGmJYM3yrnaNvaey4oh4YWl+RApzxuA==,iv:KNjWDOF6PV8SVmXwzgom3wI+mjfnUSAzyuVIkDMgWHI=,tag:q9wOCGsXF5BOKEnt8jEAog==,type:str] +cloudflared-tunnel-apartment-deluge: ENC[AES256_GCM,data:BG4ak9wQQjDanJ+RqI33PrAx8g==,iv:s1c/6pWQZim73VjLiJmvR2ly7ktAQf7rJ6Yx34EFddo=,tag:nNu/Re0U5HJSb8JLFu2NMA==,type:str] ha-integration: ENC[AES256_GCM,data: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,iv:tRzbBW/YFMp2vw26M9ediGY49GuxvyV2ijZ1W7mjURQ=,tag:L4ACYnVzdarztrjlsX3cAQ==,type:str] sops: shamir_threshold: 1 @@ -39,8 +40,8 @@ sops: VndVTG0zQWhsUHcwTkFjK2ZPdzRPUUEKJ3flgZ6/s+TjlFgzsANYaOFiEPQuE4zR 7npNUDFLe26Q32G3j/lLSBzZZfKoOC5SOSp9TB8eWMYSxfNnXEIu0g== -----END AGE ENCRYPTED FILE----- - lastmodified: "2023-06-04T19:13:59Z" - mac: ENC[AES256_GCM,data:TeOARJG8rQN4AjY/jYX5zlba1Kt8Zu8bYg6csdjprjivFXn6sXSJbjmizSxZAMQM+CfE944PT7iKigQpdLJSftqeYRAaQ57sWnbUtKzOguGFrXlP5NqLyBwSvFCk6mtE2gtf/BNyNF2dY3Ns3RKy4BkkTysieK71ggSGnFVjZHQ=,iv:J5TVUlJqJAVpxeUayd88+sZ9WIo3fg7RXYp3zgRFEZ4=,tag:SstL6gpB0jYf9gBzlru0fw==,type:str] + lastmodified: "2023-07-11T18:05:23Z" + mac: ENC[AES256_GCM,data:97lA3tTSp8jm8bFoDM/HiNY4mLOCDB5DxewXH49iUNshkGNylYjSb9I0L2m8Se1/yA6QKlHJKkSq2dtqFIXO/ANaHzRTTnR1D6jjh+2AYsbKZUhMXKLaC7HTSWoj/SkvHlgzznz1xSz8iWZXoIzRMpwRHk56TlPejbxJ+UzNWqc=,iv:y7VSWBQcV1fcdirtouQmpD6gxl6dkUddwnzKvG2dka0=,tag:elpRiXRvjmuIMgQexgMwWg==,type:str] pgp: - created_at: "2023-03-10T17:06:53Z" enc: |