From d644aaaa6ddd9c775e6c4edf3c116eb9a97b6ac6 Mon Sep 17 00:00:00 2001 From: Alois Date: Sat, 16 May 2026 16:18:53 +0200 Subject: [PATCH 1/6] [Add] Nix Flake --- flake.lock | 78 ++++++++++++++++++++++++ flake.nix | 171 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 249 insertions(+) create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..6f56d6f --- /dev/null +++ b/flake.lock @@ -0,0 +1,78 @@ +{ + "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=", + "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..900b774 --- /dev/null +++ b/flake.nix @@ -0,0 +1,171 @@ +{ + description = "Omega"; + + 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.omega; + omega = pkgs.rustPlatform.buildRustPackage { + pname = "omega"; + version = "0.1.0"; + src = ./.; + cargoLock = { + lockFile = ./Cargo.lock; + allowBuiltinFetchGit = true; + }; + nativeBuildInputs = with pkgs; [ cmake perl pkg-config ]; + buildInputs = with pkgs; [ openssl libmysqlclient ]; + 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.omega; + defaultPackage = self.packages.${pkgs.stdenv.hostPlatform.system}.default or (throw "omega: no pre-built package for system ${pkgs.stdenv.hostPlatform.system}"); + in + { + options.services.omega = { + enable = lib.mkEnableOption "Omega, Tensamin's central server"; + + dataDir = lib.mkOption { + type = lib.types.str; + default = "/var/lib/omega"; + description = "Directory where Omega stores its data and reads certificates from."; + }; + + apiCertFile = lib.mkOption { + type = lib.types.path; + description = "Path to the SSL certificate file for the web/API server (e.g. ACME fullchain.pem). Copied to server_cert.pem at runtime."; + }; + + apiKeyFile = lib.mkOption { + type = lib.types.path; + description = "Path to the SSL private key file for the web/API server (e.g. ACME key.pem). Converted to PKCS#8 and copied to server_key.pem at runtime."; + }; + + transportCertFile = lib.mkOption { + type = lib.types.path; + description = "Path to the SSL certificate file for the TTP/QUIC transport (e.g. ACME fullchain.pem). Copied to transport_cert.pem at runtime."; + }; + + transportKeyFile = lib.mkOption { + type = lib.types.path; + description = "Path to the SSL private key file for the TTP/QUIC transport (e.g. ACME key.pem). Converted to PKCS#8 and copied to transport_key.pem at runtime."; + }; + + environmentFiles = lib.mkOption { + type = lib.types.listOf lib.types.path; + default = [ ]; + description = '' + Environment files to load for the Omega service. + Must provide at least DB_URL, PRIVATE_KEY, and PUBLIC_KEY. + ''; + }; + + openFirewall = lib.mkOption { + type = lib.types.bool; + default = true; + description = "Whether to open the firewall for ports used by Omega."; + }; + + package = lib.mkOption { + type = lib.types.package; + default = defaultPackage; + description = "The Omega package to use."; + }; + }; + + config = lib.mkIf cfg.enable { + users.users.omega = { + isSystemUser = true; + group = "omega"; + home = cfg.dataDir; + createHome = true; + description = "Omega service user"; + }; + + users.groups.omega = { }; + + systemd.services.omega = { + description = "Tensamin Omega"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + serviceConfig = { + Type = "simple"; + User = "omega"; + Group = "omega"; + WorkingDirectory = cfg.dataDir; + ExecStart = "${cfg.package}/bin/omega"; + Restart = "unless-stopped"; + RestartSec = "5"; + + EnvironmentFile = cfg.environmentFiles; + + AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; + CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; + + ExecStartPre = [ + ("+" + pkgs.writeShellScript "omega-setup-certs" '' + mkdir -p ${cfg.dataDir}/certs + cp ${cfg.apiCertFile} ${cfg.dataDir}/certs/server_cert.pem + ${pkgs.openssl}/bin/openssl pkcs8 -topk8 -nocrypt \ + -in ${cfg.apiKeyFile} \ + -out ${cfg.dataDir}/certs/server_key.pem + cp ${cfg.transportCertFile} ${cfg.dataDir}/certs/transport_cert.pem + ${pkgs.openssl}/bin/openssl pkcs8 -topk8 -nocrypt \ + -in ${cfg.transportKeyFile} \ + -out ${cfg.dataDir}/certs/transport_key.pem + chown -R omega:omega ${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 = [ 9187 9188 ]; + allowedUDPPorts = [ 9187 9188 ]; + }; + }; + }; + }; + }; +} From b02795b80c6ea472bfd8aaccd684656dab2bf3d9 Mon Sep 17 00:00:00 2001 From: Alois Date: Sat, 16 May 2026 16:43:39 +0200 Subject: [PATCH 2/6] [Fix] Nix Flake --- flake.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flake.nix b/flake.nix index 900b774..9c34223 100644 --- a/flake.nix +++ b/flake.nix @@ -122,8 +122,8 @@ Group = "omega"; WorkingDirectory = cfg.dataDir; ExecStart = "${cfg.package}/bin/omega"; - Restart = "unless-stopped"; - RestartSec = "5"; + Restart = "always"; + RestartSec = "5s"; EnvironmentFile = cfg.environmentFiles; From 8451b64bea8c904bfca0682be27f66adc97c2d3b Mon Sep 17 00:00:00 2001 From: Alois Date: Sat, 16 May 2026 17:34:10 +0200 Subject: [PATCH 3/6] [Fix] use working directory instead of executable directory --- src/util/file_util.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/util/file_util.rs b/src/util/file_util.rs index b108810..f1c51db 100644 --- a/src/util/file_util.rs +++ b/src/util/file_util.rs @@ -163,9 +163,8 @@ pub fn get_children(path: &str) -> Vec { } pub fn get_directory() -> String { - let exe = std::env::current_exe().unwrap_or_else(|_| PathBuf::from(".")); - exe.parent() - .unwrap_or(Path::new(".")) + std::env::current_dir() + .unwrap_or_else(|_| PathBuf::from(".")) .to_string_lossy() .to_string() } From 7e9e834326d6c724a2780ee5af5f2eab265f8249 Mon Sep 17 00:00:00 2001 From: Alois Date: Sat, 16 May 2026 17:44:40 +0200 Subject: [PATCH 4/6] [Add] port options in nix flake --- flake.nix | 21 +++++++++++++++++++-- src/main.rs | 14 ++++++++++++-- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/flake.nix b/flake.nix index 9c34223..55f73e0 100644 --- a/flake.nix +++ b/flake.nix @@ -87,6 +87,18 @@ ''; }; + apiPort = lib.mkOption { + type = lib.types.port; + default = 9188; + description = "Port for the web/API server."; + }; + + transportPort = lib.mkOption { + type = lib.types.port; + default = 9187; + description = "Port for the TTP/QUIC transport server."; + }; + openFirewall = lib.mkOption { type = lib.types.bool; default = true; @@ -125,6 +137,11 @@ Restart = "always"; RestartSec = "5s"; + Environment = [ + "API_PORT=${toString cfg.apiPort}" + "OMIKRON_PORT=${toString cfg.transportPort}" + ]; + EnvironmentFile = cfg.environmentFiles; AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; @@ -161,8 +178,8 @@ }; networking.firewall = lib.mkIf cfg.openFirewall { - allowedTCPPorts = [ 9187 9188 ]; - allowedUDPPorts = [ 9187 9188 ]; + allowedTCPPorts = [ cfg.transportPort cfg.apiPort ]; + allowedUDPPorts = [ cfg.transportPort cfg.apiPort ]; }; }; }; diff --git a/src/main.rs b/src/main.rs index 8143c9f..7d5cfcc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -35,8 +35,13 @@ async fn main() { log_in!("Incoming messages"); log_out!("Outgoing messages"); + let omikron_port: u16 = env::var("OMIKRON_PORT") + .ok() + .and_then(|s| s.parse().ok()) + .unwrap_or(9187); + tokio::spawn(async move { - match omikron_connection::start(9187).await { + match omikron_connection::start(omikron_port).await { Err(e) => log_err!(0, PrintType::General, "{:?}", e), _ => {} } @@ -59,7 +64,12 @@ async fn main() { log!(" Users"); } - let _ = server::server::start(9188).await; + let api_port: u16 = env::var("API_PORT") + .ok() + .and_then(|s| s.parse().ok()) + .unwrap_or(9188); + + let _ = server::server::start(api_port).await; tokio::signal::ctrl_c().await.unwrap(); } From a3f9e0ea3af65c17ada6e9e9b051e17ea96c2e0f Mon Sep 17 00:00:00 2001 From: Alois Date: Sat, 16 May 2026 19:02:12 +0200 Subject: [PATCH 5/6] [Add] ttpBind --- Cargo.lock | 4 ++-- flake.lock | 11 ++++++----- flake.nix | 16 +++++++++++++++- src/server/server.rs | 3 ++- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 21d6ccc..aa6be62 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3599,7 +3599,7 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "ttp-core" version = "0.1.0" -source = "git+https://git.methanium.net/Tensamin/TTP.git#929cb9d3a6aebebe6365973f13062ac2a8e03af6" +source = "git+https://git.methanium.net/Tensamin/TTP.git#7e5d1953df8592a1feba0f390d205d0ef61a3119" dependencies = [ "base64", "byteorder", @@ -3612,7 +3612,7 @@ dependencies = [ [[package]] name = "ttp-native" version = "0.1.0" -source = "git+https://git.methanium.net/Tensamin/TTP.git#929cb9d3a6aebebe6365973f13062ac2a8e03af6" +source = "git+https://git.methanium.net/Tensamin/TTP.git#7e5d1953df8592a1feba0f390d205d0ef61a3119" dependencies = [ "quinn", "rustls", diff --git a/flake.lock b/flake.lock index 6f56d6f..e742243 100644 --- a/flake.lock +++ b/flake.lock @@ -59,15 +59,16 @@ "ttp": { "flake": false, "locked": { - "lastModified": 1778329030, - "narHash": "sha256-qEEPlOuGVco1g6lI/kfEvIZkJmBbjehuchGWPTywR10=", - "rev": "929cb9d3a6aebebe6365973f13062ac2a8e03af6", - "revCount": 115, + "lastModified": 1778948017, + "narHash": "sha256-hqBYSZnPq7f/F2Z6nJK+6a8ITk6WRCcVBcNT0CR6SnM=", + "ref": "refs/heads/main", + "rev": "7e5d1953df8592a1feba0f390d205d0ef61a3119", + "revCount": 117, "type": "git", "url": "https://git.methanium.net/Tensamin/TTP.git" }, "original": { - "rev": "929cb9d3a6aebebe6365973f13062ac2a8e03af6", + "rev": "7e5d1953df8592a1feba0f390d205d0ef61a3119", "type": "git", "url": "https://git.methanium.net/Tensamin/TTP.git" } diff --git a/flake.nix b/flake.nix index 55f73e0..29f2373 100644 --- a/flake.nix +++ b/flake.nix @@ -5,7 +5,7 @@ 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"; + url = "git+https://git.methanium.net/Tensamin/TTP.git?rev=7e5d1953df8592a1feba0f390d205d0ef61a3119"; flake = false; }; }; @@ -99,6 +99,18 @@ description = "Port for the TTP/QUIC transport server."; }; + ttpBind = lib.mkOption { + type = lib.types.str; + default = "0.0.0.0"; + description = "IP address to bind the TTP/QUIC transport server to."; + }; + + bindAddress = lib.mkOption { + type = lib.types.str; + default = "0.0.0.0"; + description = "IP address to bind the HTTP/API server to."; + }; + openFirewall = lib.mkOption { type = lib.types.bool; default = true; @@ -140,6 +152,8 @@ Environment = [ "API_PORT=${toString cfg.apiPort}" "OMIKRON_PORT=${toString cfg.transportPort}" + "TTP_BIND=${cfg.ttpBind}" + "BIND_ADDRESS=${cfg.bindAddress}" ]; EnvironmentFile = cfg.environmentFiles; diff --git a/src/server/server.rs b/src/server/server.rs index 1fcfe04..3c7fc05 100644 --- a/src/server/server.rs +++ b/src/server/server.rs @@ -30,7 +30,8 @@ pub async fn start(port: u16) -> anyhow::Result<()> { config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()]; - let addr = format!("0.0.0.0:{port}"); + let bind_addr = std::env::var("BIND_ADDRESS").unwrap_or_else(|_| "0.0.0.0".to_string()); + let addr = format!("{}:{}", bind_addr, port); log!(" Server on {}", addr); HttpServer::new(move || { From 046654cad7e995eabefd1ff6a6dfce8291da971c Mon Sep 17 00:00:00 2001 From: Alois Date: Sun, 17 May 2026 13:44:19 +0200 Subject: [PATCH 6/6] [Add] nix dev shell --- flake.lock | 28 +++++++++++++++++++++++---- flake.nix | 57 ++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 62 insertions(+), 23 deletions(-) diff --git a/flake.lock b/flake.lock index e742243..fb5bf79 100644 --- a/flake.lock +++ b/flake.lock @@ -20,11 +20,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1778443072, - "narHash": "sha256-zi7/fsqM/kFdNuED//4WOCUtezGtKKqRNORjMvfwjnA=", + "lastModified": 1778869304, + "narHash": "sha256-30sZNZoA1cqF5JNO9fVX+wgiQYjB7HJqqJ4ztCDeBZE=", "owner": "nixos", "repo": "nixpkgs", - "rev": "da5ad661ba4e5ef59ba743f0d112cbc30e474f32", + "rev": "d233902339c02a9c334e7e593de68855ad26c4cb", "type": "github" }, "original": { @@ -53,15 +53,35 @@ "inputs": { "flake-parts": "flake-parts", "nixpkgs": "nixpkgs", + "rust-overlay": "rust-overlay", "ttp": "ttp" } }, + "rust-overlay": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1778987862, + "narHash": "sha256-V3qGt9P1eJP/r/1ONablphfGiH0RP4agQhrRANpDYx8=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "6f44d8874ac29806c8d5cae42bf8e19ebb5ce0d3", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, "ttp": { "flake": false, "locked": { "lastModified": 1778948017, "narHash": "sha256-hqBYSZnPq7f/F2Z6nJK+6a8ITk6WRCcVBcNT0CR6SnM=", - "ref": "refs/heads/main", "rev": "7e5d1953df8592a1feba0f390d205d0ef61a3119", "revCount": 117, "type": "git", diff --git a/flake.nix b/flake.nix index 29f2373..97b1bcc 100644 --- a/flake.nix +++ b/flake.nix @@ -4,13 +4,17 @@ inputs = { nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; flake-parts.url = "github:hercules-ci/flake-parts"; + rust-overlay = { + url = "github:oxalica/rust-overlay"; + inputs.nixpkgs.follows = "nixpkgs"; + }; ttp = { url = "git+https://git.methanium.net/Tensamin/TTP.git?rev=7e5d1953df8592a1feba0f390d205d0ef61a3119"; flake = false; }; }; - outputs = inputs@{ self, nixpkgs, flake-parts, ttp, ... }: + outputs = inputs@{ self, nixpkgs, flake-parts, rust-overlay, ttp, ... }: flake-parts.lib.mkFlake { inherit inputs; } { systems = [ "x86_64-linux" @@ -19,28 +23,43 @@ "aarch64-darwin" ]; - perSystem = { self', pkgs, ... }: { - packages = { - default = self'.packages.omega; - omega = pkgs.rustPlatform.buildRustPackage { - pname = "omega"; - version = "0.1.0"; - src = ./.; - cargoLock = { - lockFile = ./Cargo.lock; - allowBuiltinFetchGit = true; + perSystem = { self', pkgs, system, ... }: + let + rustPkgs = import nixpkgs { + inherit system; + overlays = [ (import rust-overlay) ]; + }; + rustToolchain = rustPkgs.rust-bin.stable.latest.default.override { + extensions = [ "rust-src" "rust-analyzer" "clippy" "rustfmt" ]; + }; + in + { + packages = { + default = self'.packages.omega; + omega = pkgs.rustPlatform.buildRustPackage { + pname = "omega"; + version = "0.1.0"; + src = ./.; + cargoLock = { + lockFile = ./Cargo.lock; + allowBuiltinFetchGit = true; + }; + nativeBuildInputs = with pkgs; [ cmake perl pkg-config ]; + buildInputs = with pkgs; [ openssl libmysqlclient ]; + 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 + ''; }; - nativeBuildInputs = with pkgs; [ cmake perl pkg-config ]; + }; + + devShells.default = pkgs.mkShell { + nativeBuildInputs = with pkgs; [ rustToolchain git cmake perl pkg-config ]; buildInputs = with pkgs; [ openssl libmysqlclient ]; - 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, ... }: