main
1{
2 den,
3 lib,
4 ...
5}: let
6 hostKeys = [
7 {
8 path = "/etc/ssh/ssh_host_ed25519_key";
9 type = "ed25519";
10 }
11 {
12 path = "/etc/ssh/ssh_host_rsa_key";
13 type = "rsa";
14 bit = 4096;
15 }
16 ];
17
18 hostKeyFiles = builtins.concatMap (key: [key.path] ++ ["${key.path}.pub"]) hostKeys;
19in {
20 den.aspects.core.includes = [den.aspects.core.openssh];
21
22 den.aspects.core.openssh = {
23 settings.host = {
24 server = {
25 enable = lib.mkEnableOption "Whether to start OpenSSH server";
26 port = lib.mkOption {
27 type = lib.types.port;
28 default = 22;
29 };
30 };
31 authorizedKeys = lib.mkOption {
32 type = lib.types.listOf lib.types.str;
33 default = [];
34 description = "SSH authorized keys for root on this host.";
35 };
36 };
37
38 persist = {
39 files =
40 map (file: {
41 inherit file;
42 mode = "06${
43 if lib.strings.hasSuffix ".pub" file
44 then "44"
45 else "00"
46 }";
47 })
48 hostKeyFiles;
49 };
50 persistHome = {
51 directories = [
52 {
53 directory = ".ssh";
54 mode = "0700";
55 }
56 ];
57 };
58
59 nixos = {host, ...}: {
60 services.openssh = {
61 enable = host.settings.core.openssh.server.enable;
62 # Serve on 22 port for Tailscale
63 ports = lib.unique [22 host.settings.core.openssh.server.port];
64 generateHostKeys = true;
65 inherit hostKeys;
66 settings = {
67 PermitRootLogin = "prohibit-password";
68 PasswordAuthentication = false;
69 };
70 # Mannualy open filewall
71 openFirewall = false;
72 };
73
74 users.users.root.openssh.authorizedKeys.keys =
75 host.settings.core.openssh.authorizedKeys;
76
77 networking.firewall.allowedTCPPorts = [
78 host.settings.core.openssh.server.port
79 ];
80
81 environment.enableAllTerminfo = host.settings.core.openssh.server.enable;
82 };
83
84 provides.to-users = {
85 user = {user, ...}: {
86 openssh.authorizedKeys.keys = user.identity.sshKeys;
87 };
88 };
89 };
90}