diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..adc5831 --- /dev/null +++ b/flake.lock @@ -0,0 +1,79 @@ +{ + "nodes": { + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1778716662, + "narHash": "sha256-m1Yf0wZ8j1OHjTc2UwHwyQRSnNeSgLJOd7q5Y45hzi4=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "f7c1a2d347e4c52d5fb8d10cb4d94b5884e546fb", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1778443072, + "narHash": "sha256-zi7/fsqM/kFdNuED//4WOCUtezGtKKqRNORjMvfwjnA=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "da5ad661ba4e5ef59ba743f0d112cbc30e474f32", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1777168982, + "narHash": "sha256-GOkGPcboWE9BmGCRMLX3worL4EMnsnG8MyKmXNeYuhQ=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "f5901329dade4a6ea039af1433fb087bd9c1fe14", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-parts": "flake-parts", + "nixpkgs": "nixpkgs", + "ttp": "ttp" + } + }, + "ttp": { + "flake": false, + "locked": { + "lastModified": 1778329030, + "narHash": "sha256-qEEPlOuGVco1g6lI/kfEvIZkJmBbjehuchGWPTywR10=", + "ref": "refs/heads/main", + "rev": "929cb9d3a6aebebe6365973f13062ac2a8e03af6", + "revCount": 115, + "type": "git", + "url": "https://git.methanium.net/Tensamin/TTP.git" + }, + "original": { + "rev": "929cb9d3a6aebebe6365973f13062ac2a8e03af6", + "type": "git", + "url": "https://git.methanium.net/Tensamin/TTP.git" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..4064585 --- /dev/null +++ b/flake.nix @@ -0,0 +1,152 @@ +{ + description = "Omikron"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; + flake-parts.url = "github:hercules-ci/flake-parts"; + ttp = { + url = "git+https://git.methanium.net/Tensamin/TTP.git?rev=929cb9d3a6aebebe6365973f13062ac2a8e03af6"; + flake = false; + }; + }; + + outputs = inputs@{ self, nixpkgs, flake-parts, ttp, ... }: + flake-parts.lib.mkFlake { inherit inputs; } { + systems = [ + "x86_64-linux" + "aarch64-linux" + "x86_64-darwin" + "aarch64-darwin" + ]; + + perSystem = { self', pkgs, ... }: { + packages = { + default = self'.packages.omikron; + omikron = pkgs.rustPlatform.buildRustPackage { + pname = "omikron"; + version = "0.1.0"; + src = ./.; + cargoLock = { + lockFile = ./Cargo.lock; + allowBuiltinFetchGit = true; + }; + nativeBuildInputs = with pkgs; [ cmake perl pkg-config ]; + buildInputs = with pkgs; [ openssl ]; + dontUseCmakeConfigure = true; + preConfigure = '' + if [ -d ../cargo-vendor-dir/ttp-core-0.1.0 ]; then + cp ${ttp}/ttp-codec.json ../cargo-vendor-dir/ttp-codec.json + fi + ''; + }; + }; + }; + + flake = { + nixosModules.default = { config, pkgs, lib, ... }: + let + cfg = config.services.omikron; + defaultPackage = self.packages.${pkgs.stdenv.hostPlatform.system}.default or (throw "omikron: no pre-built package for system ${pkgs.stdenv.hostPlatform.system}"); + in + { + options.services.omikron = { + enable = lib.mkEnableOption "Enabled the Omikron"; + + dataDir = lib.mkOption { + type = lib.types.str; + default = "/var/lib/omikron"; + description = "Directory where the Omikron stores its data and reads certificates from."; + }; + + certFile = lib.mkOption { + type = lib.types.path; + description = "Path to the SSL certificate file (cert.pem)."; + }; + + keyFile = lib.mkOption { + type = lib.types.path; + description = "Path to the SSL private key file (key.pem)."; + }; + + environmentFiles = lib.mkOption { + type = lib.types.listOf lib.types.path; + default = [ ]; + description = "Environment files to load for the Omikron service."; + }; + + openFirewall = lib.mkOption { + type = lib.types.bool; + default = true; + description = "Whether to open the firewall for ports used by the Omikron."; + }; + + package = lib.mkOption { + type = lib.types.package; + default = defaultPackage; + description = "The Omikron package to use."; + }; + }; + + config = lib.mkIf cfg.enable { + users.users.omikron = { + isSystemUser = true; + group = "omikron"; + home = cfg.dataDir; + createHome = true; + description = "Omikron service user"; + }; + + users.groups.omikron = { }; + + systemd.services.omikron = { + description = "Tensamin Omikron"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + serviceConfig = { + Type = "simple"; + User = "omikron"; + Group = "omikron"; + WorkingDirectory = cfg.dataDir; + ExecStart = "${cfg.package}/bin/omikron"; + Restart = "unless-stopped"; + RestartSec = "5"; + + EnvironmentFile = cfg.environmentFiles; + + AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; + CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; + + ExecStartPre = [ + ("+" + pkgs.writeShellScript "omikron-setup-certs" '' + mkdir -p ${cfg.dataDir}/certs + ln -sf ${cfg.certFile} ${cfg.dataDir}/certs/cert.pem + ln -sf ${cfg.keyFile} ${cfg.dataDir}/certs/key.pem + chown -R omikron:omikron ${cfg.dataDir} + '') + ]; + + ProtectSystem = "strict"; + ProtectHome = true; + PrivateTmp = true; + NoNewPrivileges = true; + ReadWritePaths = cfg.dataDir; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectControlGroups = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + LockPersonality = true; + MemoryDenyWriteExecute = true; + }; + }; + + networking.firewall = lib.mkIf cfg.openFirewall { + allowedTCPPorts = [ 959 ]; + allowedUDPPorts = [ 959 ]; + }; + }; + }; + }; + }; +}