SSH *** The Secure Shell Protocol (`SSH Protocol `_) is a cryptographic network protocol for operating network services securely even over an unsecured network. Its most notable applications are remote login, command-line execution but it is also use to transfer files or access other hosts behind the remote end. So SSH (secure shell) is a widely-used protocol for remote administration of Unix and Linux servers. It's available too on Windows 10 and later. `openssh `_ is the implementation running on all my Linux servers. It contains numerous parameters including several potentially insecure settings so as to maintain compatibility with outdated client software. On my servers, the configuration file is generated by ansible using a template. The default values I am using comes from * my own experience working with various Linux distributions * the recommendations from :doc:`lynis` * the recommendations from ssh-audit * the feedback from security auditors To configure it consistently, I am using a template. Do not use the values blindly, ie. one-time-password may require modification. Current configuration ===================== To check the validity of the configuration file and output the effective configuration to stdout, run .. code-block:: sshd -T -C user=user -C host=localhost -C addr=localhost On AlmaLinux/CentOS/..., :command:`sshd -T` is enough, no need to add the extra parameters. Crypto ====== You will find bellow the values I am using for the parameters * :code:`Ciphers`, * :code:`HostKeyAlgorithms` * :code:`KexAlgorithms` * :code:`MACs` * :code:`PubkeyAcceptedAlgorithms` * :code:`PubkeyAcceptedKeyTypes` * :code:`RequiredRSASize` .. warning:: Changing the HostKeyAlgorithms line can cause clients to get a scary warning message about the host key changing: .. code-block:: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ CentOS/Oracle Linux/RHEL 6 -------------------------- CentOS 6 and 7 are obsolete Linux distributions but for various reasons, the systems may still be waiting to be migrated. openssh on CentOS 6 and 7 are vulnerable to Terrapin (CVE-2023-48795) https://access.redhat.com/security/cve/cve-2023-48795 .. literalinclude:: sshd/vars/os_CentOS_6.yml :name: os_CentOS_6.yml CentOS/Oracle Linux/RHEL 7 -------------------------- .. literalinclude:: sshd/vars/os_CentOS_7.yml :name: os_CentOS_7.yml AlmaLinux/CentOS/Oracle/RHEL 8 ------------------------------ .. literalinclude:: sshd/vars/os_CentOS_8.yml :name: os_CentOS_8.yml AlmaLinux/CentOS/Oracle/RHEL 9 ------------------------------ .. literalinclude:: sshd/vars/os_AlmaLinux_9.yml :name: os_AlmaLinux_9.yml AlmaLinux/CentOS/Oracle/RHEL 10 ------------------------------- .. literalinclude:: sshd/vars/os_AlmaLinux_10.yml :name: os_AlmaLinux_10.yml Debian 10 --------- .. literalinclude:: sshd/vars/os_Debian_10.yml :name: os_Debian_10.yml Debian 11 --------- .. literalinclude:: sshd/vars/os_Debian_11.yml :name: os_Debian_11.yml Debian 12 --------- .. literalinclude:: sshd/vars/os_Debian_12.yml :name: os_Debian_12.yml Debian 13 --------- .. literalinclude:: sshd/vars/os_Debian_13.yml :name: os_Debian_13.yml To get the accepted values * :command:`ssh -Q cipher`: supported symmetric ciphers * :command:`ssh -Q cipher-auth`: supported symmetric ciphers that support authenticated encryption * :command:`ssh -Q mac`: supported message integrity codes * :command:`ssh -Q kex`: key exchange algorithms * :command:`ssh -Q kex-gss`: GSSAPI key exchange algorithms * :command:`ssh -Q key`: key types * :command:`ssh -Q key-ca-sign`: valid CA signature algorithms for certificates, * :command:`ssh -Q key-cert`: certificate key types * :command:`ssh -Q key-plain`: non-certificate key types * :command:`ssh -Q key-sig`: all key types and signature algorithms * :command:`ssh -Q protocol-version`: supported SSH protocol versions * :command:`ssh -Q sig`: supported signature algorithms. https://blog.jeanbruenn.info/2023/12/23/hardening-your-openssh-configuration-do-you-know-about-the-tool-ssh-audit/ https://materials.rangeforce.com/tutorial/2020/02/13/SSH-Audit/ AllowAgentForwarding ==================== .. code-block:: AllowAgentForwarding no AllowTcpForwarding ================== .. code-block:: AllowTcpForwarding no ChallengeResponseAuthentication =============================== .. code-block:: ChallengeResponseAuthentication no ClientAliveCountMax =================== .. code-block:: ClientAliveCountMax 2 Compression =========== .. code-block:: Compression delayed DebianBanner ============ :command:`DebianBanner no` Debian system retuns by default a banner like :code:`SSH-2.0-OpenSSH_7.9p1 Debian-10+deb10u4`. With :command:`DebianBanner no`, the banner becomes :code:`SSH-2.0-OpenSSH_7.9p1` GSSAPIAuthentication ==================== .. code-block:: GSSAPIAuthentication no GSSAPICleanupCredentials ======================== .. code-block:: GSSAPICleanupCredentials yes HostbasedAuthentication ======================= .. code-block:: HostbasedAuthentication no IgnoreRhosts ============ .. code-block:: IgnoreRhosts yes LogLevel ======== :command:`LogLevel INFO` .. code-block:: Sep 17 15:37:36 tst-almalinux9 sshd[1497662]: Accepted publickey for filtrix from 10.20.20.248 port 60368 ssh2: RSA SHA256:CXSnf0gnApTmysI/S1srUAOj11vktocFrV4O0y3FpAk The LogLevel is configured to INFO by default. It records the fingerprint of the publickey used to authenticate since OpenSSH 6.3/6.3p1 (2013-09-13). So it seems useless to follow :doc:`lynis` who still recommend to use :command:`VERBOSE` to record the fingerprint. MaxAuthTries ============ Lynis want 3 but it may be too low if you have multiple ssh keys. I need to pick a value, 5 seems ok. .. code-block:: MaxAuthTries 5 MaxSessions =========== I never have any problem with .. code-block:: MaxSessions 10 It's the default value. But Lynis recommend 2 sessions. If you want to follow Lynis advice but need sessions for a user named :code:`admin`, you can use .. code-block:: MaxSessions 2 Match User admin MaxSessions 10 MaxStartups =========== .. code-block:: MaxStartups 10:30:100 PasswordAuthentication ====================== .. code-block:: PasswordAuthentication no If some users really need to use password, it remains possible to enable this possible user per user or per group .. code-block:: Match User alice PasswordAuthentication yes PermitEmptyPasswords ==================== .. code-block:: PermitEmptyPasswords no PermitListen ============ OpenSSH 7.8/7.8p1 (2018-08-24) sshd(8): add a PermitListen directive to sshd_config(5) and a corresponding permitlisten= authorized_keys option that control which listen addresses and port numbers may be used by remote forwarding (ssh -R ...). PermitOpen ========== .. code-block:: PermitOpen none PermitRootLogin =============== * :command:`PermitRootLogin no`: it's not possible to ssh as root * :command:`PermitRootLogin forced-commands-only`: it's possible to run a limited number of commands as root. I am using the later to enable rsync backup. .. code-block:: :caption: /root/.ssh/.authorized_keys from="1.2.3.4",restrict,command="/usr/local/bin/validate-rsync" ssh-rsa AAAAB... :code:`forced-commands-only` is better than a plain :code:`yes` but of course, if the rsync command is granted, it's quite easy to alter the configuration. The `GTFOBins `_ project collects legitimate functions of Unix binaries that can be abused to break out restricted shells, escalate or maintain elevated privileges, transfer files, spawn bind and reverse shells, and facilitate the other post-exploitation tasks. Port ==== The default ssh port is 22. I don't think security through obscurity brings enough benefits to change the port. PrintLastLog ============ .. code-block:: PrintLastLog yes Protocol ======== :command:`Protocol 2` PubkeyAuthentication ==================== .. code-block:: PubkeyAuthentication yes StrictModes =========== .. code-block:: StrictModes yes Specifies whether sshd should check file modes and ownership of the user's files and home directory before accepting login. This is normally desirable because novices sometimes accidentally leave their directory or files world-writable. The default is yes. TCPKeepAlive ============ .. code-block:: TCPKeepAlive yes The default is yes (to send TCP keepalive messages), and the server will notice if the network goes down or the client host crashes. This avoids infinitely hanging sessions. The TCP keepalive option enabled by :command:`TCPKeepAlive` is spoofable but disabling :command:`TCPKeepAlive` will not increase the security. To add non spoofable keep-alive, configure :command:`ClientAliveInterval` to set a timeout interval in seconds after which if no data has been received from the client, sshd will send a message through the encrypted channel to request a response from the client. UseDNS ====== .. code-block:: UseDNS no UsePAM ====== .. code-block:: UsePAM yes X11Forwarding ============= .. code-block:: X11Forwarding no This parameter can be overridden for some users or groups.