refactor hosts directory, and move ssh keys out of modules/data
longer-term, i want hosts/by-name to define host-specific data that's accessible via the other hosts (things like pubkeys). also the secrets management needs some rethinking. there's really not much point in me specifiying where *exactly* a secret comes from at its use site. i should really be specifying secret store manifests; i.e. "servo.yaml contains secrets X Y and Z", and leaving the rest up to auto-computing.
This commit is contained in:
parent
35e28041cd
commit
d13bcc49ab
|
@ -9,7 +9,7 @@
|
||||||
sane.gui.sway.enable = true;
|
sane.gui.sway.enable = true;
|
||||||
sane.services.duplicity.enable = true;
|
sane.services.duplicity.enable = true;
|
||||||
sane.services.nixserve.enable = true;
|
sane.services.nixserve.enable = true;
|
||||||
sane.services.nixserve.sopsFile = ../../secrets/desko.yaml;
|
sane.services.nixserve.sopsFile = ../../../secrets/desko.yaml;
|
||||||
sane.persist.enable = true;
|
sane.persist.enable = true;
|
||||||
|
|
||||||
boot.loader.efi.canTouchEfiVariables = false;
|
boot.loader.efi.canTouchEfiVariables = false;
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
services.usbmuxd.enable = true;
|
services.usbmuxd.enable = true;
|
||||||
|
|
||||||
sops.secrets.colin-passwd = {
|
sops.secrets.colin-passwd = {
|
||||||
sopsFile = ../../secrets/desko.yaml;
|
sopsFile = ../../../secrets/desko.yaml;
|
||||||
neededForUsers = true;
|
neededForUsers = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
sops.secrets.duplicity_passphrase = {
|
sops.secrets.duplicity_passphrase = {
|
||||||
sopsFile = ../../secrets/desko.yaml;
|
sopsFile = ../../../secrets/desko.yaml;
|
||||||
};
|
};
|
||||||
|
|
||||||
programs.steam = {
|
programs.steam = {
|
|
@ -14,7 +14,7 @@
|
||||||
sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];
|
sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];
|
||||||
|
|
||||||
sops.secrets.colin-passwd = {
|
sops.secrets.colin-passwd = {
|
||||||
sopsFile = ../../secrets/lappy.yaml;
|
sopsFile = ../../../secrets/lappy.yaml;
|
||||||
neededForUsers = true;
|
neededForUsers = true;
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
services.getty.autologinUser = "root"; # allows for emergency maintenance?
|
services.getty.autologinUser = "root"; # allows for emergency maintenance?
|
||||||
|
|
||||||
sops.secrets.colin-passwd = {
|
sops.secrets.colin-passwd = {
|
||||||
sopsFile = ../../secrets/moby.yaml;
|
sopsFile = ../../../secrets/moby.yaml;
|
||||||
neededForUsers = true;
|
neededForUsers = true;
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
./fs.nix
|
./fs.nix
|
||||||
./net.nix
|
./net.nix
|
||||||
./users.nix
|
./users.nix
|
||||||
|
./secrets.nix
|
||||||
./services
|
./services
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -21,10 +22,6 @@
|
||||||
boot.loader.efi.canTouchEfiVariables = false;
|
boot.loader.efi.canTouchEfiVariables = false;
|
||||||
sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];
|
sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];
|
||||||
|
|
||||||
sops.secrets.duplicity_passphrase = {
|
|
||||||
sopsFile = ../../secrets/servo.yaml;
|
|
||||||
};
|
|
||||||
|
|
||||||
# both transmission and ipfs try to set different net defaults.
|
# both transmission and ipfs try to set different net defaults.
|
||||||
# we just use the most aggressive of the two here:
|
# we just use the most aggressive of the two here:
|
||||||
boot.kernel.sysctl = {
|
boot.kernel.sysctl = {
|
36
hosts/by-name/servo/secrets.nix
Normal file
36
hosts/by-name/servo/secrets.nix
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{ ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
sops.secrets."ddns_afraid" = {
|
||||||
|
sopsFile = ../../../secrets/servo.yaml;
|
||||||
|
};
|
||||||
|
|
||||||
|
sops.secrets."ddns_he" = {
|
||||||
|
sopsFile = ../../../secrets/servo.yaml;
|
||||||
|
};
|
||||||
|
|
||||||
|
sops.secrets."duplicity_passphrase" = {
|
||||||
|
sopsFile = ../../../secrets/servo.yaml;
|
||||||
|
};
|
||||||
|
|
||||||
|
sops.secrets."freshrss_passwd" = {
|
||||||
|
sopsFile = ../../../secrets/servo.yaml;
|
||||||
|
};
|
||||||
|
|
||||||
|
sops.secrets."pleroma_secrets" = {
|
||||||
|
sopsFile = ../../../secrets/servo.yaml;
|
||||||
|
};
|
||||||
|
sops.secrets."dovecot_passwd" = {
|
||||||
|
sopsFile = ../../../secrets/servo.yaml;
|
||||||
|
};
|
||||||
|
sops.secrets."mediawiki_pw" = {
|
||||||
|
sopsFile = ../../../secrets/servo.yaml;
|
||||||
|
};
|
||||||
|
|
||||||
|
sops.secrets."matrix_synapse_secrets" = {
|
||||||
|
sopsFile = ../../../secrets/servo.yaml;
|
||||||
|
};
|
||||||
|
sops.secrets."mautrix_signal_env" = {
|
||||||
|
sopsFile = ../../../secrets/servo/mautrix_signal_env.bin;
|
||||||
|
};
|
||||||
|
}
|
|
@ -24,8 +24,4 @@ lib.mkIf false
|
||||||
OnUnitActiveSec = "10min";
|
OnUnitActiveSec = "10min";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
sops.secrets."ddns_afraid" = {
|
|
||||||
sopsFile = ../../../secrets/servo.yaml;
|
|
||||||
};
|
|
||||||
}
|
}
|
|
@ -27,8 +27,4 @@ lib.mkIf false
|
||||||
OnUnitActiveSec = "10min";
|
OnUnitActiveSec = "10min";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
sops.secrets."ddns_he" = {
|
|
||||||
sopsFile = ../../../secrets/servo.yaml;
|
|
||||||
};
|
|
||||||
}
|
}
|
|
@ -11,8 +11,7 @@
|
||||||
|
|
||||||
{ config, lib, pkgs, sane-lib, ... }:
|
{ config, lib, pkgs, sane-lib, ... }:
|
||||||
{
|
{
|
||||||
sops.secrets.freshrss_passwd = {
|
sops.secrets."freshrss_passwd" = {
|
||||||
sopsFile = ../../../secrets/servo.yaml;
|
|
||||||
owner = config.users.users.freshrss.name;
|
owner = config.users.users.freshrss.name;
|
||||||
mode = "0400";
|
mode = "0400";
|
||||||
};
|
};
|
|
@ -131,8 +131,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
sops.secrets.matrix_synapse_secrets = {
|
sops.secrets."matrix_synapse_secrets" = {
|
||||||
sopsFile = ../../../../secrets/servo.yaml;
|
|
||||||
owner = config.users.users.matrix-synapse.name;
|
owner = config.users.users.matrix-synapse.name;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -25,8 +25,7 @@
|
||||||
{ user = "mautrix-signal"; group = "mautrix-signal"; directory = "/var/lib/mautrix-signal"; }
|
{ user = "mautrix-signal"; group = "mautrix-signal"; directory = "/var/lib/mautrix-signal"; }
|
||||||
];
|
];
|
||||||
|
|
||||||
sops.secrets.mautrix_signal_env = {
|
sops.secrets."mautrix_signal_env" = {
|
||||||
sopsFile = ../../../../secrets/servo/mautrix_signal_env.bin;
|
|
||||||
format = "binary";
|
format = "binary";
|
||||||
mode = "0440";
|
mode = "0440";
|
||||||
owner = config.users.users.mautrix-signal.name;
|
owner = config.users.users.mautrix-signal.name;
|
|
@ -17,5 +17,5 @@
|
||||||
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."nixcache" = "native";
|
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."nixcache" = "native";
|
||||||
|
|
||||||
sane.services.nixserve.enable = true;
|
sane.services.nixserve.enable = true;
|
||||||
sane.services.nixserve.sopsFile = ../../../secrets/servo.yaml;
|
sane.services.nixserve.sopsFile = ../../../../secrets/servo.yaml;
|
||||||
}
|
}
|
|
@ -179,8 +179,7 @@
|
||||||
|
|
||||||
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."fed" = "native";
|
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."fed" = "native";
|
||||||
|
|
||||||
sops.secrets.pleroma_secrets = {
|
sops.secrets."pleroma_secrets" = {
|
||||||
sopsFile = ../../../secrets/servo.yaml;
|
|
||||||
owner = config.users.users.pleroma.name;
|
owner = config.users.users.pleroma.name;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -197,8 +197,7 @@ in
|
||||||
# }
|
# }
|
||||||
];
|
];
|
||||||
|
|
||||||
sops.secrets.dovecot_passwd = {
|
sops.secrets."dovecot_passwd" = {
|
||||||
sopsFile = ../../../secrets/servo.yaml;
|
|
||||||
owner = config.users.users.dovecot2.name;
|
owner = config.users.users.dovecot2.name;
|
||||||
# TODO: debug why mail can't be sent without this being world-readable
|
# TODO: debug why mail can't be sent without this being world-readable
|
||||||
mode = "0444";
|
mode = "0444";
|
|
@ -8,7 +8,6 @@ lib.mkIf false
|
||||||
{
|
{
|
||||||
sops.secrets."mediawiki_pw" = {
|
sops.secrets."mediawiki_pw" = {
|
||||||
owner = config.users.users.mediawiki.name;
|
owner = config.users.users.mediawiki.name;
|
||||||
sopsFile = ../../../secrets/servo.yaml;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
services.mediawiki.enable = true;
|
services.mediawiki.enable = true;
|
|
@ -5,7 +5,7 @@
|
||||||
./cross.nix
|
./cross.nix
|
||||||
./feeds.nix
|
./feeds.nix
|
||||||
./fs.nix
|
./fs.nix
|
||||||
./hardware
|
./hardware.nix
|
||||||
./i2p.nix
|
./i2p.nix
|
||||||
./ids.nix
|
./ids.nix
|
||||||
./machine-id.nix
|
./machine-id.nix
|
||||||
|
|
|
@ -1,24 +1,33 @@
|
||||||
{ config, lib, sane-data, sane-lib, ... }:
|
{ config, lib, sane-data, sane-lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
inherit (builtins) head map mapAttrs tail;
|
||||||
|
inherit (lib) concatStringsSep mkMerge reverseList;
|
||||||
|
in
|
||||||
{
|
{
|
||||||
sane.ssh.pubkeys =
|
sane.ssh.pubkeys =
|
||||||
let
|
let
|
||||||
# path is a DNS-style path like [ "org" "uninsane" "root" ]
|
# path is a DNS-style path like [ "org" "uninsane" "root" ]
|
||||||
keyNameForPath = path:
|
keyNameForPath = path:
|
||||||
let
|
let
|
||||||
rev = lib.reverseList path;
|
rev = reverseList path;
|
||||||
name = builtins.head rev;
|
name = head rev;
|
||||||
host = lib.concatStringsSep "." (builtins.tail rev);
|
host = concatStringsSep "." (tail rev);
|
||||||
in
|
in
|
||||||
"${name}@${host}";
|
"${name}@${host}";
|
||||||
|
|
||||||
# [{ path :: [String], value :: String }] for the keys we want to install
|
# [{ path :: [String], value :: String }] for the keys we want to install
|
||||||
globalKeys = sane-lib.flattenAttrs sane-data.keys;
|
globalKeys = sane-lib.flattenAttrs sane-data.keys;
|
||||||
localKeys = sane-lib.flattenAttrs sane-data.keys.org.uninsane.local;
|
domainKeys = sane-lib.flattenAttrs (
|
||||||
in lib.mkMerge (builtins.map
|
mapAttrs (host: cfg: {
|
||||||
|
colin = cfg.ssh.user_pubkey;
|
||||||
|
root = cfg.ssh.host_pubkey;
|
||||||
|
}) config.sane.hosts
|
||||||
|
);
|
||||||
|
in mkMerge (map
|
||||||
({ path, value }: {
|
({ path, value }: {
|
||||||
"${keyNameForPath path}" = value;
|
"${keyNameForPath path}" = lib.mkIf (value != null) value;
|
||||||
})
|
})
|
||||||
(globalKeys ++ localKeys)
|
(globalKeys ++ domainKeys)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
# trampoline from flake.nix into the specific host definition, while doing a tiny bit of common setup
|
# trampoline from flake.nix into the specific host definition, while doing a tiny bit of common setup
|
||||||
|
|
||||||
|
# args from flake-level `import`
|
||||||
{ hostName, localSystem }:
|
{ hostName, localSystem }:
|
||||||
|
|
||||||
|
# module args
|
||||||
{ ... }:
|
{ ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./${hostName}
|
./by-name/${hostName}
|
||||||
./common
|
./common
|
||||||
|
./modules
|
||||||
];
|
];
|
||||||
|
|
||||||
networking.hostName = hostName;
|
networking.hostName = hostName;
|
||||||
|
|
8
hosts/modules/default.nix
Normal file
8
hosts/modules/default.nix
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{ ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./hardware
|
||||||
|
./hosts.nix
|
||||||
|
];
|
||||||
|
}
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./all.nix
|
|
||||||
./x86_64.nix
|
./x86_64.nix
|
||||||
];
|
];
|
||||||
}
|
}
|
|
@ -1,8 +1,7 @@
|
||||||
{ lib, pkgs, ... }:
|
{ lib, pkgs, ... }:
|
||||||
|
|
||||||
with lib;
|
|
||||||
{
|
{
|
||||||
config = mkIf (pkgs.system == "x86_64-linux") {
|
config = lib.mkIf (pkgs.system == "x86_64-linux") {
|
||||||
boot.initrd.availableKernelModules = [
|
boot.initrd.availableKernelModules = [
|
||||||
"xhci_pci" "ahci" "sd_mod" "sdhci_pci" # nixos-generate-config defaults
|
"xhci_pci" "ahci" "sd_mod" "sdhci_pci" # nixos-generate-config defaults
|
||||||
"usb_storage" # rpi needed this to boot from usb storage, i think.
|
"usb_storage" # rpi needed this to boot from usb storage, i think.
|
92
hosts/modules/hosts.nix
Normal file
92
hosts/modules/hosts.nix
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
inherit (lib) types mkOption;
|
||||||
|
cfg = config.sane.hosts;
|
||||||
|
|
||||||
|
host = types.submodule ({ config, ... }: {
|
||||||
|
options = {
|
||||||
|
is-target = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
description = ''
|
||||||
|
true if the config is being built for deployment to this host.
|
||||||
|
set internally.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
roles.server = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
whether this machine is a server for domain-level services like wireguard, rss aggregation, etc.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
roles.client = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
whether this machine is a client to domain-level services like wireguard, rss aggregation, etc.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
ssh.user_pubkey = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
description = ''
|
||||||
|
ssh pubkey that the primary user of this machine will use when connecting to other machines.
|
||||||
|
e.g. "ssh-ed25519 AAAA<base64>".
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
ssh.host_pubkey = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
description = ''
|
||||||
|
ssh pubkey which this host will present to connections initiated against it.
|
||||||
|
e.g. "ssh-ed25519 AAAA<base64>".
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
# user should set `sane.hosts.target = config.sane.hosts."${host}"` to build for it.
|
||||||
|
is-target = cfg ? "target" && cfg.target == config;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
sane.hosts = mkOption {
|
||||||
|
type = types.attrsOf host;
|
||||||
|
default = {};
|
||||||
|
description = ''
|
||||||
|
map of hostname => attrset of information specific to that host,
|
||||||
|
like its ssh pubkey, etc.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
sane.hosts."desko" = {
|
||||||
|
ssh.user_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPU5GlsSfbaarMvDA20bxpSZGWviEzXGD8gtrIowc1pX";
|
||||||
|
ssh.host_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFw9NoRaYrM6LbDd3aFBc4yyBlxGQn8HjeHd/dZ3CfHk";
|
||||||
|
roles.client = true;
|
||||||
|
};
|
||||||
|
sane.hosts."lappy" = {
|
||||||
|
ssh.user_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDpmFdNSVPRol5hkbbCivRhyeENzb9HVyf9KutGLP2Zu";
|
||||||
|
ssh.host_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILSJnqmVl9/SYQ0btvGb0REwwWY8wkdkGXQZfn/1geEc";
|
||||||
|
roles.client = true;
|
||||||
|
};
|
||||||
|
sane.hosts."moby" = {
|
||||||
|
ssh.user_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICrR+gePnl0nV/vy7I5BzrGeyVL+9eOuXHU1yNE3uCwU";
|
||||||
|
ssh.host_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO1N/IT3nQYUD+dBlU1sTEEVMxfOyMkrrDeyHcYgnJvw";
|
||||||
|
roles.client = true;
|
||||||
|
};
|
||||||
|
sane.hosts."servo" = {
|
||||||
|
ssh.user_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPS1qFzKurAdB9blkWomq8gI1g0T3sTs9LsmFOj5VtqX";
|
||||||
|
ssh.host_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOfdSmFkrVT6DhpgvFeQKm3Fh9VKZ9DbLYOPOJWYQ0E8";
|
||||||
|
roles.server = true;
|
||||||
|
};
|
||||||
|
sane.hosts."rescue" = {
|
||||||
|
ssh.user_pubkey = null;
|
||||||
|
ssh.host_pubkey = null;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -5,24 +5,9 @@
|
||||||
org.uninsane = rec {
|
org.uninsane = rec {
|
||||||
root = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOfdSmFkrVT6DhpgvFeQKm3Fh9VKZ9DbLYOPOJWYQ0E8";
|
root = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOfdSmFkrVT6DhpgvFeQKm3Fh9VKZ9DbLYOPOJWYQ0E8";
|
||||||
git.root = root;
|
git.root = root;
|
||||||
|
|
||||||
local = {
|
|
||||||
# machine aliases i specify on my lan; not actually asserted as DNS
|
|
||||||
desko.colin = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPU5GlsSfbaarMvDA20bxpSZGWviEzXGD8gtrIowc1pX";
|
|
||||||
desko.root = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFw9NoRaYrM6LbDd3aFBc4yyBlxGQn8HjeHd/dZ3CfHk";
|
|
||||||
|
|
||||||
lappy.colin = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDpmFdNSVPRol5hkbbCivRhyeENzb9HVyf9KutGLP2Zu";
|
|
||||||
lappy.root = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILSJnqmVl9/SYQ0btvGb0REwwWY8wkdkGXQZfn/1geEc";
|
|
||||||
|
|
||||||
moby.colin = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICrR+gePnl0nV/vy7I5BzrGeyVL+9eOuXHU1yNE3uCwU";
|
|
||||||
moby.root = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO1N/IT3nQYUD+dBlU1sTEEVMxfOyMkrrDeyHcYgnJvw";
|
|
||||||
|
|
||||||
servo.colin = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPS1qFzKurAdB9blkWomq8gI1g0T3sTs9LsmFOj5VtqX";
|
|
||||||
servo.root = root;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
com.github = rec {
|
com.github = {
|
||||||
# documented here: <https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints>
|
# documented here: <https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints>
|
||||||
# Github actually uses multiple keys -- one per format
|
# Github actually uses multiple keys -- one per format
|
||||||
root = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl";
|
root = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl";
|
||||||
|
|
|
@ -57,7 +57,7 @@ in
|
||||||
options = {
|
options = {
|
||||||
sane.ssh.pubkeys = mkOption {
|
sane.ssh.pubkeys = mkOption {
|
||||||
type = types.attrsOf coercedToKey;
|
type = types.attrsOf coercedToKey;
|
||||||
default = [];
|
default = {};
|
||||||
description = ''
|
description = ''
|
||||||
mapping from "user@host" to pubkey.
|
mapping from "user@host" to pubkey.
|
||||||
'';
|
'';
|
||||||
|
|
Loading…
Reference in New Issue
Block a user