Linux Level 1, Task 7: Disabling Direct Root SSH Login¶
Today's task was one of the most fundamental security hardening steps for any Linux server. My goal was to disable the ability for anyone to log in directly as the root user over SSH. This is a critical best practice that drastically reduces a server's vulnerability to common attacks.
This was also a perfect opportunity to compare the manual, server-by-server approach with a modern, automated solution using Ansible. This document is my detailed, first-person guide covering both methods, explaining why this security measure is so important and how to implement it efficiently.
Table of Contents¶
- The Task
- Solution 1: The Manual Approach (Server by Server)
- Solution 2: The Automated Approach (with Ansible)
- Why Did I Do This? (The "What & Why")
- Deep Dive: The Power of
sedvs. the Intelligence of Ansible - Common Pitfalls
- Exploring the Commands and Modules I Used
The Task¶
My objective was to enhance security on all three Nautilus app servers (stapp01, stapp02, stapp03) by disabling direct SSH login for the root user.
Solution 1: The Manual Approach (Server by Server)¶
This method involves logging into each server and running the same sequence of commands.
The Workflow (Repeated 3 Times)¶
-
Connect to the Server: I started by connecting to the first app server.
ssh tony@stapp01 -
Modify the SSH Configuration: I needed to edit the
/etc/ssh/sshd_configfile.- The Slow Way (with
vi): I could open the file (sudo vi /etc/ssh/sshd_config), search for the line containingPermitRootLogin, change its value tono(and remove the#if it was commented out), and then save the file. - The Fast Way (with
sed): A much more efficient one-liner uses thesedcommand to perform the replacement for me. This command finds any line containingPermitRootLoginand replaces the entire line withPermitRootLogin no.sudo sed -i 's/.*PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
- The Slow Way (with
-
Restart the SSH Service: The change doesn't take effect until the
sshdservice is restarted.sudo systemctl restart sshd - Verification: I checked the file to confirm the change.
Seeing the correct line in the output confirmed success for that server.
grep "PermitRootLogin no" /etc/ssh/sshd_config
I then had to exit and repeat this entire process for stapp02 and stapp03.
Solution 2: The Automated Approach (with Ansible)¶
This is the professional, scalable solution. I performed all my work from the jump host, using Ansible to orchestrate the changes on all three app servers simultaneously.
1. The Inventory (inventory.ini)¶
First, I created an "address book" for Ansible on the jump host.
[app_servers]
stapp01 ansible_host=172.16.238.10 ansible_user=tony ansible_ssh_pass=Ir0nM@n ansible_become_pass=Ir0nM@n
stapp02 ansible_host=172.16.238.11 ansible_user=steve ansible_ssh_pass=Am3ric@ ansible_become_pass=Am3ric@
stapp03 ansible_host=172.16.238.12 ansible_user=banner ansible_ssh_pass=BigGr33n ansible_become_pass=BigGr33n
2. The Playbook (playbook.yml)¶
Next, I wrote a "to-do list" in YAML. This playbook is idempotent, meaning it can be run multiple times safely.
---
- name: Harden SSH on App Servers
hosts: app_servers
become: yes
tasks:
- name: Disable root login in sshd_config
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^.*PermitRootLogin'
line: 'PermitRootLogin no'
state: present
notify: restart sshd
handlers:
- name: restart sshd
service:
name: sshd
state: restarted
3. The Execution¶
Finally, from the jump host, I ran a single command to execute the playbook.
ansible-playbook -i inventory.ini playbook.yml
Why Did I Do This? (The "What & Why")¶
- Security Hardening: This is the general term for the process of reducing a system's vulnerability by minimizing its "attack surface." Disabling direct root login is one of the first and most important hardening steps for any Linux server.
- Reduces Brute-Force Attacks: The root username is a universal constant. By disabling it for SSH, I instantly neutralize the most common type of automated password-guessing attack.
- Enforces Accountability and Audit Trails: This is the most critical reason. Forcing administrators to log in with their own named account (tony, steve) and then use sudo means that every privileged command is logged with the name of the user who ran it. This creates an audit trail, which is essential for security and compliance. If everyone logs in as root, you have no idea who did what.
Deep Dive: The Power of sed vs. the Intelligence of Ansible¶
This task was a perfect comparison between a simple tool and a smart tool.
-
sed(The Scalpel):sudo sed -i 's/.*PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config- How it works:
sedis a "stream editor." It's a powerful command-line tool for finding and replacing text in files. My command is a "blind" operation: it finds any line withPermitRootLoginand replaces the whole line. It's fast and effective for a one-off change. - Limitation: It's not idempotent. If I run it again, it will perform the same search-and-replace, even if the file is already correct. It also doesn't know that it needs to restart the SSH service afterward.
-
Ansible
lineinfileModule (The Smart Robot):- How it works: The
lineinfilemodule is much more intelligent. It reads the file and checks if the linePermitRootLogin noalready exists.- If the line exists but is commented out, it will uncomment it.
- If the line exists with
yes, it will change it tono. - If the line doesn't exist at all, it will add it.
- If the file is already correct, it does nothing.
- Benefit (Idempotence and Handlers): Because it only makes a change if necessary, it's idempotent. Furthermore, the
notify: restart sshddirective tells Ansible to trigger therestart sshdhandler only if a change was actually made. This is far more efficient and safer than restarting the service every single time, even if nothing changed.
- How it works: The
Common Pitfalls¶
- Forgetting to Restart sshd: A very common mistake is to edit the sshd_config file and then forget to restart the service. The new security rule will not be active until the service is restarted.
- Incorrect sed command: A faulty sed regular expression could accidentally delete the line or fail to replace it.
- Locking Yourself Out: If I were to disable root login without first ensuring that my own user (tony, steve) had working sudo privileges, I could lock myself out of all administrative functions on the server.
- YAML Syntax Errors (Ansible): Ansible playbooks are written in YAML, which is very sensitive to indentation. A single wrong space can cause the playbook to fail.
Exploring the Commands and Modules I Used¶
Manual Commands¶
sudo vi /etc/ssh/sshd_config: The command to open and edit the SSH daemon's configuration file.sudo sed -i 's/.*PermitRootLogin.*/PermitRootLogin no/' ...: My one-liner to find and replace the necessary line.-imeans edit in-place.sudo systemctl restart sshd: The standard command to restart a system service to apply new configuration.grep "..." [file]: A simple command to search for and print lines that match a pattern in a file, which I used for verification.
Ansible Modules¶
ansible-playbook -i [inventory] [playbook]: The main command to run an Ansible playbook.lineinfile: An Ansible module that ensures a particular line is in a file, or that a line matching a regular expression is replaced. This is perfect for managing configuration files.service: An Ansible module for managing system services (starting, stopping, restarting).handlers: A special section in Ansible playbooks. Handlers are tasks that only run when "notified" by another task, which is the ideal way to handle service restarts that should only happen when a configuration file has changed.