···7171 nixos-mailserver.url = "gitlab:simple-nixos-mailserver/nixos-mailserver";
7272 nixos-mailserver.inputs.nixpkgs.follows = "nixpkgs";
73737474- sigexec.url = "git+https://git.geninf.io/Lassulus/sigexec";
7575- sigexec.inputs.nixpkgs.follows = "nixpkgs";
7676-7774 # build farm (configs/nix-farm): remote builds over grpc:// ...
7875 # Fork with the drain/upload race fix (Mic92/nix-grpc-store#204);
7976 # back to upstream once that is merged.
-51
configs/sigexec/dashboard.nix
···11-# sigexec dashboard: one page + executor registry + reverse proxy (no key
22-# material, no job data). nginx terminates TLS and forwards to it; the
33-# executors themselves live in ./executor.nix on each machine.
44-# browser: https://sigexec.lassul.us (register passkeys at /register)
55-# CLI: sigexec run -x https://sigexec.lassul.us/x/neoprism -- uptime
66-# (statements sign the path relative to the base URL, so the executor
77-# verifies /jobs after the proxy strips /x/neoprism)
88-let
99- domain = "sigexec.lassul.us";
1010- dashboardPort = 7501;
1111- # Must match configs/sigexec/executor.nix.
1212- executorPort = 7601;
1313-in
1414-{ self, ... }:
1515-{
1616- imports = [ self.inputs.sigexec.nixosModules.dashboard ];
1717-1818- services.sigexec-dashboard = {
1919- enable = true;
2020- rpId = domain;
2121- port = dashboardPort;
2222- executors = {
2323- # this host's own executor (neoprism also imports ./executor.nix)
2424- neoprism = "http://127.0.0.1:${toString executorPort}";
2525- # reached over retiolum (executor port is open on that interface only)
2626- coaxmetal = "http://coaxmetal.r:${toString executorPort}";
2727- icarus = "http://icarus.r:${toString executorPort}";
2828- shodan = "http://shodan.r:${toString executorPort}";
2929- # over public TLS (set up before starkstrom had a kartei card); its own
3030- # nginx terminates TLS and strips the /sigexec prefix
3131- # (machines/starkstrom/config.nix).
3232- starkstrom = "https://starkstrom.lassul.us/sigexec";
3333- };
3434- };
3535-3636- services.nginx.virtualHosts.${domain} = {
3737- enableACME = true;
3838- forceSSL = true;
3939- locations."/" = {
4040- proxyPass = "http://127.0.0.1:${toString dashboardPort}";
4141- extraConfig = ''
4242- # Job streams are long-lived chunked responses: unbuffered so output
4343- # arrives live, and a generous read timeout because `logs` on a
4444- # pending job legitimately blocks until someone approves it.
4545- proxy_buffering off;
4646- proxy_read_timeout 1d;
4747- proxy_send_timeout 1d;
4848- '';
4949- };
5050- };
5151-}
-40
configs/sigexec/executor.nix
···11-# sigexec executor: signed remote command execution as root, for
22-# administration. The signature is the authorization — commands are signed in
33-# the browser (passkey) or by the CLI's local ed25519 key, verified against
44-# the key list below; no shell parses them, argv runs literally.
55-#
66-# There is no TLS here: the port is opened on retiolum only, and the dashboard
77-# on neoprism (./dashboard.nix) proxies browser/CLI traffic to it. Machines
88-# not reachable over retiolum (starkstrom) additionally put their own nginx in
99-# front; see machines/starkstrom/config.nix.
1010-let
1111- # Must match the executor URLs registered in ./dashboard.nix.
1212- executorPort = 7601;
1313- domain = "sigexec.lassul.us";
1414-in
1515-{ self, ... }:
1616-{
1717- imports = [ self.inputs.sigexec.nixosModules.executor ];
1818-1919- services.sigexec-executor = {
2020- enable = true;
2121- # root deliberately: this executor's purpose is administration, and the
2222- # executor's privileges are the jobs' privileges.
2323- user = "root";
2424- group = "root";
2525- # ssh-style: login shell env, bare command names work.
2626- login = true;
2727- # Wildcard dual-stack bind; reachability is the firewall's job below.
2828- listen = "[::]:${toString executorPort}";
2929- # Browser passkeys sign against the dashboard's origin.
3030- rpId = domain;
3131- origins = [ "https://${domain}" ];
3232- authorizedKeys = [
3333- "ed25519 RhYj8TzT8w3q50Oi3-q7U1KLRLrm66FltogC15ootJg read,request lass@ignavia"
3434- "webauthn-es256 MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZPkoTMJKVdsC-_m8wPrKrJiCKVcZLdJarMTzF8JQFJUKmYlqY_34oQr1u9wCMTQZFU541Jmje1ri9z20XmsXpQ 6KpUo9EZQrmOCQ0vVwgnbw read,write lass@ignavia"
3535- ];
3636- };
3737-3838- # Reachable from the mesh only; the dashboard proxies for the outside world.
3939- networking.firewall.interfaces.retiolum.allowedTCPPorts = [ executorPort ];
4040-}