{ description = "tsnet-proxy: proxy onto tsnet"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; }; outputs = { self, nixpkgs, systems, }: let eachSystem = f: nixpkgs.lib.genAttrs (import systems) (system: f rec { inherit system; pkgs = nixpkgs.legacyPackages.${system}; inherit (pkgs) callPackage; }); in { packages = eachSystem ({callPackage, ...}: { default = callPackage ./. {}; }); devShells = eachSystem ({callPackage, ...}: { default = callPackage ./shell.nix {}; }); nixosModules.default = { config, pkgs, lib, ... }: { options.services.bluepython508.tsnet-proxy = with lib; with types; { clientId = mkOption { type = str; }; clientSecretFile = mkOption { type = str; }; tags = mkOption {type = listOf str;}; proxies = mkOption { type = attrsOf (submodule ({config, ...}: { options = let proto = enum ["udp" "tcp" "unix"]; in { enable = mkOption { type = bool; default = true; }; proto = mkOption {type = proto;}; dest = mkOption {type = str;}; hostProto = mkOption {type = proto;}; port = mkOption {type = port;}; }; config.hostProto = mkDefault config.proto; })); }; }; config.systemd.services = let cfg = config.services.bluepython508.tsnet-proxy; get-authkey = pkgs.tailscale.overrideAttrs { subPackages = ["cmd/get-authkey"]; postInstall = ""; }; in lib.mapAttrs' (hostname: { proto, hostProto, port, dest, enable, ... }: let name = "tsnet-proxy-${hostname}"; in { inherit name; value = { inherit enable; script = '' TS_AUTHKEY=$(cat $RUNTIME_DIRECTORY/authkey) ${lib.getExe self.packages.${pkgs.system}.default} ${hostProto} ${hostname} ${toString port} ${proto} ${dest} ''; wantedBy = ["multi-user.target"]; serviceConfig = { DynamicUser = true; RuntimeDirectory = name; ExecStartPre = "!${pkgs.writeShellScript "get-authkey" '' TS_API_CLIENT_ID=${cfg.clientId} TS_API_CLIENT_SECRET=$(cat ${cfg.clientSecretFile}) ${get-authkey}/bin/get-authkey -ephemeral -tags ${lib.concatStringsSep "," cfg.tags} > $RUNTIME_DIRECTORY/authkey chown ${name}:${name} $RUNTIME_DIRECTORY/authkey ''}"; }; }; }) cfg.proxies; }; }; }