{
  lib,
  config,
  ...
}: {
  services.openssh = {
    enable = true;
    settings = {
      KbdInteractiveAuthentication = false;
      Ciphers = [
        "aes256-gcm@openssh.com"
      ];
      # Use key exchange algorithms recommended by `nixpkgs#ssh-audit`
      KexAlgorithms = [
        "curve25519-sha256"
        "curve25519-sha256@libssh.org"
        "diffie-hellman-group16-sha512"
        "diffie-hellman-group18-sha512"
        "sntrup761x25519-sha512@openssh.com"
      ];
      PasswordAuthentication = false;
      StreamLocalBindUnlink = true; # unbind gnupg sockets if they exists
      UseDns = false;
      X11Forwarding = false;
    };
    hostKeys =
      if config.weinturm.impermanence.enable
      then [
        {
          type = "ed25519";
          path = "/persist/etc/ssh/ssh_host_ed25519_key";
        }
      ]
      else [
        {
          type = "ed25519";
          path = "/etc/ssh/ssh_host_ed25519_key";
        }
      ];
    authorizedKeysFiles = lib.mkIf (!config.services.gitlab.enable) (lib.mkForce ["/etc/ssh/authorized_keys.d/%u"]);
  };

  networking.nftables.tables."nixos-fw".content = lib.mkOrder 20 ''
    set ssh-ratelimit-v4 {
      type ipv4_addr
      timeout 60s
      flags dynamic
    }

    set ssh-ratelimit-v6 {
      type ipv6_addr
      timeout 60s
      flags dynamic
    }
  '';

  # Implement connection rate limit
  services.openssh.openFirewall = false;
  networking.firewall.extraInputRules = lib.mkOrder 5 (
    let
      ports = builtins.concatStringsSep ", " (map builtins.toString config.services.openssh.ports);
    in ''
      tcp dport { ${ports} } update @ssh-ratelimit-v4 { ip saddr limit rate 1/second burst 10 packets } accept
      tcp dport { ${ports} } update @ssh-ratelimit-v6 { ip6 saddr limit rate 1/second burst 10 packets } accept
    ''
  );
}
