tailproxy @main -
refs -
log -
-
https://git.jolheiser.com/tailproxy.git
Signature
-----BEGIN SSH SIGNATURE-----
U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgBTEvCQk6VqUAdN2RuH6bj1dNkY
oOpbPWj+jw4ua1B1cAAAADZ2l0AAAAAAAAAAZzaGE1MTIAAABTAAAAC3NzaC1lZDI1NTE5
AAAAQK5S4ZMXYP58rk7xe3pcTIv5gB5Hn8f6ucy8IFtpbD6HLzkbooF9pMTCWBcP+KFFOq
rm1lnIvs8YT7Uzk788ywI=
-----END SSH SIGNATURE-----
diff --git a/nix/module.nix b/nix/module.nix
index adac61afca46731122a75d9e3b53480f68657ca4..1734e9fc5e8d0ee80bbd11946acd403a3de70b9c 100644
--- a/nix/module.nix
+++ b/nix/module.nix
@@ -7,15 +7,14 @@ }:
let
cfg = config.services.tailproxy;
pkg = pkgs.callPackage ./pkg.nix { inherit pkgs; };
-in
-{
- options =
+ instanceOptions =
+ { name, config, ... }:
let
inherit (lib) mkEnableOption mkOption types;
in
{
- services.tailproxy = {
- enable = mkEnableOption "Enable tailproxy";
+ options = {
+ enable = mkEnableOption "Enable tailproxy for ${name}";
package = mkOption {
type = types.package;
@@ -23,29 +22,32 @@ description = "tailproxy package to use";
default = pkg;
};
- hostname = mkOption {
- type = types.str;
- description = "Tailscale hostname";
- };
- auth-key = mkOption {
- type = types.str;
- description = "Tailscale auth key";
- };
- funnel = mkOption {
- type = types.bool;
- description = "Expose on Tailscale funnel";
- };
- data-dir = mkOption {
- type = types.str;
- description = "tsnet data directory";
- default = ".tailproxy";
-
- };
- port = mkOption {
- type = types.int;
- description = "Port to proxy";
- };
-
+ hostname = mkOption {
+ type = types.str;
+ description = "Tailscale hostname";
+ };
+
+ auth-key = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ description = "Tailscale auth key";
+ };
+
+ funnel = mkOption {
+ type = types.bool;
+ description = "Expose on Tailscale funnel";
+ };
+
+ data-dir = mkOption {
+ type = types.str;
+ description = "tsnet data directory";
+ default = "/var/lib/tailproxy-${name}";
+ };
+
+ port = mkOption {
+ type = types.int;
+ description = "Port to proxy";
+ };
user = mkOption {
type = types.str;
@@ -60,46 +62,55 @@ description = "Group account under which tailproxy runs";
};
};
};
- config = lib.mkIf cfg.enable {
- users.users."${cfg.user}" = {
- home = "/var/lib/tailproxy";
- createHome = true;
- group = "${cfg.group}";
- isSystemUser = true;
- isNormalUser = false;
- description = "user for tailproxy service";
+in
+{
+ options = {
+ services.tailproxy = lib.mkOption {
+ type = lib.types.attrsOf (lib.types.submodule instanceOptions);
+ default = { };
+ description = "Attribute set of tailproxy instances";
};
- users.groups."${cfg.group}" = { };
-
- systemd.services = {
- tailproxy = {
- enable = true;
- script =
- let
- args = [
- "--hostname=${cfg.hostname}"
- "--auth-key=${cfg.auth-key}"
- "--funnel=${cfg.funnel}"
- "--data-dir=${cfg.data-dir}"
- "--port=${cfg.port}"
-
- ];
- in
- "${cfg.package}/bin/tailproxyd ${builtins.concatStringsSep " " args}";
+ };
+ config = lib.mkIf (cfg.instances != { }) {
+ systemd.services = lib.mapAttrs' (
+ name: instanceCfg:
+ lib.nameValuePair "tailproxy-${name}" {
+ description = "tailproxy-${name}";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
- path = [
- cfg.package
- ];
serviceConfig = {
- User = cfg.user;
- Group = cfg.group;
- Restart = "always";
- RestartSec = "15";
- WorkingDirectory = "/var/lib/tailproxy";
+ ExecStart =
+ let
+ args =
+ lib.optionals (instanceCfg.auth-key != null) [
+ "--auth-key=${instanceCfg.auth-key}"
+ ]
+ ++ [
+ (lib.optionalString instanceCfg.funnel "--funnel")
+ "--hostname=${instanceCfg.hostname}"
+ "--port=${builtins.toString instanceCfg.port}"
+ "--data-dir=${instanceCfg.data-dir}"
+ ];
+ in
+ "${instanceCfg.package}/bin/tailproxy ${lib.concatStringsSep " " args}";
+ User = instanceCfg.user;
+ Restart = "on-failure";
};
- };
- };
+ }
+ ) (lib.filterAttrs (name: instanceCfg: instanceCfg.enable) cfg.instances);
+
+ users.users = lib.mapAttrs' (
+ name: instanceCfg:
+ lib.nameValuePair instanceCfg.user {
+ isSystemUser = true;
+ group = instanceCfg.user;
+ home = instanceCfg.data-dir;
+ createHome = true;
+ }
+ ) (lib.filterAttrs (name: instanceCfg: instanceCfg.enable) cfg.instances);
+
+ users.groups = lib.mapAttrs' (name: instanceCfg: lib.nameValuePair instanceCfg.user { }) (
+ lib.filterAttrs (name: instanceCfg: instanceCfg.enable) cfg.instances
+ );
};
}
-