Skip to content

SSHD Ansible Role

An Ansible role to configure the OpenSSH server (sshd) on Debian-based systems.

Features

  • Configure sshd settings (e.g., port, authentication, logging, session behavior)
  • Install and manage openssh-server
  • Lightweight validation (checks sshd configuration syntax before applying)
  • Support for per-user/group/address SSH configurations using Match blocks

Installation

Add the following to your requirements.yml:

roles:
  - name: sshd
    src: https://gitlab.com/niclas-zone/tools/ansible/roles/sshd.git
    version: 1.13.0
    scm: git

Then install:

ansible-galaxy install -r requirements.yml --force

Role Variables

General

Variable Default Type Description
ansible_managed_warning "This file is managed by Ansible. Manual changes will be overwritten." string Comment header written into every templated file to signal it is Ansible-managed.
ansible_role_repository https://gitlab.com/niclas-zone/tools/ansible/roles/sshd string Source repository URL; embedded in the managed-file header so engineers know where to make changes.
sshd_enabled true boolean Start and enable the sshd systemd service. Set to false to install the package but leave it off.
sshd_validate_config true boolean Run sshd -t to validate the generated config before restarting the service. Disable only in test environments where the binary is unavailable.
sshd_include_dir "/etc/ssh/sshd_config.d" string Drop-in directory included at the end of sshd_config. Files here are loaded in lexicographic order.

Network & Binding

Variable Default Type Description
sshd_port 22 integer TCP port sshd listens on.
sshd_address_family "any" string Restrict the socket address family. any binds on both IPv4 and IPv6; inet for IPv4-only; inet6 for IPv6-only. Set to null to omit the directive entirely.
sshd_listen_addresses [] list[str] Explicit IP addresses to bind. Empty list keeps the default (bind all interfaces).
sshd_host_keys ["/etc/ssh/ssh_host_rsa_key", "/etc/ssh/ssh_host_ecdsa_key", "/etc/ssh/ssh_host_ed25519_key"] list[str] Private host key files loaded on startup. Empty list falls back to OpenSSH's compiled-in defaults (commented out).
sshd_use_dns false boolean Resolve client IPs to hostnames during authentication. Disabled by default to avoid slow logins when DNS is unreachable.

Logging

Variable Default Type Description
sshd_syslog_facility "AUTH" string Syslog facility used for log messages. AUTH routes SSH logs to the standard authentication log (/var/log/auth.log on Debian).
sshd_log_level "VERBOSE" string Log verbosity. VERBOSE additionally logs the fingerprint of the public key used in each successful authentication — useful for auditing.

Authentication

Variable Default Type Description
sshd_login_grace_time "60" string Seconds the server waits for a client to complete authentication after connecting. The connection is dropped after this period regardless of authentication state.
sshd_permit_root_login "no" string Controls root login. no blocks all root logins; prohibit-password allows key-based only; yes allows everything (strongly discouraged).
sshd_strict_modes true boolean Reject logins if the user's ~/.ssh directory or authorized keys file has wrong ownership or permissions (e.g., world-writable). Prevents trivially compromised key files.
sshd_max_auth_tries 2 integer Maximum authentication attempts per connection before the server closes it. Limits brute-force exposure per TCP session.
sshd_max_sessions 10 integer Maximum simultaneous multiplexed sessions per connection (SSH multiplexing / ControlMaster).
sshd_password_authentication true boolean Allow password-based authentication. Set to false when all users authenticate via public keys.
sshd_pubkey_authentication true boolean Allow public key authentication. This is the recommended primary method.
sshd_kbd_interactive_authentication false boolean Allow keyboard-interactive authentication (e.g., PAM challenge-response). Disabled by default; enabling it alongside PAM can enable 2FA prompts.
sshd_permit_empty_passwords false boolean Allow logins to accounts with no password set. Never enable this on any system reachable from a network.
sshd_authorized_keys_file [".ssh/authorized_keys"] list[str] Files containing public keys for key-based authentication, relative to the user's home directory.
sshd_authorized_principals_file "none" string File listing allowed certificate principals per user. none disables certificate-principal matching.
sshd_authorized_keys_command "none" string External command to fetch authorized keys (e.g., from LDAP). none disables the feature.
sshd_authorized_keys_command_user "nobody" string Unprivileged user under which AuthorizedKeysCommand runs.
sshd_hostbased_authentication false boolean Allow host-based authentication (trust relationships between hosts). Disabled by default; rarely appropriate on modern systems.
sshd_ignore_user_known_hosts false boolean Ignore ~/.ssh/known_hosts during host-based authentication.
sshd_ignore_rhosts true boolean Ignore ~/.rhosts and ~/.shosts. Always keep true; .rhosts authentication is insecure and obsolete.

User Access Control

Variable Default Type Description
sshd_allow_users [] list[str] Explicit list of users permitted to log in. When non-empty, all other users are implicitly denied. Supports wildcards and @group notation. Empty = allow all.
sshd_deny_users [] list[str] Users explicitly denied SSH access. Applied before AllowUsers. Supports wildcards.
sshd_allow_groups [] list[str] Groups whose members are permitted to log in. When non-empty, users not in any listed group are denied. Empty = allow all.
sshd_deny_groups [] list[str] Groups whose members are denied SSH access.

Kerberos & GSSAPI

Variable Default Type Description
sshd_kerberos_authentication false boolean Authenticate against a Kerberos KDC instead of (or in addition to) local passwords.
sshd_kerberos_or_local_passwd true boolean Fall back to local password check if Kerberos authentication fails.
sshd_kerberos_ticket_cleanup true boolean Destroy the user's Kerberos ticket cache on logout.
sshd_kerberos_get_afs_token false boolean Obtain an AFS token after Kerberos authentication. Only rendered when true; removed in OpenSSH 9.0+.
sshd_gssapi_authentication false boolean Enable GSSAPI (Kerberos SSO) authentication.
sshd_gssapi_cleanup_credentials true boolean Destroy GSSAPI credentials on logout.
sshd_gssapi_strict_acceptor_check true boolean Enforce strict matching of the GSSAPI acceptor name to the server's hostname.
sshd_gssapi_key_exchange false boolean Allow GSSAPI-based key exchange (authenticates both host and user via Kerberos).

PAM

Variable Default Type Description
sshd_use_pam true boolean Enable PAM for account processing and session setup (e.g., pam_limits, pam_motd, pam_unix). Required when using PAM-based 2FA or account restrictions.

Forwarding

Variable Default Type Description
sshd_disable_forwarding true boolean Single directive that disables all forwarding (X11, agent, TCP, StreamLocal) at once. When true, overrides the individual forwarding variables below.
sshd_allow_agent_forwarding false boolean Allow SSH agent forwarding (ssh -A). Unnecessary on most servers and can be abused if the server is compromised; keep false unless specifically needed.
sshd_allow_tcp_forwarding false boolean Allow TCP port forwarding / tunneling (ssh -L/-R). Disabled by default to prevent the SSH daemon from being used as a proxy or pivot.
sshd_gateway_ports false boolean Allow remote port forwards to bind on non-loopback interfaces (i.e., accept connections from other hosts). Keep false to restrict forwarded ports to localhost only.
sshd_permit_tunnel false boolean Allow tun/tap device tunneling (ssh -w). Disabled because it grants network-layer access.

X11

Variable Default Type Description
sshd_x11_forwarding false boolean Enable X11 display forwarding. Disabled by default; X11 forwarding gives the remote server access to the local display.
sshd_x11_display_offset 10 integer Offset added to the X11 display number allocated for forwarding sessions (:10, :11, …). Avoids conflicts with local displays.
sshd_x11_use_localhost true boolean Bind the forwarded X11 socket to localhost only. Prevents other hosts from connecting to the forwarded display.

Session Behavior

Variable Default Type Description
sshd_permit_tty true boolean Allow the allocation of a pseudo-terminal (PTY). Set to false for SFTP-only accounts where interactive shells are unwanted.
sshd_print_motd false boolean Print /etc/motd on login. Disabled here because PAM (pam_motd) typically handles this; enabling both causes duplicate output.
sshd_print_last_log true boolean Show the date/time and source IP of the user's last login on each login. Helps users detect unexpected access.
sshd_permit_user_environment false boolean Allow users to set environment variables via ~/.ssh/environment. Disabled because it can be used to bypass ForceCommand or PATH restrictions.
sshd_accept_env see below list[str] Environment variables the client is allowed to pass through to the session. Restricted to locale and color variables by default.
sshd_chroot_directory "none" string chroot(2) the session into this directory after authentication. none disables chrooting. Useful for restricting SFTP users to a specific directory tree.
sshd_compression "delayed" string SSH compression. delayed activates compression only after authentication, preventing CPU exhaustion from unauthenticated compressed data. yes compresses from the start; no disables compression.
sshd_rekey_limit "default none" string Force renegotiation of session keys after a data volume (default = 1 GB) or time (none = no time limit). default none uses OpenSSH's built-in thresholds.
sshd_version_addendum "none" string Text appended to the SSH protocol banner (e.g., SSH-2.0-OpenSSH_9.2 <addendum>). none suppresses the addendum, reducing version disclosure to unauthenticated scanners.
sshd_banner "/etc/issue.net" string Path to a file whose contents are displayed to the client before authentication. Typically contains a legal warning.

Session Keepalive

Variable Default Type Description
sshd_tcp_keep_alive true boolean Enable OS-level TCP keepalives (SO_KEEPALIVE). The kernel sends TCP probes independently of SSH. Helps detect truly dead TCP connections and keeps NAT/firewall table entries alive. These probes are spoofable at the network layer.
sshd_client_alive_interval 60 integer Seconds between encrypted keepalive probes sent from the server to the client through the SSH channel. 0 disables SSH-level keepalives entirely. These probes are encrypted and cannot be spoofed.
sshd_client_alive_count_max 0 integer How many consecutive unanswered keepalives before the server terminates the session. 0 (default) disables auto-disconnect — keepalives are still sent (maintaining NAT entries) but the session is never dropped. Set to a positive integer to re-enable disconnect (e.g., 3 = disconnect after 3 × 60 s = 3 min of silence).

Connection Throttling & Limits

Variable Default Type Description
sshd_max_startups "10:30:60" string Throttle unauthenticated connections using start:rate:full format. At 10 unauthenticated connections, begin randomly dropping new ones at 30% probability; hard-reject all above 60. Protects against connection floods.
sshd_pid_file "/run/sshd.pid" string Path to the PID file written by the sshd master process. Used by init scripts and systemd to manage the service.

Subsystems & Other

Variable Default Type Description
sshd_subsystem_sftp "/usr/lib/openssh/sftp-server" string Path to the SFTP server binary. This enables the sftp subsystem (sftp user@host).
sshd_match_blocks [] list[dict] Per-user/group/address override blocks. Each entry becomes a Match stanza in sshd_config. See below for structure.

Cryptographic Algorithms

Variable Default Type Description
sshd_kex_algorithms see below list[str] Allowed key exchange algorithms, ordered by preference. Restricts to modern ECDH and DH-group-exchange methods; removes weaker SHA-1 based algorithms.
sshd_ciphers see below list[str] Symmetric ciphers allowed for bulk encryption, ordered by preference. Prefers AEAD modes (ChaCha20, AES-GCM) over CTR modes.
sshd_macs see below list[str] Message authentication codes for integrity protection, ordered by preference. Prefers ETM (Encrypt-then-MAC) variants.

Session Keepalive Behavior

Two complementary mechanisms prevent idle session disconnections:

OS-level TCP keepalives (TCPKeepAlive yes): The kernel sends TCP-layer probes at intervals controlled by the OS (net.ipv4.tcp_keepalive_*). These operate below the SSH layer — spoofable but effective at keeping NAT/firewall table entries alive and at detecting broken TCP stacks.

SSH-level encrypted keepalives (ClientAliveInterval 60 + ClientAliveCountMax 0): The SSH daemon sends a null packet through the encrypted channel every 60 seconds. Because ClientAliveCountMax is 0, the server never disconnects the client regardless of how many keepalives go unanswered. This prevents accidental dropouts on flaky networks (Wi-Fi, VPN, high-latency links).

To enable automatic cleanup of truly dead sessions, set sshd_client_alive_count_max to a positive integer:

sshd_client_alive_interval: 60
sshd_client_alive_count_max: 3   # disconnect after 3 × 60 s = 3 min of silence

Default Cryptographic Algorithms

The role includes hardened defaults for cryptographic algorithms:

sshd_kex_algorithms:
  - "curve25519-sha256@libssh.org"
  - "ecdh-sha2-nistp521"
  - "ecdh-sha2-nistp384"
  - "ecdh-sha2-nistp256"
  - "diffie-hellman-group-exchange-sha256"

sshd_ciphers:
  - "chacha20-poly1305@openssh.com"
  - "aes256-gcm@openssh.com"
  - "aes128-gcm@openssh.com"
  - "aes256-ctr"
  - "aes192-ctr"
  - "aes128-ctr"

sshd_macs:
  - "hmac-sha2-512-etm@openssh.com"
  - "hmac-sha2-256-etm@openssh.com"
  - "hmac-sha2-512"
  - "hmac-sha2-256"

Default Environment Variables

sshd_accept_env:
  - "LANG"
  - "LC_*"
  - "COLORTERM"
  - "NO_COLOR"

Per-User/Group/Address Configurations

The sshd_match_blocks variable allows you to define SSH configurations that apply only to specific users, groups, or addresses. Each block is a dictionary with:

  • name: (required) A descriptive comment for the Match block
  • match: (required) The Match criteria (e.g., User, Group, Address, or combinations)
  • settings: (required) A dictionary of SSH settings to apply for this Match block

Example Playbooks

Basic: configure sshd with defaults

---
- hosts: servers
  become: true
  roles:
    - role: sshd

Custom sshd settings

---
- hosts: servers
  become: true
  roles:
    - role: sshd
      vars:
        sshd_port: 2222
        sshd_permit_root_login: "prohibit-password"
        sshd_password_authentication: false
        sshd_pubkey_authentication: true
        sshd_max_auth_tries: 3
        sshd_max_sessions: 5
        sshd_x11_forwarding: false

Minimal configuration (disable password authentication)

---
- hosts: servers
  become: true
  roles:
    - role: sshd
      vars:
        sshd_password_authentication: false
        sshd_pubkey_authentication: true

Per-user SSH configurations

---
- hosts: servers
  become: true
  roles:
    - role: sshd
      vars:
        # Global settings
        sshd_permit_root_login: "no"
        sshd_password_authentication: false

        # Per-user/group/address overrides using Match blocks
        sshd_match_blocks:
          # Restrict root login from a specific IP
          - name: "Restrict root login from admin host"
            match: "Address 10.0.2.31"
            settings:
              PermitRootLogin: "yes"

          # Allow password authentication for specific user from subnet
          - name: "Allow password auth for admin user"
            match: "User admin Address 10.0.2.*"
            settings:
              PasswordAuthentication: "yes"

          # Allow password authentication only for specific group
          - name: "Allow password for system administrators group"
            match: "Group sysadmin"
            settings:
              PasswordAuthentication: "yes"

          # Restrict port forwarding for specific users
          - name: "Disable forwarding for guest users"
            match: "User guest"
            settings:
              AllowTcpForwarding: "no"
              AllowAgentForwarding: "no"

Advanced: Combining Match blocks with different conditions

---
- hosts: servers
  become: true
  roles:
    - role: sshd
      vars:
        sshd_match_blocks:
          # subnet role
          - name: "Allow root from internal subnet with key-only auth"
            match: "User root Address 192.168.0.*"
            settings:
              PermitRootLogin: "prohibit-password"
              PasswordAuthentication: "no"

          # Group Specific role
          - name: "Service account configuration"
            match: "Group service-accounts"
            settings:
              AllowTcpForwarding: "yes"
              X11Forwarding: "no"
              PermitTTY: "no"
              ForceCommand: "internal-sftp"

User Access Control: Allow and Deny specific users

---
- hosts: servers
  become: true
  roles:
    - role: sshd
      vars:
        # Method 1: Allow only specific users
        sshd_allow_users:
          - vivek
          - jerry
          - admin

        # Method 2: Deny specific users (allow all others)
        # sshd_deny_users:
        #   - root
        #   - saroj
        #   - guest

User Access Control: Restrict SSH with patterns

---
- hosts: servers
  become: true
  roles:
    - role: sshd
      vars:
        # Allow users and patterns (wildcards supported)
        sshd_allow_users:
          - admin
          - "user*"  # Allow user1, user2, user3, etc.
          - "@admins"  # Allow users in the 'admins' group

        # Deny specific users and patterns
        sshd_deny_users:
          - root
          - "test*"  # Deny test1, test2, test3, etc.
          - "guest*"

Cryptographic hardening with custom algorithms

---
- hosts: servers
  become: true
  roles:
    - role: sshd
      vars:
        # Use stricter cryptographic algorithms
        sshd_kex_algorithms:
          - "curve25519-sha256@libssh.org"
          - "curve25519-sha256"

        sshd_ciphers:
          - "chacha20-poly1305@openssh.com"
          - "aes256-gcm@openssh.com"

        sshd_macs:
          - "hmac-sha2-512-etm@openssh.com"
          - "hmac-sha2-256-etm@openssh.com"