summaryrefslogtreecommitdiff
path: root/modules/openssh.nix
blob: 470b6c9080bac56ee934ae8e9d5afc0f13a9d954 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
{
  config,
  lib,
  pkgs,
  ...
}:
with lib;
let
  cfg = config.nixfiles.modules.openssh;
in
{
  options.nixfiles.modules.openssh = {
    client.enable = mkEnableOption "OpenSSH client";
    server = {
      enable = mkEnableOption "OpenSSH server";

      port = mkOption {
        description = "OpenSSH server port.";
        type = types.port;
        default = 22022; # Port 22 should be occupied by a tarpit.
      };
    };
  };

  config = mkMerge [
    (mkIf cfg.client.enable {
      hm = {
        home.packages = with pkgs; [
          mosh
          sshfs
          sshpass
        ];

        programs.ssh = {
          enable = true;

          hashKnownHosts = true;

          controlMaster = "auto";
          controlPersist = "24H";

          serverAliveCountMax = 30;
          serverAliveInterval = 60;

          matchBlocks =
            let
              mkBlock =
                name:
                {
                  hostname ? name,
                  port ? 22022, # NOTE This is not the default OpenSSH port.
                  user ? my.username,
                  identityFile ? "${config.my.home}/.ssh/${my.username}_${my.ssh.type}",
                  extraAttrs ? { },
                }:
                nameValuePair name (
                  {
                    inherit
                      hostname
                      port
                      user
                      identityFile
                      ;
                  }
                  // extraAttrs
                );

              internalServers = mapAttrs' mkBlock (
                mapAttrs (name: _: { hostname = "${name}.${my.domain.shire}"; }) (
                  filterAttrs (_: attr: hasAttr "wireguard" attr && attr.isHeadless) my.configurations
                )
              );
            in
            internalServers
            // (mapAttrs' mkBlock {
              gitolite = {
                user = "git";
                hostname = "git.${my.domain.shire}";
              };
            });
        };
      };
    })
    (mkIf cfg.server.enable {
      ark.files = [
        "/etc/ssh/ssh_host_ed25519_key"
        "/etc/ssh/ssh_host_ed25519_key.pub"
        "/etc/ssh/ssh_host_rsa_key"
        "/etc/ssh/ssh_host_rsa_key.pub"
      ];

      programs.mosh.enable = true;

      services = {
        openssh = {
          enable = true;
          ports = [ cfg.server.port ];
          settings = {
            ClientAliveCountMax = 3;
            ClientAliveInterval = 60;
            KbdInteractiveAuthentication = false;
            MaxAuthTries = 3;
            PasswordAuthentication = false;
            PermitRootLogin = mkForce "no";
          };
        };

        fail2ban.jails.sshd = {
          enabled = true;
          settings = {
            mode = "aggressive";
            inherit (cfg.server) port;
          };
        };
      };
    })
  ];
}