When I run sudo commands on my Amazon Elastic Compute Cloud (Amazon EC2) Linux instance, I receive an error.
Short description
The /usr/bin/sudo file must have root:root as the owner. If a non-root user owns the /usr/bin/sudo file, then you receive the following error message when run sudo commands on your EC2 Linux instance:
"/usr/bin/sudo must be owned by uid 0 and have the setuid bit set"
The sudoers file also can't be world-writable. If the file is world-writable, then everyone can write to the file and you receive the following error message:
"sudo: /etc/sudoers is world writable"
Note: By default, the file mode for the sudoers file is 0440. This configuration allows the owner and group to read the file, but doesn't allow anyone to write to the file.
To resolve the preceding errors, use the EC2 Serial Console for Linux to connect and troubleshoot. Or, update the instance's user data script to reset file permissions.
Resolution
Note: If you receive errors when you run AWS Command Line Interface (AWS CLI) commands, then see Troubleshooting errors for the AWS CLI. Also, make sure that you're using the most recent AWS CLI version.
Use the EC2 Serial Console to connect and troubleshoot
Prerequisite: Configure access to the EC2 Serial Console. You can only use the serial console on instances that are built on the AWS Nitro System and supported bare metal instances.
Use the Amazon EC2 console or the AWS CLI with SSH client commands to connect to your instance with the serial console. The serial console doesn't require a working network connection. After you connect, troubleshoot your instance for boot, network configuration, or SSH configuration issues.
If you can't use the serial console to connect, then you must use a user data script to troubleshoot the sudo errors.
Update the user data script
Note: When you troubleshoot issues with a user data script, you must stop and start your instance.
Configure your instance for a stop and start
Note: When you stop and start an instance, the instance's public IP address changes. It's a best practice to use an Elastic IP address to route external traffic to your instance instead of a public IP address. If you use Amazon Route 53, then you might need to update the Route 53 DNS records when the public IP address changes. A stop and start is different from an instance reboot. For more information, see How EC2 instance stop and start works.
Before you stop and start your instance, take the following actions:
Update your user data script
Complete the following steps:
- Stop the instance.
Note: If you can't choose Stop, then the instance is already stopped, or its root device is an instance store volume.
- Choose your instance, and then choose Actions.
- Select Instance settings, and then choose Edit User Data.
- (Optional) If you don't know the required permissions, then check /usr/bin/sudo for the the correct permissions. Run the following command on a working instance with the same operating system:
ls -l /usr/bin/sudo
Note: The permissions for /usr/bin/sudo differ across Linux distributions. You can use the permissions in the command output as a reference. Make sure that the instance where you run the command is a clean installation and not in production. This configurations means that the file remains unchanged.
- Enter the following user data script based on your Linux distribution.
Red Hat-based distributions:
Content-Type: multipart/mixed; boundary="//"MIME-Version: 1.0
--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"
#cloud-config
cloud_final_modules:
- [scripts-user, always]
--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"
#!/bin/bash
PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:
rpm --setugids sudo && rpm --setperms sudo
find /etc/sudoers.d/ -type f -exec /bin/chmod 0440 {} \;
find /etc/sudoers.d/ -type f -exec /bin/chown root:root {} \;
--//
Debian-based distributions:
Content-Type: multipart/mixed; boundary="//"MIME-Version: 1.0
--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"
#cloud-config
cloud_final_modules:
- [scripts-user, always]
--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"
#!/bin/bash
/bin/chown root:root /usr/bin/sudo
/bin/chmod 4111 /usr/bin/sudo
/bin/chmod 644 /usr/lib/sudo/sudoers.so
/bin/chmod 0440 /etc/sudoers
/bin/chmod 750 /etc/sudoers.d
find /etc/sudoers.d/ -type f -exec /bin/chmod 0440 {} \;
find /etc/sudoers.d/ -type f -exec /bin/chown root:root {} \;
--//
Note: Make sure to copy the entire script. Don't insert additional spaces when you enter the script. The final two command lines recover the permissions, owner, and group for the custom sudo security policy plugins in the /etc/sudoers.d/ directory.
- Choose Save.
- Start the instance.
- Use SSH to connect to the instance, and then run a test command to verify that sudo works as expected.
Example command:
sudo whoami
Note: The output for the preceding example command must be root. If you still receive permissions errors, then check the /var/log/cloud-init-output.log for user data script execution errors that you must resolve. If you receive a syntax error, then see How do I fix sudo errors on my Amazon EC2 or Amazon Lightsail instance when I run the sudo command?