Securing SSH Connections on RHEL 9 | CentOS 9 Using Ansible Roles

Securing SSH connections on RHEL 9 and CentOS 9 with Ansible

Learn about securing SSH connections on RHEL 9 and CentOS 9 with Ansible roles. This guide covers key SSH security practices, Ansible playbook setup, and detailed instructions to protect your servers.

Table of Contents

Introduction

Securing SSH connections is an essential task for system administrators to ensure that only authorized users can access their Linux servers. With the popularity of RHEL 9 (Red Hat Enterprise Linux 9) and CentOS 9 as enterprise-grade Linux distributions, configuring SSH securely is a critical step in safeguarding your systems from unauthorized access. This process can be made simpler and more consistent by using Ansible, a powerful automation tool.

In this blog post, we’ll explore how to secure SSH connections on RHEL 9 and CentOS 9 servers using Ansible roles. You’ll learn how to automate SSH security tasks, enforce best practices, and apply configurations across multiple servers, making your security management more efficient and scalable.

Introduction to SSH Security on RHEL 9 and CentOS 9

SSH (Secure Shell) is the standard protocol used for remotely accessing Linux servers. Since SSH provides a secure encrypted channel, it’s critical to configure it properly to prevent unauthorized access. On both RHEL 9 and CentOS 9, the default SSH configurations are secure, but there are various enhancements you can make to harden your system further.

Best practices include:

  • Disabling root login.

  • Using key-based authentication instead of passwords.

  • Changing the default SSH port to a non-standard port.

  • Enabling two-factor authentication (2FA).

  • Limiting SSH access to specific IP addresses.

Applying these practices manually to multiple servers can be time-consuming, especially when scaling to large environments. This is where Ansible comes in. Ansible allows you to automate the application of these security settings across multiple servers in a controlled and repeatable manner.

Why Use Ansible for SSH Security Automation?

Ansible is a popular open-source automation tool that simplifies IT infrastructure management. It allows administrators to automate complex tasks, like securing SSH connections, by creating playbooks and roles. Here’s why Ansible is ideal for SSH security automation:

  • Consistency: Ansible ensures that your SSH security settings are applied uniformly across all managed servers.

  • Scalability: You can manage a large number of servers easily, ensuring that SSH configurations are consistent across your entire infrastructure.

  • Reusability: Once you create Ansible roles, you can reuse them for multiple environments or systems.

  • Simplicity: Ansible doesn’t require agents on remote systems, and its syntax is straightforward, making it easy to use for system administrators of all skill levels.


Securing SSH connections on RHEL 9 and CentOS 9 with Ansible

Prerequisites for Securing SSH with Ansible

Before you begin securing SSH with Ansible, make sure you have the following prerequisites:

  • Ansible Installed: Install Ansible on the control node (the machine from which you’ll manage the target servers).
				
					sudo dnf install ansible -y
				
			
  • SSH Access to Target Servers: Ensure you have SSH access to your RHEL 9 and CentOS 9 servers.

  • Sudo Privileges: You need sudo privileges on the target servers to modify SSH configurations.

  • Inventory File: Ansible requires an inventory file to know which servers to manage. The file lists the hosts (servers) and groups to which you’ll apply your configurations.

For this demonstration, we configured our Linux servers as follows:

HostnameIP AddressRAM (GB)CoresOS
control.dev.naijalabs.net (Ansible Controller)192.168.1.2142CentOS Stream release 9
server1.dev.naijalabs.net192.168.1.21342Red Hat Enterprise Linux release 9.5 (Plow)
server2.dev.naijalabs.net192.168.1.21642CentOS Stream release 9

Best Practices for Securing SSH Connections on RHEL 9 | CentOS 9

Securing SSH is vital to prevent unauthorized access. Below are some of the best practices to follow when securing SSH on RHEL 9 and CentOS 9:

Best PracticeDescription
Use SSH Key-Based AuthenticationDisable password-based login and use SSH keys to authenticate users securely.
Disable Root LoginPrevent direct root login via SSH to avoid giving attackers access to the most privileged user.
Change the Default SSH PortMove SSH to a non-standard port to make it harder for attackers to target your system.
Enable Two-Factor AuthenticationAdd a second layer of security by requiring something other than just the SSH key, such as Google Authenticator.
Limit SSH Access by IPRestrict SSH access to specific trusted IP addresses to reduce the attack surface.
Set SSH Timeout and Idle LimitsSet a timeout to automatically disconnect idle sessions and reduce the potential for unauthorized access.
Enable Fail2BanUse Fail2Ban to block IPs after multiple failed login attempts, protecting against brute-force attacks.

We’ll use Ansible to automate the application of these best practices.

Securing SSH connections on RHEL 9 and CentOS 9 with Ansible

Photo by admingeek from Infotechys


Securing SSH connections on RHEL 9 and CentOS 9 with Ansible: Creating Ansible Roles for SSH Security

Ansible roles allow you to organize your playbooks into reusable units, making your automation more modular and efficient. Let’s create a role to secure SSH on RHEL 9 and CentOS 9.

Step 1: Create the Role Directory Structure

Create the directory structure for the Ansible role:

				
					mkdir -p secure-ssh; cd secure-ssh; ansible-galaxy init ssh_security
				
			
				
					- Role ssh_security was created successfully
				
			

This command creates the directory secure-ssh and navigates to it. Then, creates the ssh_security role. Now, let’s change to the role directory:

				
					cd ssh_security
				
			

Step 2: Define SSH Security Tasks

Inside the tasks directory, create a file named main.yml:

				
					vim tasks/main.yml
				
			

Add the following tasks to configure SSH securely:

				
					---
# tasks file for ssh_security
- name: Ensure SSH is installed
  dnf:
    name: openssh-server
    state: present

- name: Disable root login in SSH
  lineinfile:
    path: /etc/ssh/sshd_config
    regexp: '^#PermitRootLogin'
    line: 'PermitRootLogin no'
    state: present
  notify:
    - restart sshd

- name: Disable password authentication
  lineinfile:
    path: /etc/ssh/sshd_config
    regexp: '^#PasswordAuthentication'
    line: 'PasswordAuthentication no'
    state: present
  notify:
    - restart sshd

- name: Change the SSH port to {{ ssh_port }}
  lineinfile:
    path: /etc/ssh/sshd_config
    regexp: '^#Port 22'
    line: 'Port {{ ssh_port }}'
    state: present
  notify:
    - restart sshd

- name: Configure SSH timeout
  lineinfile:
    path: /etc/ssh/sshd_config
    regexp: '^#ClientAliveInterval'
    line: 'ClientAliveInterval {{ client_alive_interval }}'
    state: present

- name: Enable and start sshd service
  service:
    name: sshd
    state: started
    enabled: true

- name: Add custom SSH port {{ ssh_port }} to SELinux
  command: semanage port -a -t ssh_port_t -p tcp {{ ssh_port }}
  ignore_errors: yes  # In case the port is already added, it will not cause a failure

- name: Configure firewall to allow SSH on port {{ ssh_port }}
  shell: |
    sudo firewall-cmd --permanent --add-port={{ item }}/tcp
    sudo firewall-cmd --reload
  with_items:
    - "{{ ssh_port }}"  # You can add more ports here as needed
  loop_control:
    loop_var: item  # Customizing the loop variable name if necessary

				
			

Summary and Explanations

Here’s a brief description of each task:

Task NamePurposeDetails
Ensure SSH is installedEnsures that the openssh-server package is installed on the system.Uses dnf to install openssh-server with state: present.
Disable root login in SSHDisables the ability to log in as the root user via SSH.Modifies /etc/ssh/sshd_config to set PermitRootLogin no to enhance security.
Disable password authenticationDisables SSH login using passwords (forcing key-based authentication).Modifies /etc/ssh/sshd_config to set PasswordAuthentication no to enhance security.
Change the SSH port to {{ ssh_port }}Changes the default SSH port from 22 to a custom port provided in the ssh_port variable.Modifies /etc/ssh/sshd_config to set a custom port (Port {{ ssh_port }}) for SSH connections.
Configure SSH timeoutConfigures the SSH client alive interval to control session timeouts.Modifies /etc/ssh/sshd_config to set ClientAliveInterval {{ client_alive_interval }} for timeouts.
Enable and start sshd serviceEnsures that the SSH service is running and enabled to start on boot.Uses the service module to start and enable sshd service (state: started, enabled: true).
Add custom SSH port {{ ssh_port }} to SELinuxAdds the custom SSH port to SELinux’s allowed ports.Uses semanage port -a to associate the port with the ssh_port_t type, allowing SELinux to accept connections on the custom port.
Configure firewall to allow SSH on port {{ ssh_port }}Updates the firewall to allow SSH traffic on the custom port.Uses firewall-cmd to permanently open the custom port ({{ ssh_port }}) and reload the firewall settings.

Step 3: Create a Handler to Restart SSH

Inside the handlers directory, create a file named main.yml:

				
					vim handlers/main.yml
				
			

Add the following content to restart the SSH service after making configuration changes:

				
					---
# handlers file for ssh_security
- name: restart sshd
  service:
    name: sshd
    state: restarted
				
			

Step 4: Create Default Variables

In the defaults directory, create a main.yml file:

				
					vim defaults/main.yml
				
			

Add the following default variables to configure SSH securely:

				
					---
# defaults file for ssh_security
ssh_port: 2222
client_alive_interval: 300
				
			

This will allow you to customize SSH settings for your environment.


Writing the Ansible Playbook for SSH Security

Now that we have created the role, we can write an Ansible playbook to apply this role to our RHEL 9 and CentOS 9 servers. Create a new playbook named ssh_security.yml:

				
					vim ~/secure-ssh/ssh_security.yml
				
			

Add the following content:

				
					---
# Main playbook for securing SSH
- name: Secure SSH connections on RHEL 9 and CentOS 9 servers
  hosts: all
  become: true
  roles:
    - ssh_security
				
			

In this playbook, we specify that the ssh_security role should be applied to all hosts in the inventory.


Testing and Applying the Ansible Roles

It’s important to test the playbook before applying it to production servers.

Test the playbook

				
					ansible-playbook -i inventory/hosts ssh_security.yml --check
				
			

The --check flag simulates the changes without actually applying them.

Apply the playbook

				
					ansible-playbook -i inventory/hosts ssh_security.yml
				
			

This will apply the SSH security configurations to your servers.

Securing SSH connections on RHEL 9 and CentOS 9 with Ansible

Photo by admingeek from Infotechys

Additional SSH Security Considerations

While securing SSH connections using Ansible roles is an excellent start, consider these additional steps to further improve your server security:

  • Set up Fail2Ban: Install and configure Fail2Ban to protect against brute-force login attempts.
  • Use SELinux: Ensure that SELinux is enabled and properly configured to add an extra layer of security.
  • Monitor SSH Logs: Regularly check logs for unusual access attempts and configure alerts for suspicious behavior.

Conclusion

Securing SSH connections on RHEL 9 and CentOS 9 is a critical aspect of protecting your servers from unauthorized access. By using Ansible roles to automate SSH security tasks, you ensure that your security measures are applied consistently across multiple systems. Enhance and customize the roles shared in the post to align with your organization’s specific security requirements. The steps outlined in this post help automate the process of configuring SSH securely, improving the overall security posture of your systems. Modify and expand on the roles provided in the post to meet security requirements in your organization.

Did you find this article useful? Your feedback is invaluable to us! Please feel free to share this post!


Related Posts
Install Ansible Tower on RHEL 9
Commands
Install Ansible Tower on RHEL 9

Learn how to install Ansible Tower on RHEL 9 with this comprehensive step-by-step guide. Covering prerequisites, system requirements, and post-installation tasks, this resource is perfect for

Read More »

Leave a Reply

Your email address will not be published. Required fields are marked *