# SSH hardening configuration for production security { config, lib, ... }: with lib; { options.security.ssh-hardening = { enable = mkEnableOption "SSH security hardening"; level = mkOption { type = types.enum [ "development" "production" "paranoid" ]; default = "production"; description = "Security level for SSH configuration"; }; allowUsers = mkOption { type = types.listOf types.str; default = [ "admin" ]; description = "Users allowed to SSH"; }; maxAuthTries = mkOption { type = types.int; default = 3; description = "Maximum authentication attempts"; }; maxSessions = mkOption { type = types.int; default = 10; description = "Maximum concurrent sessions"; }; }; config = mkIf config.security.ssh-hardening.enable { services.openssh = { enable = true; settings = { # Authentication settings PermitRootLogin = if config.security.ssh-hardening.level == "development" then "prohibit-password" else "no"; PasswordAuthentication = false; KbdInteractiveAuthentication = false; ChallengeResponseAuthentication = false; # Security settings PermitEmptyPasswords = false; UsePAM = false; X11Forwarding = false; AllowAgentForwarding = config.security.ssh-hardening.level == "development"; AllowTcpForwarding = config.security.ssh-hardening.level != "paranoid"; GatewayPorts = "no"; # User restrictions AllowUsers = config.security.ssh-hardening.allowUsers; # Protocol settings Protocol = 2; LogLevel = if config.security.ssh-hardening.level == "paranoid" then "VERBOSE" else "INFO"; # Timing settings LoginGraceTime = 30; ClientAliveInterval = 300; ClientAliveCountMax = 2; TCPKeepAlive = false; # Crypto settings for security Ciphers = [ "chacha20-poly1305@openssh.com" "aes256-gcm@openssh.com" "aes128-gcm@openssh.com" "aes256-ctr" "aes192-ctr" "aes128-ctr" ]; Macs = [ "hmac-sha2-256-etm@openssh.com" "hmac-sha2-512-etm@openssh.com" "hmac-sha2-256" "hmac-sha2-512" ]; KexAlgorithms = [ "curve25519-sha256@libssh.org" "diffie-hellman-group16-sha512" "diffie-hellman-group18-sha512" "diffie-hellman-group14-sha256" ]; }; extraConfig = '' # Rate limiting MaxAuthTries ${toString config.security.ssh-hardening.maxAuthTries} MaxSessions ${toString config.security.ssh-hardening.maxSessions} MaxStartups 10:30:60 # Banner ${optionalString (config.security.ssh-hardening.level != "development") '' Banner /etc/ssh/banner ''} # Additional security ${optionalString (config.security.ssh-hardening.level == "paranoid") '' StrictModes yes IgnoreRhosts yes HostbasedAuthentication no PermitUserEnvironment no Compression delayed ''} ''; }; # Create SSH banner for non-development environments environment.etc."ssh/banner" = mkIf (config.security.ssh-hardening.level != "development") { text = '' ################################################################################ # NOTICE # # # # This system is for authorized users only. All activity may be monitored # # and recorded. Unauthorized access is prohibited. # # # ################################################################################ ''; mode = "0644"; }; }; }