From 24897193b31bc7cc5515408c1113240561585015 Mon Sep 17 00:00:00 2001 From: Aaron Bieber Date: Thu, 1 Dec 2022 21:00:23 -0700 Subject: [PATCH] h: add golink module / package and stand it up --- flake.nix | 1 + hosts/h/default.nix | 9 ++++ modules/golink.nix | 89 ++++++++++++++++++++++++++++++++++++++++ pkgs/golink.nix | 30 ++++++++++++++ pkgs/golink_keyfile.diff | 35 ++++++++++++++++ 5 files changed, 164 insertions(+) create mode 100644 modules/golink.nix create mode 100644 pkgs/golink.nix create mode 100644 pkgs/golink_keyfile.diff diff --git a/flake.nix b/flake.nix index d0d0261..6d06c90 100644 --- a/flake.nix +++ b/flake.nix @@ -240,6 +240,7 @@ inherit pkgs; isUnstable = true; }; + golink = pkgs.callPackage ./pkgs/golink.nix { inherit pkgs; }; gosignify = pkgs.callPackage ./pkgs/gosignify.nix { inherit pkgs; }; gotosocial = pkgs.callPackage ./pkgs/gotosocial.nix { inherit pkgs; }; govulncheck = diff --git a/hosts/h/default.nix b/hosts/h/default.nix index 65eb1fc..bc4e7b8 100644 --- a/hosts/h/default.nix +++ b/hosts/h/default.nix @@ -27,6 +27,7 @@ in { ../../modules/gotosocial.nix ../../modules/yarr.nix ../../modules/tsvnstat.nix + ../../modules/golink.nix ]; boot.loader.grub.enable = true; @@ -83,6 +84,10 @@ in { sopsFile = config.xin-secrets.h.services; owner = config.users.users.tsvnstat.name; }; + golink = { + sopsFile = config.xin-secrets.h.services; + owner = config.users.users.golink.name; + }; wireguard_private_key = { sopsFile = config.xin-secrets.h.services; }; }; @@ -187,6 +192,10 @@ in { }; services = { + golink = { + enable = true; + keyFile = "${config.sops.secrets.golink.path}"; + }; tsvnstat = { enable = true; keyPath = "${config.sops.secrets.router_stats_ts_key.path}"; diff --git a/modules/golink.nix b/modules/golink.nix new file mode 100644 index 0000000..857653f --- /dev/null +++ b/modules/golink.nix @@ -0,0 +1,89 @@ +{ config, lib, pkgs, inputs, ... }: +with pkgs; +let + cfg = config.services.golink; + golink = callPackage ../pkgs/golink.nix { }; +in { + options = with lib; { + services.golink = { + enable = mkEnableOption "Enable golink"; + + user = mkOption { + type = with types; oneOf [ str int ]; + default = "golink"; + description = '' + The user the service will use. + ''; + }; + + dataDir = mkOption { + type = types.path; + default = "/var/lib/golink"; + description = '' + Path to the golink sqlite database + ''; + }; + + keyFile = mkOption { + type = types.path; + default = "/run/secrets/golink"; + description = '' + Path to a file containing the golink tailscale auth token + ''; + }; + + group = mkOption { + type = with types; oneOf [ str int ]; + default = "golink"; + description = '' + The user the service will use. + ''; + }; + + package = mkOption { + type = types.package; + default = golink; + defaultText = literalExpression "pkgs.golink"; + description = "The package to use for golink"; + }; + }; + }; + config = lib.mkIf cfg.enable { + users.groups.${cfg.group} = { }; + users.users.${cfg.user} = { + description = "golink service user"; + isSystemUser = true; + home = cfg.dataDir; + createHome = true; + group = "${cfg.group}"; + }; + + systemd.services.golink = { + enable = true; + description = "golink server"; + wantedBy = [ "network-online.target" ]; + after = [ "network-online.target" ]; + + path = [ pkgs.vnstat ]; + + environment = { + HOME = cfg.dataDir; + HOSTNAME = config.networking.hostName; + }; + + serviceConfig = { + User = cfg.user; + Group = cfg.group; + + RuntimeDirectory = "golink"; + StateDirectory = "golink"; + StateDirectoryMode = "0755"; + CacheDirectory = "golink"; + CacheDirectoryMode = "0755"; + + ExecStart = + "${cfg.package}/bin/golink -sqlitedb ${cfg.dataDir}/golink.db -keyfile ${cfg.keyFile}"; + }; + }; + }; +} diff --git a/pkgs/golink.nix b/pkgs/golink.nix new file mode 100644 index 0000000..7713512 --- /dev/null +++ b/pkgs/golink.nix @@ -0,0 +1,30 @@ +{ lib, buildGoModule, fetchFromGitHub, ... }: + +let vendorHash = "sha256-U3j5yiFhtYR0wvHD1U+DkYuFVt6NyEPlx7feLWfr3/Y="; + +in with lib; +buildGoModule rec { + pname = "golink"; + version = "0.0.0"; + + src = fetchFromGitHub { + owner = "tailscale"; + repo = pname; + rev = "0755e37a910b73b586544e2805c075dcec7d0207"; + sha256 = "sha256-zzup/TR9iRNPrEEOzhIL5PTF8iKF8NlPqXBuRKt8AEc="; + }; + + patches = [ ./golink_keyfile.diff ]; + + vendorSha256 = vendorHash; + + proxyVendor = true; + + meta = { + + description = "A private shortlink service for tailnets"; + homepage = "https://github.com/tailscale/golink"; + license = licenses.bsd3; + maintainers = with maintainers; [ qbit ]; + }; +} diff --git a/pkgs/golink_keyfile.diff b/pkgs/golink_keyfile.diff new file mode 100644 index 0000000..d073d1d --- /dev/null +++ b/pkgs/golink_keyfile.diff @@ -0,0 +1,35 @@ +diff --git a/golink.go b/golink.go +index 3bc3353..fb0e791 100644 +--- a/golink.go ++++ b/golink.go +@@ -37,6 +37,7 @@ var ( + sqlitefile = flag.String("sqlitedb", "", "path of SQLite database to store links") + dev = flag.String("dev-listen", "", "if non-empty, listen on this addr and run in dev mode; auto-set sqlitedb if empty and don't use tsnet") + snapshot = flag.String("snapshot", "", "file path of snapshot file") ++ keyfile = flag.String("keyfile", "", "file path of file containing tskey") + ) + + var stats struct { +@@ -116,6 +117,13 @@ func Run() error { + Hostname: "go", + Logf: func(format string, args ...any) {}, + } ++ if *keyfile != "" { ++ keyData, err := os.ReadFile(*keyfile) ++ if err != nil { ++ log.Fatalf("error reading keyfile file %q: %v", *keyfile, err) ++ } ++ srv.AuthKey = string(keyData) ++ } + if *verbose { + srv.Logf = log.Printf + } +@@ -353,7 +361,7 @@ type expandEnv struct { + var expandFuncMap = texttemplate.FuncMap{ + "PathEscape": url.PathEscape, + "QueryEscape": url.QueryEscape, +- "TrimSuffix": strings.TrimSuffix, ++ "TrimSuffix": strings.TrimSuffix, + } + + // expandLink returns the expanded long URL to redirect to, executing any