The system admins team of xFusionCorp Industries has set up some scripts on jump host that run on regular intervals and perform operations on all app servers in Stratos Datacenter. To make these scripts work properly we need to make sure the thor user on jump host has password-less SSH access to all app servers through their respective sudo users (i.e tony for app server 1). Based on the requirements, perform the following:
Set up a password-less authentication from user thor on jump host to all app servers through their respective sudo users.
1. Understanding SSH Authentication
What is SSH?
SSH (Secure Shell) is a cryptographic network protocol used for secure remote access to servers. It provides encrypted communication between two systems.
SSH Authentication Methods
| Method | Description | Security Level |
|---|---|---|
| Password | User enters password each time | Medium |
| Public Key | Cryptographic key pair for authentication | High |
| Host-based | Trust based on host identity | Low |
| Keyboard-interactive | Challenge-response authentication | Medium |
Why Password-less SSH?
| Benefit | Description |
|---|---|
| Automation | Enables scripts to run without human intervention |
| Convenience | No need to remember or type passwords |
| Security | Uses strong cryptographic keys instead of passwords |
| Efficiency | Faster access to multiple servers |
| Integration | Works with automation tools (Ansible, Puppet, etc.) |
How SSH Key Authentication Works
┌─────────────────┐ ┌─────────────────┐
│ Client (Jump │ │ Server (App │
│ Host) │ │ Server) │
│ │ │ │
│ Private Key │────▶│ Public Key │
│ (id_rsa) │ │ (authorized) │
│ │ │ │
└─────────────────┘ └─────────────────┘
- Client sends a request to the server
- Server sends a challenge encrypted with the public key
- Client decrypts the challenge with the private key
- Server verifies the decryption
- Connection is established without a password
2. Understanding Sudo Access
What is Sudo?
Sudo (Superuser DO) allows authorized users to execute commands with elevated privileges (as root or another user).
Sudo Authentication
By default, sudo prompts for the user's password before executing privileged commands. This can be bypassed by configuring NOPASSWD in the sudoers file.
Why Password-less Sudo?
| Benefit | Description |
|---|---|
| Automation | Scripts can run privileged commands without prompting |
| Headless Operation | No terminal needed for password input |
| Consistency | Prevents failed commands due to password prompts |
| CI/CD Integration | Essential for deployment pipelines |
Sudoers File Locations
| Location | Purpose |
|---|---|
/etc/sudoers |
Main sudo configuration file |
/etc/sudoers.d/ |
Directory for individual configuration files |
/etc/sudoers.d/username |
User-specific sudo rules |
3. Prerequisites
Before You Begin
- SSH access to the jump host and all target servers
- Passwords for all server user accounts
- Sudo privileges on target servers
- OpenSSH client installed
Server Details for This Tutorial
| Server | User | Password | Purpose |
|---|---|---|---|
| jump-host | thor | mjolnir123 | Jump/Bastion host |
| stapp01 | tony | Ir0nM@n | Application Server 1 |
| stapp02 | steve | Am3ric@ | Application Server 2 |
| stapp03 | banner | BigGr33n | Application Server 3 |
4. Step 1: Generate SSH Key Pair
Connect to Jump Host
# Connect to the jump host
ssh thor@jump-host
# Password: mjolnir123
Check for Existing SSH Keys
# Check if SSH keys already exist
ls -la ~/.ssh/id_rsa*
# If files exist, you can either use them or generate new ones
Generate a New SSH Key Pair
# Generate RSA key pair (4096-bit for security)
ssh-keygen -t rsa -b 4096 -N "" -f ~/.ssh/id_rsa
Command Breakdown:
| Option | Description |
|---|---|
-t rsa |
Use RSA encryption algorithm |
-b 4096 |
Use 4096-bit key length (more secure than 2048) |
-N "" |
No passphrase (for automation) |
-f ~/.ssh/id_rsa |
Save to default location |
Expected Output:
Generating public/private rsa key pair.
Your identification has been saved in /home/thor/.ssh/id_rsa
Your public key has been saved in /home/thor/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:TijFO2sEaH98fh4JD2JIT+M1+4IJYOtzky5TSJn9heI thor@jump-host
The key's randomart image is:
+---[RSA 4096]----+
| |
| . . |
| =+o =.o |
| o+=oO.=.o |
| ..o=o%.S |
| .. EB.@ = . |
| o.+ = + * |
| o+ o + . |
| o. . |
+----[SHA256]-----+
Verify the Keys
# View the private key
ls -la ~/.ssh/id_rsa
# -rw------- 1 thor thor 3381 Sep 3 10:00 /home/thor/.ssh/id_rsa
# View the public key
cat ~/.ssh/id_rsa.pub
# ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC... thor@jump-host
5. Step 2: Copy SSH Public Key to Servers
Method 1: Using ssh-copy-id (Recommended)
# Copy key to App Server 1 (tony)
ssh-copy-id tony@stapp01
# Password: Ir0nM@n
# Copy key to App Server 2 (steve)
ssh-copy-id steve@stapp02
# Password: Am3ric@
# Copy key to App Server 3 (banner)
ssh-copy-id banner@stapp03
# Password: BigGr33n
Expected Output:
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/thor/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
tony@stapp01's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'tony@stapp01'"
and check to make sure that only the key(s) you wanted were added.
Method 2: Manual Key Copy
# If ssh-copy-id is not available
cat ~/.ssh/id_rsa.pub | ssh tony@stapp01 "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
Method 3: Using SCP
# Copy the public key to the server
scp ~/.ssh/id_rsa.pub tony@stapp01:/tmp/
# Add the key to authorized_keys
ssh tony@stapp01 "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat /tmp/id_rsa.pub >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys && rm /tmp/id_rsa.pub"
Verify Password-less SSH Access
# Test each server (should not prompt for password)
ssh tony@stapp01 "hostname"
ssh steve@stapp02 "hostname"
ssh banner@stapp03 "hostname"
Expected Output:
stapp01
stapp02
stapp03
6. Step 3: Configure Password-less Sudo
Even with password-less SSH, sudo still prompts for a password by default. We need to configure NOPASSWD in the sudoers file.
Method 1: Using sudoers.d Directory (Recommended)
App Server 1 (stapp01):
ssh tony@stapp01 << 'EOF'
echo 'Ir0nM@n' | sudo -S bash -c '
echo "tony ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/tony
chmod 440 /etc/sudoers.d/tony
echo "✓ sudo NOPASSWD configured for tony"
'
EOF
App Server 2 (stapp02):
ssh steve@stapp02 << 'EOF'
echo 'Am3ric@' | sudo -S bash -c '
echo "steve ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/steve
chmod 440 /etc/sudoers.d/steve
echo "✓ sudo NOPASSWD configured for steve"
'
EOF
App Server 3 (stapp03):
ssh banner@stapp03 << 'EOF'
echo 'BigGr33n' | sudo -S bash -c '
echo "banner ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/banner
chmod 440 /etc/sudoers.d/banner
echo "✓ sudo NOPASSWD configured for banner"
'
EOF
Method 2: Using visudo (Interactive)
# Connect to each server
ssh tony@stapp01
# Edit sudoers file
sudo visudo
# Add this line at the end:
tony ALL=(ALL) NOPASSWD: ALL
# Save and exit
# Repeat for steve@stapp02 and banner@stapp03
Method 3: Using visudo with a Separate File
# Create a separate file and include it
ssh tony@stapp01 "sudo bash -c 'echo \"tony ALL=(ALL) NOPASSWD: ALL\" > /etc/sudoers.d/tony'"
Verify Sudo Access
# Test sudo (should not prompt for password)
ssh tony@stapp01 "sudo whoami"
ssh steve@stapp02 "sudo whoami"
ssh banner@stapp03 "sudo whoami"
Expected Output:
root
root
root
7. Step 4: Verification and Testing
Complete Verification Script
#!/bin/bash
echo "========================================="
echo "Verifying SSH and Sudo Configuration"
echo "========================================="
# Define servers
SERVERS=("stapp01:tony" "stapp02:steve" "stapp03:banner")
for server_info in "${SERVERS[@]}"; do
IFS=':' read -r server user <<< "$server_info"
echo ""
echo "=== Testing $server (User: $user) ==="
# Test SSH connection
echo "SSH connection:"
ssh -o ConnectTimeout=5 "$user@$server" "echo ✓ Connected to $server" 2>/dev/null
if [ $? -eq 0 ]; then
echo " ✓ SSH password-less working"
else
echo " ✗ SSH password-less failed"
fi
# Test sudo access
echo "Sudo access:"
ssh "$user@$server" "sudo whoami" 2>/dev/null
if [ $? -eq 0 ]; then
echo " ✓ Sudo NOPASSWD working"
else
echo " ✗ Sudo NOPASSWD failed"
fi
# Check sudoers file
echo "Sudoers file:"
ssh "$user@$server" "cat /etc/sudoers.d/$user 2>/dev/null || echo ' Not found'"
done
echo ""
echo "========================================="
echo "✅ Verification complete!"
echo "========================================="
Quick Verification Commands
# Test all servers
for server in stapp01 stapp02 stapp03; do
echo "=== $server ==="
ssh tony@$server "hostname && sudo whoami"
done
Detailed Verification
# 1. Check SSH key
ssh tony@stapp01 "ls -la ~/.ssh/authorized_keys"
# 2. Check sudoers file
ssh tony@stapp01 "cat /etc/sudoers.d/tony 2>/dev/null"
# 3. Check sudo configuration
ssh tony@stapp01 "sudo -l"
# 4. Test command execution
ssh tony@stapp01 "sudo yum update -y --assumeno" 2>/dev/null
8. Automated Deployment Scripts
Complete Bash Script
#!/bin/bash
echo "========================================="
echo "Setting Up Password-less SSH and Sudo"
echo "========================================="
# Server configuration
declare -A SERVERS=(
["stapp01"]="tony:Ir0nM@n"
["stapp02"]="steve:Am3ric@"
["stapp03"]="banner:BigGr33n"
)
# Generate SSH key if not exists
echo ""
echo "=== SSH Key Generation ==="
if [ ! -f ~/.ssh/id_rsa ]; then
ssh-keygen -t rsa -b 4096 -N "" -f ~/.ssh/id_rsa
echo "✓ SSH key generated"
else
echo "✓ SSH key already exists"
fi
echo ""
echo "Public Key:"
cat ~/.ssh/id_rsa.pub
echo ""
# Copy SSH keys and configure sudo
for server in "${!SERVERS[@]}"; do
IFS=':' read -r user pass <<< "${SERVERS[$server]}"
echo "========================================="
echo "Configuring $server (User: $user)"
echo "========================================="
# Step 1: Copy SSH key
echo "Copying SSH key..."
sshpass -p "$pass" ssh-copy-id -o StrictHostKeyChecking=no "$user@$server" 2>/dev/null
if [ $? -eq 0 ]; then
echo "✓ SSH key copied"
else
echo "❌ Failed to copy SSH key"
continue
fi
# Step 2: Verify SSH access
echo "Verifying SSH access..."
ssh -o StrictHostKeyChecking=no "$user@$server" "hostname" > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "✓ SSH password-less working"
else
echo "❌ SSH password-less failed"
continue
fi
# Step 3: Configure sudo NOPASSWD
echo "Configuring sudo NOPASSWD..."
echo "$pass" | ssh -o StrictHostKeyChecking=no "$user@$server" "sudo -S bash -c 'echo \"$user ALL=(ALL) NOPASSWD: ALL\" > /etc/sudoers.d/$user && chmod 440 /etc/sudoers.d/$user'"
# Step 4: Verify sudo
echo "Verifying sudo access..."
ssh "$user@$server" "sudo whoami" > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "✓ Sudo NOPASSWD working"
else
echo "❌ Sudo NOPASSWD failed"
fi
echo ""
done
echo "========================================="
echo "✅ Configuration complete!"
echo "========================================="
echo ""
echo "Verification:"
for server in "${!SERVERS[@]}"; do
IFS=':' read -r user _ <<< "${SERVERS[$server]}"
echo " ssh $user@$server 'sudo whoami'"
done
Using the Script
# Save the script
nano setup_ssh_sudo.sh
# Make it executable
chmod +x setup_ssh_sudo.sh
# Run the script
./setup_ssh_sudo.sh
9. Troubleshooting Common Issues
Issue 1: "Permission denied (publickey,password)"
Problem: SSH key authentication fails.
Solutions:
# Check if key is added to authorized_keys
ssh tony@stapp01 "cat ~/.ssh/authorized_keys"
# Manually add the key
cat ~/.ssh/id_rsa.pub | ssh tony@stapp01 "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
# Check SSH daemon configuration
ssh tony@stapp01 "grep PubkeyAuthentication /etc/ssh/sshd_config"
# Should be: PubkeyAuthentication yes
# Restart SSH daemon
ssh tony@stapp01 "sudo systemctl restart sshd"
Issue 2: "sudo: a password is required"
Problem: Sudo still asks for password.
Solutions:
# Check if sudoers file exists
ssh tony@stapp01 "ls -la /etc/sudoers.d/"
# Check contents
ssh tony@stapp01 "cat /etc/sudoers.d/tony"
# Create with correct syntax
ssh tony@stapp01 "echo 'tony ALL=(ALL) NOPASSWD: ALL' | sudo tee /etc/sudoers.d/tony"
# Check sudoers syntax
ssh tony@stapp01 "visudo -c"
Issue 3: "Host key verification failed"
Problem: SSH doesn't recognize the host.
Solution:
# Remove the host key
ssh-keygen -R stapp01
# Reconnect (will prompt to accept the key)
ssh tony@stapp01
Issue 4: "ssh-copy-id: command not found"
Problem: The ssh-copy-id command is not available.
Solution (Manual method):
# Manual key copy
cat ~/.ssh/id_rsa.pub | ssh tony@stapp01 "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
Issue 5: "sudo: no tty present"
Problem: Sudo requires a terminal.
Solution:
# Use -S flag with sudo
ssh tony@stapp01 "echo 'password' | sudo -S whoami"
# Or disable requiretty in sudoers
ssh tony@stapp01 "echo 'Defaults:tony !requiretty' | sudo tee /etc/sudoers.d/requiretty"
Issue 6: "sshpass: command not found"
Problem: sshpass is not installed.
Solution:
# Install sshpass
sudo yum install -y sshpass
# or
sudo apt-get install -y sshpass
# Or use interactive method without sshpass
10. Security Best Practices
1. Use Strong SSH Keys
# Use 4096-bit RSA keys (not 2048)
ssh-keygen -t rsa -b 4096 -N "" -f ~/.ssh/id_rsa
# Or use Ed25519 (more secure and faster)
ssh-keygen -t ed25519 -N "" -f ~/.ssh/id_ed25519
2. Restrict Key Access
# Add restrictions to authorized_keys
echo "from="192.168.1.*",command=\"/usr/bin/some-command\",no-agent-forwarding,no-port-forwarding,no-X11-forwarding,no-pty ssh-rsa AAAAB3..." >> ~/.ssh/authorized_keys
3. Use Separate sudoers Files
# Create user-specific files in /etc/sudoers.d/
echo "username ALL=(ALL) NOPASSWD: /usr/bin/specific-command" > /etc/sudoers.d/username
chmod 440 /etc/sudoers.d/username
4. Limit Sudo Commands
Instead of NOPASSWD: ALL, restrict to specific commands:
# Only allow specific commands
username ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/journalctl -u nginx
# Allow only specific users to sudo
username ALL=(username) NOPASSWD: ALL
5. Regular Key Rotation
# Regularly rotate SSH keys (every 90 days)
# Generate new key
ssh-keygen -t rsa -b 4096 -N "" -f ~/.ssh/id_rsa_new
# Copy to servers
ssh-copy-id -i ~/.ssh/id_rsa_new.pub tony@stapp01
# Remove old key from servers
6. Monitor SSH Access
# Check SSH logs
tail -f /var/log/secure
# Monitor authorized_keys changes
auditctl -w /home/*/.ssh/authorized_keys -p wa -k authorized_keys
7. Use a Jump Host (Bastion Host)
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Client │───▶│ Jump │───▶│ App │
│ │ │ Host │ │ Server │
└──────────┘ └──────────┘ └──────────┘
│ │ │
│ Only SSH │ SSH + Sudo │
│ from client │ from jump │
└────────────────┴────────────────┘
11. Conclusion
What We've Accomplished
| Task | Command/Step | Status |
|---|---|---|
| Generate SSH key pair | ssh-keygen -t rsa -b 4096 |
✅ |
| Copy SSH key to servers | ssh-copy-id user@server |
✅ |
| Verify SSH access | ssh user@server "hostname" |
✅ |
| Configure sudo NOPASSWD | echo "user ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/user |
✅ |
| Verify sudo access | ssh user@server "sudo whoami" |
✅ |
| Create automation script | setup_ssh_sudo.sh |
✅ |
Complete Solution Summary
# SSH Access (No Password)
ssh tony@stapp01 # Works without password prompt
# Sudo Access (No Password)
ssh tony@stapp01 "sudo whoami" # Returns: root
# Run Commands on All Servers
for server in stapp01 stapp02 stapp03; do
ssh tony@$server "sudo systemctl status nginx"
done
# Automation Scripts
# Scripts on jump host can now run on all app servers
Key Takeaways
- SSH Keys provide secure, password-less authentication
- ssh-copy-id simplifies key distribution
- sudoers.d is the cleanest way to configure NOPASSWD
- Automation is now possible without password prompts
- Security should be maintained with key rotation and restrictions
Final Verification Commands
# Complete verification
echo "=== Testing All Servers ==="
for server in stapp01 stapp02 stapp03; do
echo "=== $server ==="
ssh tony@$server "hostname && sudo whoami"
done
Expected Output:
=== Testing All Servers ===
=== stapp01 ===
stapp01
root
=== stapp02 ===
stapp02
root
=== stapp03 ===
stapp03
root
Additional Resources
Manual Pages
man ssh-keygen # SSH key generation
man ssh-copy-id # Copy SSH keys
man sudoers # Sudo configuration
man ssh # SSH client
Related Topics
- SSH Agent: Forwarding keys for multi-hop connections
- Ansible: Automation tool that uses password-less SSH
-
SSH Config:
~/.ssh/configfor connection shortcuts - Firewall Rules: Allow SSH from specific IPs only
Automation Tools
| Tool | Purpose |
|---|---|
| Ansible | Configuration management and automation |
| Puppet | Infrastructure as code |
| Chef | Automation platform |
| SaltStack | Remote execution |
Quick Reference Card
Commands Summary
| Task | Command |
|---|---|
| Generate SSH key | ssh-keygen -t rsa -b 4096 -N "" -f ~/.ssh/id_rsa |
| Copy SSH key | ssh-copy-id user@server |
| Test SSH | ssh user@server "hostname" |
| Configure sudo NOPASSWD | echo "user ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/user |
| Test sudo | ssh user@server "sudo whoami" |
| Batch test | for s in stapp01 stapp02 stapp03; do ssh tony@$s "hostname"; done |
Top comments (0)