Chapter 1. Using secure communications between two systems with OpenSSH
Chapter 1. Using secure communications between two systems with OpenSSH SSH (Secure Shell) is a protocol which provides secure communications between two systems using a client-server architecture and allows users to log in to server host systems remotely. Unlike other remote communication protocols, such as FTP or Telnet, SSH encrypts the login session, which prevents intruders from collecting unencrypted passwords from the connection. 1.1. SSH and OpenSSH SSH (Secure Shell) is a program for logging into a remote machine and executing commands on that machine. The SSH protocol provides secure encrypted communications between two untrusted hosts over an insecure network. You can also forward X11 connections and arbitrary TCP/IP ports over the secure channel. The SSH protocol mitigates security threats, such as interception of communication between two systems and impersonation of a particular host, when you use it for remote shell login or file copying. This is because the SSH client and server use digital signatures to verify their identities. Additionally, all communication between the client and server systems is encrypted. A host key authenticates hosts in the SSH protocol. Host keys are cryptographic keys that are generated automatically when OpenSSH is started for the first time or when the host boots for the first time. OpenSSH is an implementation of the SSH protocol supported by Linux, UNIX, and similar operating systems. It includes the core files necessary for both the OpenSSH client and server. The OpenSSH suite consists of the following user-space tools: ssh is a remote login program (SSH client). sshd is an OpenSSH SSH daemon. scp is a secure remote file copy program. sftp is a secure file transfer program. ssh-agent is an authentication agent for caching private keys. ssh-add adds private key identities to ssh-agent . ssh-keygen generates, manages, and converts authentication keys for ssh . ssh-copy-id is a script that adds local public keys to the authorized_keys file on a remote SSH server. ssh-keyscan gathers SSH public host keys. The OpenSSH suite in RHEL supports only SSH version 2. It has an enhanced key-exchange algorithm that is not vulnerable to exploits known in the older version 1. Red Hat Enterprise Linux includes the following OpenSSH packages: the general openssh package, the openssh-server package, and the openssh-clients package. The OpenSSH packages require the OpenSSL package openssl-libs , which installs several important cryptographic libraries that enable OpenSSH to provide encrypted communications. OpenSSH, as one of core cryptographic subsystems of RHEL, uses system-wide crypto policies. This ensures that weak cipher suites and cryptographic algorithms are disabled in the default configuration. To modify the policy, the administrator must either use the update-crypto-policies command to adjust the settings or manually opt out of the system-wide crypto policies. See the Excluding an application from following system-wide crypto policies section for more information. The OpenSSH suite uses two sets of configuration files: one for client programs (that is, ssh , scp , and sftp ), and another for the server (the sshd daemon). System-wide SSH configuration information is stored in the /etc/ssh/ directory. The /etc/ssh/ssh_config file contains the client configuration, and the /etc/ssh/sshd_config file is the default OpenSSH server configuration file. User-specific SSH configuration information is stored in ~/.ssh/ in the user's home directory. For a detailed list of OpenSSH configuration files, see the FILES section in the sshd(8) man page on your system. Additional resources Man pages listed by using the man -k ssh command on your system Using system-wide cryptographic policies 1.2. Generating SSH key pairs You can log in to an OpenSSH server without entering a password by generating an SSH key pair on a local system and copying the generated public key to the OpenSSH server. Each user who wants to create a key must run this procedure. To preserve previously generated key pairs after you reinstall the system, back up the ~/.ssh/ directory before you create new keys. After reinstalling, copy it back to your home directory. You can do this for all users on your system, including root . Prerequisites You are logged in as a user who wants to connect to the OpenSSH server by using keys. The OpenSSH server is configured to allow key-based authentication. Procedure Generate an ECDSA key pair: You can also generate an RSA key pair by using the ssh-keygen command without any parameter or an Ed25519 key pair by entering the ssh-keygen -t ed25519 command. Note that the Ed25519 algorithm is not FIPS-140-compliant, and OpenSSH does not work with Ed25519 keys in FIPS mode. Copy the public key to a remote machine: Replace <username> @ <ssh-server-example.com> with your credentials. If you do not use the ssh-agent program in your session, the command copies the most recently modified ~/.ssh/id*.pub public key if it is not yet installed. To specify another public-key file or to prioritize keys in files over keys cached in memory by ssh-agent , use the ssh-copy-id command with the -i option. Verification Log in to the OpenSSH server by using the key file: Additional resources ssh-keygen(1) and ssh-copy-id(1) man pages on your system 1.3. Setting key-based authentication as the only method on an OpenSSH server To improve system security, enforce key-based authentication by disabling password authentication on your OpenSSH server. Prerequisites The openssh-server package is installed. The sshd daemon is running on the server. You can already connect to the OpenSSH server by using a key. See the Generating SSH key pairs section for details. Procedure Open the /etc/ssh/sshd_config configuration in a text editor, for example: Change the PasswordAuthentication option to no : On a system other than a new default installation, check that the PubkeyAuthentication parameter is either not set or set to yes . Set the ChallengeResponseAuthentication directive to no . Note that the corresponding entry is commented out in the configuration file and the default value is yes . To use key-based authentication with NFS-mounted home directories, enable the use_nfs_home_dirs SELinux boolean: If you are connected remotely, not using console or out-of-band access, test the key-based login process before disabling password authentication. Reload the sshd daemon to apply the changes: Additional resources sshd_config(5) and setsebool(8) man pages on your system 1.4. Caching your SSH credentials by using ssh-agent To avoid entering a passphrase each time you initiate an SSH connection, you can use the ssh-agent utility to cache the private SSH key for a login session. If the agent is running and your keys are unlocked, you can log in to SSH servers by using these keys but without having to enter the key's password again. The private key and the passphrase remain secure. Prerequisites You have a remote host with the SSH daemon running and reachable through the network. You know the IP address or hostname and credentials to log in to the remote host. You have generated an SSH key pair with a passphrase and transferred the public key to the remote machine. See the Generating SSH key pairs section for details. Procedure Add the command for automatically starting ssh-agent in your session to the ~/.bashrc file: Open ~/.bashrc in a text editor of your choice, for example: Add the following line to the file: Save the changes, and quit the editor. Add the following line to the ~/.ssh/config file: With this option and ssh-agent started in your session, the agent prompts for a password only for the first time when you connect to a host. Verification Log in to a host which uses the corresponding public key of the cached private key in the agent, for example: Note that you did not have to enter the passphrase. 1.5. Authenticating by SSH keys stored on a smart card You can create and store ECDSA and RSA keys on a smart card and authenticate by the smart card on an OpenSSH client. Smart-card authentication replaces the default password authentication. Prerequisites On the client side, the opensc package is installed and the pcscd service is running. Procedure List all keys provided by the OpenSC PKCS #11 module including their PKCS #11 URIs and save the output to the keys.pub file: Transfer the public key to the remote server. Use the ssh-copy-id command with the keys.pub file created in the step: Connect to <ssh-server-example.com> by using the ECDSA key. You can use just a subset of the URI, which uniquely references your key, for example: Because OpenSSH uses the p11-kit-proxy wrapper and the OpenSC PKCS #11 module is registered to the p11-kit tool, you can simplify the command: If you skip the id= part of a PKCS #11 URI, OpenSSH loads all keys that are available in the proxy module. This can reduce the amount of typing required: Optional: You can use the same URI string in the ~/.ssh/config file to make the configuration permanent: The ssh client utility now automatically uses this URI and the key from the smart card. Additional resources p11-kit(8) , opensc.conf(5) , pcscd(8) , ssh(1) , and ssh-keygen(1) man pages on your system 1.6. Making OpenSSH more secure You can tweak the system to increase security when using OpenSSH. Note that changes in the /etc/ssh/sshd_config OpenSSH server configuration file require reloading the sshd daemon to take effect: Warning The majority of security hardening configuration changes reduce compatibility with clients that do not support up-to-date algorithms or cipher suites. Disabling insecure connection protocols To make SSH truly effective, prevent the use of insecure connection protocols that are replaced by the OpenSSH suite. Otherwise, a user's password might be protected using SSH for one session only to be captured later when logging in using Telnet. Disabling password-based authentication Disabling passwords for authentication and allowing only key pairs reduces the attack surface. See the Setting key-based authentication as the only method on an OpenSSH server section for more information. Stronger key types Although the ssh-keygen command generates a pair of RSA keys by default, you can instruct it to generate Elliptic Curve Digital Signature Algorithm (ECDSA) or Edwards-Curve 25519 (Ed25519) keys by using the -t option. The ECDSA offers better performance than RSA at the equivalent symmetric key strength. It also generates shorter keys. The Ed25519 public-key algorithm is an implementation of twisted Edwards curves that is more secure and also faster than RSA, DSA, and ECDSA. OpenSSH creates RSA, ECDSA, and Ed25519 server host keys automatically if they are missing. To configure the host key creation in RHEL, use the sshd-keygen@.service instantiated service. For example, to disable the automatic creation of the RSA key type: Note In images with the cloud-init method enabled, the ssh-keygen units are automatically disabled. This is because the ssh-keygen template service can interfere with the cloud-init tool and cause problems with host key generation. To prevent these problems the etc/systemd/system/sshd-keygen@.service.d/disable-sshd-keygen-if-cloud-init-active.conf drop-in configuration file disables the ssh-keygen units if cloud-init is running. To allow only a particular key type for SSH connections, remove a comment out at the beginning of the relevant line in /etc/ssh/sshd_config , and reload the sshd service. For example, to allow only Ed25519 host keys, the corresponding lines must be as follows: Important The Ed25519 algorithm is not FIPS-140-compliant, and OpenSSH does not work with Ed25519 keys in FIPS mode. Non-default port By default, the sshd daemon listens on TCP port 22. Changing the port reduces the exposure of the system to attacks based on automated network scanning on the default port and therefore increases security through obscurity. You can specify the port using the Port directive in the /etc/ssh/sshd_config configuration file. You also have to update the default SELinux policy to allow the use of a non-default port. To do so, use the semanage tool from the policycoreutils-python-utils package: Furthermore, update firewalld configuration: In the commands, replace <port-number> with the new port number specified using the Port directive. No root login If your particular use case does not require the possibility of logging in as the root user, you can set the PermitRootLogin configuration directive to no in the /etc/ssh/sshd_config file. By disabling the possibility of logging in as the root user, the administrator can audit which users run what privileged commands after they log in as regular users and then gain root rights. Alternatively, set PermitRootLogin to prohibit-password : This enforces the use of key-based authentication instead of the use of passwords for logging in as root and reduces risks by preventing brute-force attacks. Using the X Security extension The X server in Red Hat Enterprise Linux clients does not provide the X Security extension. Therefore, clients cannot request another security layer when connecting to untrusted SSH servers with X11 forwarding. Most applications are not able to run with this extension enabled anyway. By default, the ForwardX11Trusted option in the /etc/ssh/ssh_config.d/05-redhat.conf file is set to yes , and there is no difference between the ssh -X remote_machine (untrusted host) and ssh -Y remote_machine (trusted host) command. If your scenario does not require the X11 forwarding feature at all, set the X11Forwarding directive in the /etc/ssh/sshd_config configuration file to no . Restricting SSH access to specific users, groups, or IP ranges The AllowUsers and AllowGroups directives in the /etc/ssh/sshd_config configuration file server enable you to permit only certain users, domains, or groups to connect to your OpenSSH server. You can combine AllowUsers and AllowGroups to restrict access more precisely, for example: This configuration allows only connections if all of the following conditions meet: The connection's source IP is within the 192.168.1.0/24 or 10.0.0.0/24 subnet. The source IP is not 192.168.1.2. The user is a member of the example-group group. The OpenSSH server permits only connections that pass all Allow and Deny directives in /etc/ssh/sshd_config . For example, if the AllowUsers directive lists a user that is not part of a group listed in the AllowGroups directive, then the user cannot log in. Note that using allowlists (directives starting with Allow) is more secure than using blocklists (options starting with Deny) because allowlists block also new unauthorized users or groups. Changing system-wide cryptographic policies OpenSSH uses RHEL system-wide cryptographic policies, and the default system-wide cryptographic policy level offers secure settings for current threat models. To make your cryptographic settings more strict, change the current policy level: Warning If your system communicates with legacy systems, you might face interoperability problems due to the strict setting of the FUTURE policy. You can also disable only specific ciphers for the SSH protocol through the system-wide cryptographic policies. See the Customizing system-wide cryptographic policies with subpolicies section in the Security hardening document for more information. Opting out of system-wide cryptographic policies To opt out of the system-wide cryptographic policies for your OpenSSH server, uncomment the line with the CRYPTO_POLICY= variable in the /etc/sysconfig/sshd file. After this change, values that you specify in the Ciphers , MACs , KexAlgoritms , and GSSAPIKexAlgorithms sections in the /etc/ssh/sshd_config file are not overridden. See the sshd_config(5) man page for more information. To opt out of system-wide cryptographic policies for your OpenSSH client, perform one of the following tasks: For a given user, override the global ssh_config with a user-specific configuration in the ~/.ssh/config file. For the entire system, specify the cryptographic policy in a drop-in configuration file located in the /etc/ssh/ssh_config.d/ directory, with a two-digit number prefix smaller than 5, so that it lexicographically precedes the 05-redhat.conf file, and with a .conf suffix, for example, 04-crypto-policy-override.conf . Additional resources sshd_config(5) , ssh-keygen(1) , crypto-policies(7) , and update-crypto-policies(8) man pages on your system Using system-wide cryptographic policies in the Security hardening document How to disable specific algorithms and ciphers for ssh service only (Red Hat Knowledgebase) 1.7. Connecting to a remote server through an SSH jump host You can connect from your local system to a remote server through an intermediary server, also called jump host. A jump server bridges hosts from different security zones and can manage multiple client-server connections. Prerequisites A jump host accepts SSH connections from your local system. A remote server accepts SSH connections from the jump host. Procedure If you connect through a jump server or more intermediary servers once, use the ssh -J command and specify the jump servers directly, for example: Change the host name-only notation in the command if the user names or SSH ports on the jump servers differ from the names and ports on the remote server, for example: If you connect to a remote server through jump servers regularly, store the jump-server configuration in your SSH configuration file: Define the jump host by editing the ~/.ssh/config file on your local system, for example: The Host parameter defines a name or alias for the host you can use in ssh commands. The value can match the real host name, but can also be any string. The HostName parameter sets the actual host name or IP address of the jump host. Add the remote server jump configuration with the ProxyJump directive to ~/.ssh/config file on your local system, for example: Use your local system to connect to the remote server through the jump server: This command is equivalent to the ssh -J jump-server1 remote-server command if you omit the configuration steps. Additional resources ssh_config(5) and ssh(1) man pages on your system 1.8. Configuring secure communication with the ssh system roles As an administrator, you can use the sshd system role to configure SSH servers and the ssh system role to configure SSH clients consistently on any number of RHEL systems at the same time by using Red Hat Ansible Automation Platform. 1.8.1. How the sshd RHEL system role maps settings from a playbook to the configuration file In the sshd RHEL system role playbook, you can define the parameters for the server SSH configuration file. If you do not specify these settings, the role produces the sshd_config file that matches the RHEL defaults. In all cases, booleans correctly render as yes and no in the final configuration on your managed nodes. You can use lists to define multi-line configuration items. For example: renders as: Additional resources /usr/share/ansible/roles/rhel-system-roles.sshd/README.md file /usr/share/doc/rhel-system-roles/sshd/ directory 1.8.2. Configuring OpenSSH servers by using the sshd RHEL system role You can use the sshd RHEL system role to configure multiple OpenSSH servers. These ensure secure communication environment for remote users by providing namely: Management of incoming SSH connections from remote clients Credentials verification Secure data transfer and command execution Note You can use the sshd RHEL system role alongside with other RHEL system roles that change SSHD configuration, for example the Identity Management RHEL system roles. To prevent the configuration from being overwritten, ensure the sshd RHEL system role uses namespaces (RHEL 8 and earlier versions) or a drop-in directory (RHEL 9). Prerequisites You have prepared the control node and the managed nodes You are logged in to the control node as a user who can run playbooks on the managed nodes. The account you use to connect to the managed nodes has sudo permissions on them. Procedure Create a playbook file, for example ~/playbook.yml , with the following content: --- - name: SSH server configuration hosts: managed-node-01.example.com tasks: - name: Configure sshd to prevent root and password login except from particular subnet ansible.builtin.include_role: name: rhel-system-roles.sshd vars: sshd: PermitRootLogin: no PasswordAuthentication: no Match: - Condition: "Address 192.0.2.0/24" PermitRootLogin: yes PasswordAuthentication: yes The settings specified in the example playbook include the following: PasswordAuthentication: yes|no Controls whether the OpenSSH server ( sshd ) accepts authentication from clients that use the username and password combination. Match: The match block allows the root user login using password only from the subnet 192.0.2.0/24 . For details about the role variables and the OpenSSH configuration options used in the playbook, see the /usr/share/ansible/roles/rhel-system-roles.sshd/README.md file and the sshd_config(5) manual page on the control node. Validate the playbook syntax: Note that this command only validates the syntax and does not protect against a wrong but valid configuration. Run the playbook: Verification Log in to the SSH server: Verify the contents of the sshd_config file on the SSH server: Check that you can connect to the server as root from the 192.0.2.0/24 subnet: Determine your IP address: If the IP address is within the 192.0.2.1 - 192.0.2.254 range, you can connect to the server. Connect to the server as root : Additional resources /usr/share/ansible/roles/rhel-system-roles.sshd/README.md file /usr/share/doc/rhel-system-roles/sshd/ directory 1.8.3. How the ssh RHEL system role maps settings from a playbook to the configuration file In the ssh RHEL system role playbook, you can define the parameters for the client SSH configuration file. If you do not specify these settings, the role produces a global ssh_config file that matches the RHEL defaults. In all the cases, booleans correctly render as yes or no in the final configuration on your managed nodes. You can use lists to define multi-line configuration items. For example: renders as: Note The configuration options are case sensitive. Additional resources /usr/share/ansible/roles/rhel-system-roles.ssh/README.md file /usr/share/doc/rhel-system-roles/ssh/ directory 1.8.4. Configuring OpenSSH clients by using the ssh RHEL system role You can use the ssh RHEL system role to configure multiple OpenSSH clients. These enable the local user to establish a secure connection with the remote OpenSSH server by ensuring namely: Secure connection initiation Credentials provision Negotiation with the OpenSSH server on the encryption method used for the secure communication channel Ability to send files securely to and from the OpenSSH server Note You can use the ssh RHEL system role alongside with other system roles that change SSH configuration, for example the Identity Management RHEL system roles. To prevent the configuration from being overwritten, make sure that the ssh RHEL system role uses a drop-in directory (default in RHEL 8 and later). Prerequisites You have prepared the control node and the managed nodes You are logged in to the control node as a user who can run playbooks on the managed nodes. The account you use to connect to the managed nodes has sudo permissions on them. Procedure Create a playbook file, for example ~/playbook.yml , with the following content: --- - name: SSH client configuration hosts: managed-node-01.example.com tasks: - name: Configure ssh clients ansible.builtin.include_role: name: rhel-system-roles.ssh vars: ssh_user: root ssh: Compression: true GSSAPIAuthentication: no ControlMaster: auto ControlPath: ~/.ssh/.cm%C Host: - Condition: example Hostname: server.example.com User: user1 ssh_ForwardX11: no The settings specified in the example playbook include the following: ssh_user: root Configures the root user's SSH client preferences on the managed nodes with certain configuration specifics. Compression: true Compression is enabled. ControlMaster: auto ControlMaster multiplexing is set to auto . Host Creates alias example for connecting to the server.example.com host as a user called user1 . ssh_ForwardX11: no X11 forwarding is disabled. For details about the role variables and the OpenSSH configuration options used in the playbook, see the /usr/share/ansible/roles/rhel-system-roles.ssh/README.md file and the ssh_config(5) manual page on the control node. Validate the playbook syntax: Note that this command only validates the syntax and does not protect against a wrong but valid configuration. Run the playbook: Verification Verify that the managed node has the correct configuration by displaying the SSH configuration file: Additional resources /usr/share/ansible/roles/rhel-system-roles.ssh/README.md file /usr/share/doc/rhel-system-roles/ssh/ directory ssh_config(5) manual page 1.8.5. Using the sshd RHEL system role for non-exclusive configuration By default, applying the sshd RHEL system role overwrites the entire configuration. This may be problematic if you have previously adjusted the configuration, for example, with a different RHEL system role or a playbook. To apply the sshd RHEL system role for only selected configuration options while keeping other options in place, you can use the non-exclusive configuration. You can apply a non-exclusive configuration: In RHEL 8 and earlier by using a configuration snippet. In RHEL 9 and later by using files in a drop-in directory. The default configuration file is already placed in the drop-in directory as /etc/ssh/sshd_config.d/00-ansible_system_role.conf . Prerequisites You have prepared the control node and the managed nodes You are logged in to the control node as a user who can run playbooks on the managed nodes. The account you use to connect to the managed nodes has sudo permissions on them. Procedure Create a playbook file, for example ~/playbook.yml , with the following content: For managed nodes that run RHEL 8 or earlier: --- - name: Non-exclusive sshd configuration hosts: managed-node-01.example.com tasks: - name: Configure SSHD to accept environment variables ansible.builtin.include_role: name: rhel-system-roles.sshd vars: sshd_config_namespace: <my-application> sshd: # Environment variables to accept AcceptEnv: LANG LS_COLORS EDITOR For managed nodes that run RHEL 9 or later: - name: Non-exclusive sshd configuration hosts: managed-node-01.example.com tasks: - name: Configure sshd to accept environment variables ansible.builtin.include_role: name: rhel-system-roles.sshd vars: sshd_config_file: /etc/ssh/sshd_config.d/ <42-my-application> .conf sshd: # Environment variables to accept AcceptEnv: LANG LS_COLORS EDITOR The settings specified in the example playbooks include the following: sshd_config_namespace: <my-application> The role places the configuration that you specify in the playbook to configuration snippets in the existing configuration file under the given namespace. You need to select a different namespace when running the role from different context. sshd_config_file: /etc/ssh/sshd_config.d/ <42-my-application> .conf In the sshd_config_file variable, define the .conf file into which the sshd system role writes the configuration options. Use a two-digit prefix, for example 42- to specify the order in which the configuration files will be applied. AcceptEnv: Controls which environment variables the OpenSSH server ( sshd ) will accept from a client: LANG : defines the language and locale settings. LS_COLORS : defines the displaying color scheme for the ls command in the terminal. EDITOR : specifies the default text editor for the command-line programs that need to open an editor. For details about the role variables and the OpenSSH configuration options used in the playbook, see the /usr/share/ansible/roles/rhel-system-roles.sshd/README.md file and the sshd_config(5) manual page on the control node. Validate the playbook syntax: Note that this command only validates the syntax and does not protect against a wrong but valid configuration. Run the playbook: Verification Verify the configuration on the SSH server: For managed nodes that run RHEL 8 or earlier: For managed nodes that run RHEL 9 or later: Additional resources /usr/share/ansible/roles/rhel-system-roles.sshd/README.md file /usr/share/doc/rhel-system-roles/sshd/ directory sshd_config(5) manual page 1.9. Additional resources sshd(8) , ssh(1) , scp(1) , sftp(1) , ssh-keygen(1) , ssh-copy-id(1) , ssh_config(5) , sshd_config(5) , update-crypto-policies(8) , and crypto-policies(7) man pages on your system Configuring SELinux for applications and services with non-standard configurations Controlling network traffic using firewalld
ssh-keygen -t ecdsa Generating public/private ecdsa key pair. Enter file in which to save the key (/home/ <username> /.ssh/id_ecdsa): Enter passphrase (empty for no passphrase): <password> Enter same passphrase again: <password> Your identification has been saved in /home/ <username> /.ssh/id_ecdsa. Your public key has been saved in /home/ <username> /.ssh/id_ecdsa.pub. The key fingerprint is: SHA256:Q/x+qms4j7PCQ0qFd09iZEFHA+SqwBKRNaU72oZfaCI <username> @ <localhost.example.com> The key's randomart image is: +---[ECDSA 256]---+ |.oo..o=++ | |.. o .oo . | |. .. o. o | |....o.+... | |o.oo.o +S . | |.=.+. .o | |E.*+. . . . | |.=..+ +.. o | | . oo*+o. | +----[SHA256]-----+ ssh-copy-id <username> @ <ssh-server-example.com> /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed <username> @ <ssh-server-example.com> 's password: ... Number of key(s) added: 1 Now try logging into the machine, with: "ssh ' <username> @ <ssh-server-example.com> '" and check to make sure that only the key(s) you wanted were added. ssh -o PreferredAuthentications=publickey <username> @ <ssh-server-example.com> vi /etc/ssh/sshd_config PasswordAuthentication no setsebool -P use_nfs_home_dirs 1 systemctl reload sshd vi ~/.bashrc eval USD(ssh-agent) AddKeysToAgent yes ssh <example.user> @ <ssh-server@example.com> ssh-keygen -D pkcs11: > keys.pub ssh-copy-id -f -i keys.pub <username@ssh-server-example.com> ssh -i "pkcs11:id=%01?module-path=/usr/lib64/pkcs11/opensc-pkcs11.so" <ssh-server-example.com> Enter PIN for 'SSH key': [ssh-server-example.com] USD ssh -i "pkcs11:id=%01" <ssh-server-example.com> Enter PIN for 'SSH key': [ssh-server-example.com] USD ssh -i pkcs11: <ssh-server-example.com> Enter PIN for 'SSH key': [ssh-server-example.com] USD cat ~/.ssh/config IdentityFile "pkcs11:id=%01?module-path=/usr/lib64/pkcs11/opensc-pkcs11.so" ssh <ssh-server-example.com> Enter PIN for 'SSH key': [ssh-server-example.com] USD systemctl reload sshd systemctl mask sshd-keygen@rsa.service rm -f /etc/ssh/ssh_host_rsa_key * systemctl restart sshd HostKey /etc/ssh/ssh_host_rsa_key HostKey /etc/ssh/ssh_host_ecdsa_key HostKey /etc/ssh/ssh_host_ed25519_key semanage port -a -t ssh_port_t -p tcp <port-number> firewall-cmd --add-port <port-number> /tcp firewall-cmd --remove-port=22/tcp firewall-cmd --runtime-to-permanent PermitRootLogin prohibit-password AllowUsers *@192.168.1.* *@10.0.0.* !*@192.168.1.2 AllowGroups example-group update-crypto-policies --set FUTURE Setting system policy to FUTURE ssh -J <jump-1.example.com> , <jump-2.example.com> , <jump-3.example.com> <target-server-1.example.com> ssh -J <example.user.1> @ <jump-1.example.com> : <75> , <example.user.2> @ <jump-2.example.com> : <75> , <example.user.3> @ <jump-3.example.com> : <75> <example.user.f> @ <target-server-1.example.com> : <220> Host <jump-server-1> HostName <jump-1.example.com> Host <remote-server-1> HostName <target-server-1.example.com> ProxyJump <jump-server-1> ssh <remote-server-1> sshd_ListenAddress: - 0.0.0.0 - '::' ListenAddress 0.0.0.0 ListenAddress :: --- - name: SSH server configuration hosts: managed-node-01.example.com tasks: - name: Configure sshd to prevent root and password login except from particular subnet ansible.builtin.include_role: name: rhel-system-roles.sshd vars: sshd: PermitRootLogin: no PasswordAuthentication: no Match: - Condition: "Address 192.0.2.0/24" PermitRootLogin: yes PasswordAuthentication: yes ansible-playbook --syntax-check ~/playbook.yml ansible-playbook ~/playbook.yml ssh <username> @ <ssh_server> cat /etc/ssh/sshd_config PasswordAuthentication no PermitRootLogin no Match Address 192.0.2.0/24 PasswordAuthentication yes PermitRootLogin yes hostname -I 192.0.2.1 ssh root@ <ssh_server> LocalForward: - 22 localhost:2222 - 403 localhost:4003 LocalForward 22 localhost:2222 LocalForward 403 localhost:4003 --- - name: SSH client configuration hosts: managed-node-01.example.com tasks: - name: Configure ssh clients ansible.builtin.include_role: name: rhel-system-roles.ssh vars: ssh_user: root ssh: Compression: true GSSAPIAuthentication: no ControlMaster: auto ControlPath: ~/.ssh/.cm%C Host: - Condition: example Hostname: server.example.com User: user1 ssh_ForwardX11: no ansible-playbook --syntax-check ~/playbook.yml ansible-playbook ~/playbook.yml cat ~/root/.ssh/config Ansible managed Compression yes ControlMaster auto ControlPath ~/.ssh/.cm%C ForwardX11 no GSSAPIAuthentication no Host example Hostname example.com User user1 --- - name: Non-exclusive sshd configuration hosts: managed-node-01.example.com tasks: - name: Configure SSHD to accept environment variables ansible.builtin.include_role: name: rhel-system-roles.sshd vars: sshd_config_namespace: <my-application> sshd: # Environment variables to accept AcceptEnv: LANG LS_COLORS EDITOR - name: Non-exclusive sshd configuration hosts: managed-node-01.example.com tasks: - name: Configure sshd to accept environment variables ansible.builtin.include_role: name: rhel-system-roles.sshd vars: sshd_config_file: /etc/ssh/sshd_config.d/ <42-my-application> .conf sshd: # Environment variables to accept AcceptEnv: LANG LS_COLORS EDITOR ansible-playbook --syntax-check ~/playbook.yml ansible-playbook ~/playbook.yml cat /etc/ssh/sshd_config BEGIN sshd system role managed block: namespace <my-application> Match all AcceptEnv LANG LS_COLORS EDITOR END sshd system role managed block: namespace <my-application> cat /etc/ssh/sshd_config.d/42-my-application.conf Ansible managed # AcceptEnv LANG LS_COLORS EDITOR