diff --git a/maintainers/maintainer-list.nix b/maintainers/maintainer-list.nix index 37055b35e8f8..5c51a0805dfd 100644 --- a/maintainers/maintainer-list.nix +++ b/maintainers/maintainer-list.nix @@ -6933,6 +6933,12 @@ { fingerprint = "elY15tXap1tddxbBVoUoAioe1u0RDWti5rc9cauSmwo"; } ]; }; + figboy9 = { + email = "figboy9@tuta.io"; + github = "figboy9"; + githubId = 52276064; + name = "figboy9"; + }; figsoda = { email = "figsoda@pm.me"; matrix = "@figsoda:matrix.org"; diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 5d80f23dd23b..ad54da561659 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1252,6 +1252,7 @@ ./services/networking/uptermd.nix ./services/networking/v2ray.nix ./services/networking/v2raya.nix + ./services/networking/veilid.nix ./services/networking/vdirsyncer.nix ./services/networking/vsftpd.nix ./services/networking/wasabibackend.nix diff --git a/nixos/modules/services/networking/veilid.nix b/nixos/modules/services/networking/veilid.nix new file mode 100644 index 000000000000..d471a5f61952 --- /dev/null +++ b/nixos/modules/services/networking/veilid.nix @@ -0,0 +1,227 @@ +{ + config, + pkgs, + lib, + ... +}: +with lib; +let + cfg = config.services.veilid; + dataDir = "/var/db/veilid-server"; + + settingsFormat = pkgs.formats.yaml { }; + configFile = settingsFormat.generate "veilid-server.conf" cfg.settings; +in +{ + config = mkIf cfg.enable { + networking.firewall = mkIf cfg.openFirewall { + allowedTCPPorts = [ 5150 ]; + allowedUDPPorts = [ 5150 ]; + }; + + # Based on https://gitlab.com/veilid/veilid/-/blob/main/package/systemd/veilid-server.service?ref_type=heads + systemd.services.veilid = { + enable = true; + description = "Veilid Headless Node"; + wants = [ "network-online.target" ]; + before = [ "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + restartTriggers = [ configFile ]; + environment = { + RUST_BACKTRACE = "1"; + }; + serviceConfig = { + ExecStart = "${pkgs.veilid}/bin/veilid-server -c ${configFile}"; + ExecReload = "${pkgs.coreutils}/bin/kill -s HUP $MAINPID"; + KillSignal = "SIGQUIT"; + TimeoutStopSec = 5; + WorkingDirectory = "/"; + User = "veilid"; + Group = "veilid"; + UMask = "0002"; + + CapabilityBoundingSet = ""; + SystemCallFilter = [ "@system-service" ]; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + PrivateDevices = true; + PrivateTmp = true; + PrivateUsers = true; + ProtectHome = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + ProtectSystem = "strict"; + ReadWritePaths = dataDir; + + RestrictRealtime = true; + SystemCallArchitectures = "native"; + LockPersonality = true; + RestrictSUIDSGID = true; + }; + }; + users.users.veilid = { + isSystemUser = true; + group = "veilid"; + home = dataDir; + createHome = true; + }; + users.groups.veilid = { }; + + environment = { + systemPackages = [ pkgs.veilid ]; + }; + services.veilid.settings = { }; + }; + + options.services.veilid = { + enable = mkEnableOption "Veilid Headless Node"; + openFirewall = mkOption { + default = false; + type = types.bool; + description = "Whether to open firewall on ports 5150/tcp, 5150/udp"; + }; + settings = mkOption { + description = '' + Build veilid-server.conf with nix expression. + Check Configuration Keys. + ''; + type = types.submodule { + freeformType = settingsFormat.type; + + options = { + client_api = { + ipc_enabled = mkOption { + type = types.bool; + default = true; + description = "veilid-server will respond to Python and other JSON client requests."; + }; + ipc_directory = mkOption { + type = types.str; + default = "${dataDir}/ipc"; + description = "IPC directory where file sockets are stored."; + }; + }; + logging = { + system = { + enabled = mkOption { + type = types.bool; + default = true; + description = "Events of type 'system' will be logged."; + }; + level = mkOption { + type = types.str; + default = "info"; + example = "debug"; + description = "The minimum priority of system events to be logged."; + }; + }; + terminal = { + enabled = mkOption { + type = types.bool; + default = false; + description = "Events of type 'terminal' will be logged."; + }; + level = mkOption { + type = types.str; + default = "info"; + example = "debug"; + description = "The minimum priority of terminal events to be logged."; + }; + }; + api = { + enabled = mkOption { + type = types.bool; + default = false; + description = "Events of type 'api' will be logged."; + }; + level = mkOption { + type = types.str; + default = "info"; + example = "debug"; + description = "The minimum priority of api events to be logged."; + }; + }; + }; + core = { + capabilities = { + disable = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "APPM" ]; + description = "A list of capabilities to disable (for example, DHTV to say you cannot store DHT information)."; + }; + }; + protected_store = { + allow_insecure_fallback = mkOption { + type = types.bool; + default = true; + description = "If we can't use system-provided secure storage, should we proceed anyway?"; + }; + always_use_insecure_storage = mkOption { + type = types.bool; + default = true; + description = "Should we bypass any attempt to use system-provided secure storage?"; + }; + directory = mkOption { + type = types.str; + default = "${dataDir}/protected_store"; + description = "The filesystem directory to store your protected store in."; + }; + }; + table_store = { + directory = mkOption { + type = types.str; + default = "${dataDir}/table_store"; + description = "The filesystem directory to store your table store within."; + }; + }; + block_store = { + directory = mkOption { + type = types.nullOr types.str; + default = "${dataDir}/block_store"; + description = "The filesystem directory to store blocks for the block store."; + }; + }; + network = { + routing_table = { + bootstrap = mkOption { + type = types.listOf types.str; + default = [ "bootstrap.veilid.net" ]; + description = "Host name of existing well-known Veilid bootstrap servers for the network to connect to."; + }; + node_id = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + description = "Base64-encoded public key for the node, used as the node's ID."; + }; + }; + dht = { + min_peer_count = mkOption { + type = types.number; + default = 20; + description = "Minimum number of nodes to keep in the peer table."; + }; + }; + upnp = mkOption { + type = types.bool; + default = true; + description = "Should the app try to improve its incoming network connectivity using UPnP?"; + }; + detect_address_changes = mkOption { + type = types.bool; + default = true; + description = "Should veilid-core detect and notify on network address changes?"; + }; + }; + }; + }; + }; + }; + }; + + meta.maintainers = with maintainers; [ figboy9 ]; +}