On Amazon EC2 Ubuntu instances, the default sudoers configuration allows passwordless sudo access for the default user (typically 'ubuntu'). This is implemented through the following line in /etc/sudoers
:
ubuntu ALL=(ALL) NOPASSWD:ALL
This configuration enables the ubuntu user to execute any command with sudo privileges without entering a password - including sudo su
which provides root shell access.
This default configuration is convenient for initial setup, but presents security risks when:
- Granting access to third-party developers
- Implementing role-based access control
- Needing audit trails for privileged commands
To require password authentication for sudo commands:
- First set a password for the ubuntu user:
- Modify the sudoers configuration:
sudo passwd ubuntu
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
sudo visudo
Change:
ubuntu ALL=(ALL) NOPASSWD:ALL
To:
ubuntu ALL=(ALL) ALL
Test the new configuration in a new terminal session:
sudo -k # Clear any cached credentials
sudo ls # Should now prompt for password
For more granular control, consider these alternatives:
# Require password only for specific commands
ubuntu ALL=(ALL) PASSWD: /usr/bin/apt, /usr/bin/dpkg
# Allow passwordless for certain commands but require password for others
ubuntu ALL=(ALL) NOPASSWD: /usr/bin/apt update
ubuntu ALL=(ALL) PASSWD: /usr/bin/apt upgrade
Problem: Password not accepted after changes
Solution: Ensure you set the password for the correct user (ubuntu, not root)
Problem: Can't edit sudoers file
Solution: Always use visudo
which validates syntax before saving
- Create individual user accounts instead of sharing the ubuntu account
- Implement SSH key authentication (password authentication should only be for sudo)
- Consider using AWS IAM roles for EC2 permissions instead of local user management
- Regularly rotate passwords and SSH keys
When you spin up a fresh Ubuntu instance on Amazon EC2, you'll notice something peculiar about sudo permissions. The default user (typically 'ubuntu') can execute any sudo command without being prompted for a password. This is configured in /etc/sudoers.d/90-cloud-init-users
with a line like:
# User rules for ubuntu
ubuntu ALL=(ALL) NOPASSWD:ALL
While convenient for automated deployments, this becomes a security concern when:
- Granting access to third-party developers
- Multiple team members need varying privilege levels
- Implementing audit trails for privileged commands
Here's the correct sequence to enforce password prompts:
# First, set a password for your user (not root)
sudo passwd ubuntu
# Then modify sudoers configuration
sudo visudo
In the sudoers file, you'll need to change the line for your user from:
ubuntu ALL=(ALL) NOPASSWD:ALL
to either:
# Option 1: Require password for all commands
ubuntu ALL=(ALL) ALL
# Option 2: Allow passwordless for specific commands only
ubuntu ALL=(ALL) NOPASSWD: /usr/bin/apt-get update, /usr/bin/systemctl restart nginx
Problem: "I set the password but sudo still doesn't prompt"
Solution: You probably set the root password (sudo passwd root
) instead of your user password (sudo passwd ubuntu
).
Problem: "After changes, my password isn't accepted"
Solution: Create an AMI backup before making changes. If locked out:
# From AWS console:
1. Stop the instance
2. Detach root volume
3. Attach to another instance as secondary
4. Mount and edit /etc/sudoers
5. Reattach to original instance
For more granular control, consider these sudoers configurations:
# Allow passwordless sudo within specific groups
%developers ALL=(ALL) NOPASSWD: ALL
%auditors ALL=(ALL) ALL
# Time-restricted sudo access
ubuntu ALL=(ALL) ALL, !/usr/bin/passwd, !/usr/sbin/visudo
Remember to always use visudo
for editing these files as it validates syntax before saving.
For infrastructure as code setups, you can configure this via cloud-init:
#cloud-config
users:
- name: ubuntu
sudo: 'ALL=(ALL) ALL'
lock_passwd: false
Or with Ansible:
- name: Configure sudo password requirement
lineinfile:
path: /etc/sudoers.d/90-cloud-init-users
regexp: '^ubuntu ALL=$ALL$ NOPASSWD:ALL'
line: 'ubuntu ALL=(ALL) ALL'
validate: 'visudo -cf %s'