1{ config, lib, ... }:
2
3with lib;
4let cfg = config.nix.sshServe;
5 command =
6 if cfg.protocol == "ssh"
7 then "nix-store --serve ${lib.optionalString cfg.write "--write"}"
8 else "nix-daemon --stdio";
9in {
10 options = {
11
12 nix.sshServe = {
13
14 enable = mkOption {
15 type = types.bool;
16 default = false;
17 description = lib.mdDoc "Whether to enable serving the Nix store as a remote store via SSH.";
18 };
19
20 write = mkOption {
21 type = types.bool;
22 default = false;
23 description = lib.mdDoc "Whether to enable writing to the Nix store as a remote store via SSH. Note: the sshServe user is named nix-ssh and is not a trusted-user. nix-ssh should be added to the {option}`nix.settings.trusted-users` option in most use cases, such as allowing remote building of derivations.";
24 };
25
26 keys = mkOption {
27 type = types.listOf types.str;
28 default = [];
29 example = [ "ssh-dss AAAAB3NzaC1k... alice@example.org" ];
30 description = lib.mdDoc "A list of SSH public keys allowed to access the binary cache via SSH.";
31 };
32
33 protocol = mkOption {
34 type = types.enum [ "ssh" "ssh-ng" ];
35 default = "ssh";
36 description = lib.mdDoc "The specific Nix-over-SSH protocol to use.";
37 };
38
39 };
40
41 };
42
43 config = mkIf cfg.enable {
44
45 users.users.nix-ssh = {
46 description = "Nix SSH store user";
47 isSystemUser = true;
48 group = "nix-ssh";
49 useDefaultShell = true;
50 };
51 users.groups.nix-ssh = {};
52
53 services.openssh.enable = true;
54
55 services.openssh.extraConfig = ''
56 Match User nix-ssh
57 AllowAgentForwarding no
58 AllowTcpForwarding no
59 PermitTTY no
60 PermitTunnel no
61 X11Forwarding no
62 ForceCommand ${config.nix.package.out}/bin/${command}
63 Match All
64 '';
65
66 users.users.nix-ssh.openssh.authorizedKeys.keys = cfg.keys;
67
68 };
69}