Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

services/yggdrasil: init #1001

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions modules/module-list.nix
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
./services/trezord.nix
./services/wg-quick.nix
./services/yabai
./services/yggdrasil.nix
./services/nextdns
./programs/bash
./programs/direnv.nix
Expand Down
117 changes: 117 additions & 0 deletions modules/services/yggdrasil.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.yggdrasil;

settingsProvided = cfg.settings != { };
configFileProvided = cfg.configFile != null;

format = pkgs.formats.json { };
in
{
options = with types; {
services.yggdrasil = {
enable = mkEnableOption "the yggdrasil system service";

settings = mkOption {
type = format.type;
default = { };
example = {
Peers = [
"tcp://aa.bb.cc.dd:eeeee"
"tcp://[aaaa:bbbb:cccc:dddd::eeee]:fffff"
];
Listen = [
"tcp://0.0.0.0:xxxxx"
];
};
description = ''
Configuration for yggdrasil, as a Nix attribute set.

Warning: this is stored in the WORLD-READABLE Nix store!
Therefore, it is not appropriate for private keys. If you
wish to specify the keys, use {option}`configFile`.

If no keys are specified then ephemeral keys are generated
and the Yggdrasil interface will have a random IPv6 address
each time the service is started. This is the default.

If both {option}`configFile` and {option}`settings`
are supplied, they will be combined, with values from
{option}`configFile` taking precedence.

You can use the command `nix-shell -p yggdrasil --run "yggdrasil -genconf"`
to generate default configuration values with documentation.
'';
};

configFile = mkOption {
type = nullOr path;
default = null;
example = "/run/keys/yggdrasil.conf";
description = lib.mdDoc ''
A file which contains JSON or HJSON configuration for yggdrasil. See
the {option}`settings` option for more information.

On NixOS, file in this option is limited to 1 MB due to limitations
in systemd. If you would like to share your yggdrasil configuration
between nix-darwin and NixOS, you should keep this limitation in mind,
even though there is no equivalent limit on macOS.
'';
};

package = mkPackageOption pkgs "yggdrasil" { };

extraArgs = mkOption {
type = listOf str;
default = [ ];
example = [ "-loglevel" "info" ];
description = lib.mdDoc "Extra command line arguments.";
};
};
};

config = mkIf cfg.enable (
let
yggdrasilConf = "/run/yggdrasil/yggdrasil.conf";
binYggdrasil = "${cfg.package}/bin/yggdrasil";
binHjson = "${pkgs.hjson-go}/bin/hjson-cli";
in
{
environment.systemPackages = [ cfg.package ];

# have to write it in that way to not interfere with brew's (or idk github?) ygg.plist
launchd.daemons.ygg =
{
script = ''
set -euo pipefail

mkdir -p $(dirname ${yggdrasilConf})

# prepare config file
${(if settingsProvided || configFileProvided then
"echo "

+ (lib.optionalString settingsProvided
"'${builtins.toJSON cfg.settings}'")
+ (lib.optionalString configFileProvided
"$(${binHjson} -c ${cfg.configFile})")
+ " | ${pkgs.jq}/bin/jq -s add | ${binYggdrasil} -normaliseconf -useconf"
else
"${binYggdrasil} -genconf") + " > ${yggdrasilConf}"}

# start yggdrasil
${binYggdrasil} -useconffile ${yggdrasilConf} ${lib.strings.escapeShellArgs cfg.extraArgs}
'';

serviceConfig = {
ProcessType = "Interactive";
StandardOutPath = "/tmp/yggdrasil.stdout.log";
StandardErrorPath = "/tmp/yggdrasil.stderr.log";
KeepAlive = true;
RunAtLoad = true;
};
};
}
);
}
Loading