{ 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; }; }; }; }) ]; }